diff --git a/BeefBoot/BeefBoot.vcxproj b/BeefBoot/BeefBoot.vcxproj index 5a13fb11..f88b55fa 100644 --- a/BeefBoot/BeefBoot.vcxproj +++ b/BeefBoot/BeefBoot.vcxproj @@ -93,6 +93,7 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true Console @@ -112,6 +113,7 @@ MultiThreadedDebug false ProgramDatabase + true Console @@ -128,6 +130,7 @@ true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true Console @@ -149,6 +152,7 @@ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm\tools\clang\include MultiThreaded false + true Console diff --git a/BeefBoot/CMakeLists.txt b/BeefBoot/CMakeLists.txt index e0a3ce14..3848b33c 100644 --- a/BeefBoot/CMakeLists.txt +++ b/BeefBoot/CMakeLists.txt @@ -27,9 +27,9 @@ if(NOT CMAKE_BUILD_TYPE) endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros -add_definitions( - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC +add_definitions( + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -41,10 +41,10 @@ if (${APPLE}) include_directories( . ../ - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party - ../BeefySysLib/third_party/freetype/include - ../extern/llvm-project_13_0_1/llvm/include + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include ../extern/llvm-project_13_0_1/llvm/lib/Target ../IDEHelper @@ -54,14 +54,14 @@ else() include_directories( . ../ - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party - ../BeefySysLib/third_party/freetype/include - ../extern/llvm-project_13_0_1/llvm/include + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include ../extern/llvm-project_13_0_1/llvm/lib/Target ../IDEHelper - ../BeefySysLib/platform/linux + ../BeefySysLib/platform/linux ) endif() @@ -69,7 +69,7 @@ endif() # Defines outputs , depending Debug or Release. # ################################################# -if(CMAKE_BUILD_TYPE STREQUAL "Debug") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_definitions( -D_DEBUG ) @@ -85,23 +85,23 @@ else() ../extern/llvm_linux_rel_13_0_1/lib/Target/X86 ) set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}") - set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib") + set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib") endif() ################### Dependencies ################## # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -113,7 +113,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") endif(MSVC) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() @@ -137,8 +137,17 @@ execute_process( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/bin/llvm-config --system-libs --link-static OUTPUT_VARIABLE LLVM_SYSTEM_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE EXEC_RESULT ) +if (EXEC_RESULT AND NOT EXEC_RESULT EQUAL 0) + if (EXEC_RESULT MATCHES "^[0-9]+$") + message(FATAL_ERROR "llvm-config exited with code ${EXEC_RESULT}.") + else() + message(FATAL_ERROR "llvm-config couldn't be executed: ${EXEC_RESULT}") + endif() +endif() + if (${APPLE}) set(TARGET_LIBS_OS "") else() @@ -152,10 +161,10 @@ endif() if(MSVC) target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib) else() - target_link_libraries(${PROJECT_NAME} BeefySysLib - IDEHelper + target_link_libraries(${PROJECT_NAME} BeefySysLib + IDEHelper ${TARGET_LIBS_OS} - - #${LLVM_LIB}/libLLVMSupport.a - ) + + #${LLVM_LIB}/libLLVMSupport.a + ) endif() diff --git a/BeefBuild/BeefProj.toml b/BeefBuild/BeefProj.toml index 0d636f30..88591bcd 100644 --- a/BeefBuild/BeefProj.toml +++ b/BeefBuild/BeefProj.toml @@ -7,7 +7,7 @@ StartupObject = "BeefBuild.Program" [Platform.Windows] Description = "BeefBuild" -FileVersion = "0.43.3" +FileVersion = "0.43.4" [Configs.Debug.Win32] TargetName = "" @@ -19,7 +19,7 @@ TargetName = "$(ProjectName)_d" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib Rpcrt4.lib Ole32.lib" CLibType = "Dynamic" BeefLibType = "DynamicDebug" -DebugCommandArguments = "-proddir=c:\\Beef\\IDEHelper\\Tests -test" +DebugCommandArguments = "-proddir=c:\\Beef\\IDE -config=Debug2" DebugWorkingDirectory = "c:\\beef\\ide" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] PreprocessorMacros = ["DEBUG", "CLI"] @@ -75,9 +75,6 @@ DebugWorkingDirectory = "$(ProjectDir)\\dist" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] PreprocessorMacros = ["RELEASE", "CLI"] -[Configs.Release.Win64z] -BuildKind = "StaticLib" - [Configs.Debug2.Win32] TargetName = "" OtherLinkFlags = "" diff --git a/BeefFuzz/BeefFuzz.cpp b/BeefFuzz/BeefFuzz.cpp new file mode 100644 index 00000000..df405bbf --- /dev/null +++ b/BeefFuzz/BeefFuzz.cpp @@ -0,0 +1,87 @@ +#pragma warning(disable:4996) + +#include +#include "BeefySysLib/Common.h" +#include "BeefySysLib/util/Array.h" +#include "BeefySysLib/util/SizedArray.h" +#include "BeefySysLib/util/Dictionary.h" +#include "BeefySysLib/util/CabUtil.h" +#include "BeefySysLib/util/BeefPerf.h" +#include "BeefySysLib/util/Deque.h" +#include "BeefySysLib/util/HashSet.h" +#include "BeefySysLib/util/MultiHashSet.h" + +#define BF_DBG_64 +#include "IDEHelper/StrHashMap.h" + +using namespace Beefy; + +#include "FuzzApp.h" + +BF_IMPORT void BF_CALLTYPE IDEHelper_ProgramStart(); +BF_IMPORT void BF_CALLTYPE IDEHelper_ProgramDone(); + +static void FuzzInit() +{ + BfpSystem_SetCommandLine(0, NULL); + + BfpThread_SetName(NULL, "MainThread", NULL); + + BfpSystem_Init(BFP_VERSION, BfpSystemInitFlag_None); + + IDEHelper_ProgramStart(); + + gApp = new FuzzApp(); + gApp->SetTargetPath("fuzz_testd"); + gApp->AddDefine("CLI"); + gApp->AddDefine("DEBUG"); + gApp->SetStartupObject("fuzz_test.Program"); + gApp->SetLinkParams("./libBeefRT_d.a ./libBeefySysLib_d.so -ldl -lpthread -Wl,-rpath -Wl,$ORIGIN"); + + BF_ASSERT(gApp->Init()); +} + +void trimwhitespace(const uint8_t*& str, size_t& len) +{ + while (len > 0 && isspace(*str)) + { + str++; + len--; + } + + const uint8_t* end = str + len - 1; + while (len > 0 && isspace(*end)) + { + end--; + len--; + } +} + +static bool init = false; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if (!init) + { + init = true; + FuzzInit(); + } + + trimwhitespace(Data, Size); + if (Size == 0) + return 0; + + gApp->PrepareCompiler(); + + bool ready = gApp->QueueFile((char*)Data, Size); + + //if (ready) + // ready = gApp->QueuePath("./corlib/src"); + + //if (ready) + // gApp->Compile(); + + gApp->ReleaseCompiler(); + + return 0; +} \ No newline at end of file diff --git a/BeefFuzz/BeefFuzz.h b/BeefFuzz/BeefFuzz.h new file mode 100644 index 00000000..724d73cc --- /dev/null +++ b/BeefFuzz/BeefFuzz.h @@ -0,0 +1,180 @@ +#pragma once + +#include "BeefySysLib/Common.h" +#include "BeefySysLib/util/Array.h" +#include "BeefySysLib/util/String.h" +#include +//#include + +#pragma warning(disable:4996) + +NS_BF_BEGIN + +#define APPEND2(VAL1, VAL2) VAL1##VAL2 +#define APPEND(VAL1, VAL2) APPEND2(VAL1, VAL2) +#define ENUM_VAL_GENERATE(ENUM_ENTRY) APPEND(ENUM_TYPE, _##ENUM_ENTRY), +#define ENUM_NAME_GENERATE(ENUM_ENTRY) #ENUM_ENTRY, +#define ENUM_CREATE_DO2(EnumName) \ + static const char* EnumName##_Names[] = { ENUM_DECLARE(ENUM_NAME_GENERATE) }; \ + enum EnumName { ENUM_DECLARE(ENUM_VAL_GENERATE) }; \ + static bool EnumParse(const String& name, EnumName& result) \ + { \ + for (int i = 0; i < sizeof(EnumName##_Names)/sizeof(const char*); i++) \ + if (name == EnumName##_Names[i]) { result = (EnumName)i; return true; } \ + return false; \ + } \ + static const char* EnumToString(EnumName enumVal) \ + { \ + return EnumName##_Names[(int)enumVal]; \ + } +#define ENUM_CREATE_DO(EnumType) ENUM_CREATE_DO2(EnumType) +#define ENUM_CREATE ENUM_CREATE_DO(ENUM_TYPE) + +class IDEUtils +{ +public: + static bool FixFilePath(String& filePath) + { + if (filePath.length() == 0) + return false; + + if (filePath[0] == '<') + return false; + + if ((filePath.length() > 1) && (filePath[1] == ':')) + filePath[0] = tolower(filePath[0]); + + bool prevWasSlash = false; + for (int i = 0; i < filePath.length(); i++) + { + //if ((filePath[i] == '/') && (filePath[i - 1]) + + if (filePath[i] == DIR_SEP_CHAR_ALT) + filePath[i] = DIR_SEP_CHAR; + + if (filePath[i] == DIR_SEP_CHAR) + { + if ((prevWasSlash) && (i > 1)) + { + filePath.Remove(i, 1); + i--; + continue; + } + + prevWasSlash = true; + } + else + prevWasSlash = false; + + if ((i >= 4) && (filePath[i - 3] == DIR_SEP_CHAR) && (filePath[i - 2] == '.') && (filePath[i - 1] == '.') && (filePath[i] == DIR_SEP_CHAR)) + { + int prevSlash = (int)filePath.LastIndexOf(DIR_SEP_CHAR, i - 4); + if (prevSlash != -1) + { + filePath.Remove(prevSlash, i - prevSlash); + i = prevSlash; + } + } + } + return true; + } + + static void GetDirWithSlash(String& dirName) + { + if (dirName.length() == 0) + return; + char lastC = dirName[dirName.length() - 1]; + if ((lastC != '\\') && (lastC != '/')) + dirName += DIR_SEP_CHAR; + } + + static FILE* CreateFileWithDir(const String& fileName, const char* options) + { + FILE* fp = fopen(fileName.c_str(), options); + if (fp == NULL) + { + String fileDir = GetFileDir(fileName); + if (!fileDir.empty()) + { + RecursiveCreateDirectory(fileDir); + fp = fopen(fileName.c_str(), "w"); + } + } + return fp; + } + + static bool WriteAllText(const String& fileName, const String& data) + { + FILE* fp = CreateFileWithDir(fileName, "w"); + if (fp == NULL) + return false; + fwrite(data.c_str(), 1, data.length(), fp); + fclose(fp); + return true; + } + + static void GetFileNameWithoutExtension(const String& filePath, String& outFileName) + { + outFileName += GetFileName(filePath); + int dot = (int)outFileName.LastIndexOf('.'); + if (dot != -1) + outFileName.RemoveToEnd(dot); + } + + static void GetExtension(const String& filePath, String& ext) + { + int idx = (int)filePath.LastIndexOf('.'); + if (idx != -1) + ext = filePath.Substring(idx); + } + + static void AppendWithOptionalQuotes(String& targetStr, const String& srcFileName) + { + if ((int)srcFileName.IndexOf(' ') == -1) + targetStr += srcFileName; + else + targetStr += "\"" + srcFileName + "\""; + } +}; + +class ArgBuilder +{ +public: + String* mTarget; + bool mDoLongBreak; + int mLastBreak; + std::multiset mLinkPaths; + +public: + ArgBuilder(String& target, bool doLongBreak) + { + mTarget = ⌖ + mDoLongBreak = doLongBreak; + if (mDoLongBreak) + mLastBreak = (int)mTarget->LastIndexOf('\n'); + else + mLastBreak = 0; + } + + void AddSep() + { + if (mDoLongBreak) + { + if (mTarget->length() - mLastBreak > 0x1F000) + { + mLastBreak = (int)mTarget->length(); + mTarget->Append('\n'); + return; + } + } + mTarget->Append(' '); + } + + void AddFileName(const String& filePath) + { + IDEUtils::AppendWithOptionalQuotes(*mTarget, filePath); + } +}; + +NS_BF_END + diff --git a/BeefFuzz/BeefFuzz.vcxproj b/BeefFuzz/BeefFuzz.vcxproj new file mode 100644 index 00000000..adb08cb8 --- /dev/null +++ b/BeefFuzz/BeefFuzz.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {F5FD6845-BBAE-47B6-AE4E-2C1D30F6E145} + Win32Proj + BeefFuzz + 10.0.17763.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\ide\dist\ + + + true + $(ProjectName)_d + $(SolutionDir)\ide\dist\ + + + false + $(SolutionDir)\ide\dist\ + + + false + $(SolutionDir)\ide\dist\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include + true + false + MultiThreadedDebug + false + ProgramDatabase + + + Console + DebugFull + $(SolutionDir)\ide\dist\$(TargetName).exe + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm\tools\clang\include + MultiThreaded + false + + + Console + true + true + DebugFull + $(SolutionDir)\ide\dist\$(TargetName).exe + Default + + + + + + + + + {eceab68d-2f15-495f-a29c-5ea9548aa23d} + + + {f8d29c38-d37c-4af2-8540-2f6e543264f1} + false + + + + + + + + + + \ No newline at end of file diff --git a/BeefFuzz/BeefFuzz.vcxproj.filters b/BeefFuzz/BeefFuzz.vcxproj.filters new file mode 100644 index 00000000..bd3cc797 --- /dev/null +++ b/BeefFuzz/BeefFuzz.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/BeefFuzz/CMakeLists.txt b/BeefFuzz/CMakeLists.txt new file mode 100644 index 00000000..d1b85ae8 --- /dev/null +++ b/BeefFuzz/CMakeLists.txt @@ -0,0 +1,169 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) + +################### Variables. #################### +# Change if you want modify path or other values. # +################################################### + +set(PROJECT_NAME BeefFuzz) +# Output Variables +set(OUTPUT_DEBUG Debug/bin) +set(OUTPUT_RELEASE Release/bin) + +############## CMake Project ################ +# The main options of project # +############################################# + +project(${PROJECT_NAME} CXX C) + +set (CMAKE_CXX_STANDARD 14) +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) + +#set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# Define Release by default. +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") + message(STATUS "Build type not specified: Use Debug by default.") +endif(NOT CMAKE_BUILD_TYPE) + +# Definition of Macros +add_definitions( + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC + -DUNICODE + -D_UNICODE + -DBF_NO_FBX + -DFT2_BUILD_LIBRARY + -DBFSYSLIB_DYNAMIC +) + +if (${APPLE}) + include_directories( + . + ../ + ../BeefySysLib/ + ../BeefySysLib/third_party + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include + ../extern/llvm-project_13_0_1/llvm/lib/Target + ../IDEHelper + + ../BeefySysLib/platform/osx + ) +else() + include_directories( + . + ../ + ../BeefySysLib/ + ../BeefySysLib/third_party + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include + ../extern/llvm-project_13_0_1/llvm/lib/Target + ../IDEHelper + + ../BeefySysLib/platform/linux + ) +endif() + +############## Artefacts Output ################# +# Defines outputs , depending Debug or Release. # +################################################# + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions( + -D_DEBUG + ) + include_directories( + ../extern/llvm_linux_13_0_1/include + ../extern/llvm_linux_13_0_1/lib/Target/X86 + ) + set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}") + set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/lib") +else() + include_directories( + ../extern/llvm_linux_rel_13_0_1/include + ../extern/llvm_linux_rel_13_0_1/lib/Target/X86 + ) + set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}") + set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_13_0_1/lib") +endif() + +################### Dependencies ################## +# Add Dependencies to project. # +################################################### + +option(BUILD_DEPENDS + "Build other CMake project." + ON +) + +# Dependencies : disable BUILD_DEPENDS to link with lib already build. +if(BUILD_DEPENDS) + +else() + +endif() + +################# Flags ################ +# Defines Flags for Windows and Linux. # +######################################## + +if(MSVC) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /MD /MDd /Od /EHsc") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wno-multichar -Wno-invalid-offsetof -fno-omit-frame-pointer -fsanitize=fuzzer") + if (BF_ENABLE_ASAN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + endif() +endif() + +################ Files ################ +# -- Add files to project. -- # +####################################### + +file(GLOB SRC_FILES + BeefFuzz.cpp + FuzzApp.cpp +) + +# Add executable to build. +add_executable(${PROJECT_NAME} + ${SRC_FILES} +) + +execute_process( + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/bin/llvm-config --system-libs --link-static + OUTPUT_VARIABLE LLVM_SYSTEM_LIBS + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE EXEC_RESULT +) + +if (EXEC_RESULT AND NOT EXEC_RESULT EQUAL 0) + if (EXEC_RESULT MATCHES "^[0-9]+$") + message(FATAL_ERROR "llvm-config exited with code ${EXEC_RESULT}.") + else() + message(FATAL_ERROR "llvm-config couldn't be executed: ${EXEC_RESULT}") + endif() +endif() + +if (${APPLE}) + set(TARGET_LIBS_OS "") +else() + #set(TARGET_LIBS_OS "curses") + #set(TARGET_LIBS_OS "-Xlinker --no-demangle -v") + + set(TARGET_LIBS_OS "${LLVM_SYSTEM_LIBS}") +endif() + +# Link with other dependencies. +if(MSVC) + target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib) +else() + target_link_libraries(${PROJECT_NAME} BeefySysLib + IDEHelper + ${TARGET_LIBS_OS} + + #${LLVM_LIB}/libLLVMSupport.a + ) +endif() diff --git a/BeefFuzz/FuzzApp.cpp b/BeefFuzz/FuzzApp.cpp new file mode 100644 index 00000000..ff919a5d --- /dev/null +++ b/BeefFuzz/FuzzApp.cpp @@ -0,0 +1,300 @@ +#pragma warning(disable:4996) + +#include "FuzzApp.h" +#include +#include "BeefySysLib/util/String.h" +#include "BeefySysLib/util/FileEnumerator.h" +#include "BeefySysLib/util/WorkThread.h" +#include "BeefySysLib/platform/PlatformHelper.h" +#include "Compiler/BfSystem.h" + +#ifdef BF_PLATFORM_WINDOWS +#include +#endif + +BF_IMPORT void BF_CALLTYPE Targets_Create(); +BF_IMPORT void BF_CALLTYPE Targets_Delete(); + +BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem); +BF_EXPORT void BF_CALLTYPE BfCompiler_ProgramDone(); + +BF_IMPORT void BF_CALLTYPE Debugger_FullReportMemory(); + +////////////////////////////////////////////////////////////////////////// + +BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler); +BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx, + const char* targetTriple, const char* targetCPU, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads, + Beefy::BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName); +BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler); +BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath); +BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler); +BF_IMPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(void* bfCompiler, void* bfProject, bool flushQueuedHotFiles, bool* hadOutputChanges); + +BF_IMPORT void* BF_CALLTYPE BfSystem_CreateParser(void* bfSystem, void* bfProject); +BF_IMPORT void BF_CALLTYPE BfParser_SetSource(void* bfParser, const char* data, int length, const char* fileName); +BF_IMPORT void BF_CALLTYPE BfParser_SetCharIdData(void* bfParser, uint8* data, int length); +BF_IMPORT bool BF_CALLTYPE BfParser_Parse(void* bfParser, void* bfPassInstance, bool compatMode); +BF_IMPORT bool BF_CALLTYPE BfParser_Reduce(void* bfParser, void* bfPassInstance); +BF_IMPORT bool BF_CALLTYPE BfParser_BuildDefs(void* bfParser, void* bfPassInstance, void* resolvePassData, bool fullRefresh); + +////////////////////////////////////////////////////////////////////////// + +BF_IMPORT void* BF_CALLTYPE BfSystem_Create(); +BF_EXPORT void BF_CALLTYPE BfSystem_Lock(void* bfSystem, int priority); +BF_EXPORT void BF_CALLTYPE BfSystem_Unlock(void* bfSystem); +BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem); +BF_IMPORT void BF_CALLTYPE BfSystem_Delete(void* bfSystem); +BF_IMPORT void* BF_CALLTYPE BfSystem_CreatePassInstance(void* bfSystem); +BF_IMPORT void* BF_CALLTYPE BfSystem_CreateCompiler(void* bfSystem, bool isResolveOnly); +BF_IMPORT void* BF_CALLTYPE BfSystem_CreateProject(void* bfSystem, const char* projectName, const char* projectDir); +BF_IMPORT void BF_CALLTYPE BfParser_Delete(void* bfParser); +BF_IMPORT void BF_CALLTYPE BfSystem_AddTypeOptions(void* bfSystem, const char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 arrayBoundsCheck, + int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth); + +////////////////////////////////////////////////////////////////////////// + +BF_IMPORT void BF_CALLTYPE BfProject_SetDisabled(void* bfProject, bool disabled); +BF_IMPORT void BF_CALLTYPE BfProject_SetOptions(void* bfProject, int targetType, const char* startupObject, const char* preprocessorMacros, + int optLevel, int ltoType, int relocType, int picLevel, int32 flags); +BF_IMPORT void BF_CALLTYPE BfProject_ClearDependencies(void* bfProject); +BF_IMPORT void BF_CALLTYPE BfProject_AddDependency(void* bfProject, void* depProject); + +////////////////////////////////////////////////////////////////////////// + +BF_IMPORT const char* BF_CALLTYPE BfPassInstance_PopOutString(void* bfPassInstance); +BF_IMPORT void BF_CALLTYPE BfPassInstance_Delete(void* bfPassInstance); + +////////////////////////////////////////////////////////////////////////// + +BF_IMPORT const char* BF_CALLTYPE VSSupport_Find(); + +////////////////////////////////////////////////////////////////////////// + +USING_NS_BF; + +FuzzApp* Beefy::gApp = NULL; + + +FuzzApp::FuzzApp() +{ + Targets_Create(); + + mTargetType = BfTargetType_BeefConsoleApplication; + + mSystem = NULL; + mCompiler = NULL; + mProject = NULL; + mCELibProject = NULL; + mIsCERun = false; + mStartupObject = "Program"; + +#ifdef BF_PLATFORM_WINDOWS + mOptLevel = BfOptLevel_OgPlus; + mToolset = BfToolsetType_Microsoft; +#else + mOptLevel = BfOptLevel_O0; + mToolset = BfToolsetType_GNU; +#endif + +#ifdef BF_PLATFORM_WINDOWS + mTargetTriple = "x86_64-pc-windows-msvc"; +#elif defined BF_PLATFORM_MACOS + mTargetTriple = "x86_64-apple-macosx10.8.0"; +#else + mTargetTriple = "x86_64-unknown-linux-gnu"; +#endif +} + +FuzzApp::~FuzzApp() +{ + Targets_Delete(); +} + +bool FuzzApp::Init() +{ + char* cwdPtr = getcwd(NULL, 0); + mWorkingDir = cwdPtr; + free(cwdPtr); + + if (mTargetPath.IsEmpty()) + return false; + + return true; +} + +bool FuzzApp::QueueFile(const char* data, size_t len) +{ + bool worked = true; + void* bfParser = BfSystem_CreateParser(mSystem, (mCELibProject != NULL) ? mCELibProject : mProject); + BfParser_SetSource(bfParser, data, len, "Fuzz.bf"); + //bfParser.SetCharIdData(charIdData); + worked &= BfParser_Parse(bfParser, mPassInstance, false); + worked &= BfParser_Reduce(bfParser, mPassInstance); + worked &= BfParser_BuildDefs(bfParser, mPassInstance, NULL, false); + return worked; +} + +bool FuzzApp::QueuePath(const StringImpl& path) +{ + if (DirectoryExists(path)) + { + for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Files)) + { + String filePath = fileEntry.GetFilePath(); + + String fileName; + fileName = GetFileName(filePath); + + String ext; + ext = GetFileExtension(filePath); + + if ((ext.Equals(".bf", StringImpl::CompareKind_OrdinalIgnoreCase)) || + (ext.Equals(".cs", StringImpl::CompareKind_OrdinalIgnoreCase))) + { + int len; + const char* data = LoadTextData(filePath, &len); + if (data != NULL) + { + bool success = QueueFile(data, len); + delete[] data; + + if (!success) + return false; + } + } + } + + for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Directories)) + { + String childPath = fileEntry.GetFilePath(); + String dirName; + dirName = GetFileName(childPath); + + if (dirName == "build") + continue; + + if (!QueuePath(childPath)) + return false; + } + + return true; + } + + return false; +} + +bool FuzzApp::CopyFile(const StringImpl& srcPath, const StringImpl& destPath) +{ + BfpFileResult result = BfpFileResult_Ok; + for (int i = 0; i < 20; i++) + { + BfpFile_Copy(srcPath.c_str(), destPath.c_str(), BfpFileCopyKind_Always, &result); + if (result == BfpFileResult_Ok) + return true; + BfpThread_Sleep(100); + } + return false; +} + +void FuzzApp::PrepareCompiler() +{ + mSystem = BfSystem_Create(); + + mCompiler = BfSystem_CreateCompiler(mSystem, false); + + String projectName = GetFileName(mTargetPath); + int dotPos = (int)projectName.IndexOf('.'); + if (dotPos != -1) + projectName.RemoveToEnd(dotPos); + if (projectName.IsEmpty()) + projectName.Append("BeefProject"); + + mProject = BfSystem_CreateProject(mSystem, projectName.c_str(), GetFileDir(mTargetPath).c_str()); + + if (mIsCERun) + { + mCELibProject = BfSystem_CreateProject(mSystem, "BeefLib", GetFileDir(mTargetPath).c_str()); + BfProject_SetOptions(mCELibProject, BfTargetType_BeefLib, "", mDefines.c_str(), mOptLevel, 0, 0, 0, BfProjectFlags_None); + } + + String defines = mDefines; + if (!defines.IsEmpty()) + defines.Append("\n"); + defines.Append("BF_64_BIT"); + defines.Append("\nBF_LITTLE_ENDIAN"); + defines.Append("\n"); + defines.Append(BF_PLATFORM_NAME); + + int ltoType = 0; + BfProject_SetOptions(mProject, mTargetType, mStartupObject.c_str(), defines.c_str(), BfOptLevel_O0, ltoType, 0, 0, BfProjectFlags_None); + + if (mCELibProject != NULL) + BfProject_AddDependency(mProject, mCELibProject); + + mPassInstance = BfSystem_CreatePassInstance(mSystem); + + Beefy::String exePath; + BfpGetStrHelper(exePath, [](char* outStr, int* inOutStrSize, BfpResult* result) + { + BfpSystem_GetExecutablePath(outStr, inOutStrSize, (BfpSystemResult*)result); + }); + mBuildDir = GetFileDir(exePath) + "/build"; + + RecursiveCreateDirectory(mBuildDir + "/" + projectName); + if (mIsCERun) + RecursiveCreateDirectory(mBuildDir + "/BeefLib"); + + BfCompilerOptionFlags optionFlags = (BfCompilerOptionFlags)(BfCompilerOptionFlag_EmitDebugInfo | BfCompilerOptionFlag_EmitLineInfo | BfCompilerOptionFlag_GenerateOBJ | BfCompilerOptionFlag_OmitDebugHelpers); + + //int maxWorkerThreads = BfpSystem_GetNumLogicalCPUs(NULL); + //if (maxWorkerThreads <= 1) + // maxWorkerThreads = 6; + + BfCompiler_SetOptions(mCompiler, NULL, 0, mTargetTriple.c_str(), "", mToolset, BfSIMDSetting_SSE2, 1, 1, optionFlags, "malloc", "free"); +} + + +bool FuzzApp::Compile() +{ + BfCompiler_ClearBuildCache(mCompiler); + + if (!BfCompiler_Compile(mCompiler, mPassInstance, mBuildDir.c_str())) + return false; + + if (!mCEDest.IsEmpty()) + { + String ext; + String srcResult = mBuildDir + "/BeefProject/BeefProject"; + srcResult += BF_OBJ_EXT; + + if (!CopyFile(srcResult, mCEDest)) + return false; + } + + while (true) + { + const char* msg = BfPassInstance_PopOutString(mPassInstance); + if (msg == NULL) + break; + + if ((strncmp(msg, ":error ", 7) == 0) || + (strncmp(msg, "ERROR(", 6) == 0) || + (strncmp(msg, "ERROR:", 6) == 0)) + { + return false; + } + } + + return true; +} + +void FuzzApp::ReleaseCompiler() +{ + BfPassInstance_Delete(mPassInstance); + BfCompiler_Delete(mCompiler); + + BfSystem_Delete(mSystem); +} + + diff --git a/BeefFuzz/FuzzApp.h b/BeefFuzz/FuzzApp.h new file mode 100644 index 00000000..b491e256 --- /dev/null +++ b/BeefFuzz/FuzzApp.h @@ -0,0 +1,66 @@ +#pragma once + +#include "BeefFuzz.h" +#include "BeefySysLib/FileStream.h" +#include "BeefySysLib/util/CritSect.h" +#include "BeefySysLib/util/String.h" +#include "BeefySysLib/util/Array.h" +#include "Compiler/BfSystem.h" + +NS_BF_BEGIN + +class FuzzApp +{ +public: + BfTargetType mTargetType; + String mTargetTriple; + BfOptLevel mOptLevel; + BfToolsetType mToolset; + String mBuildDir; + String mWorkingDir; + String mDefines; + String mStartupObject; + String mTargetPath; + String mLinkParams; + + void* mSystem; + void* mCompiler; + void* mProject; + void* mPassInstance; + + bool mIsCERun; + void* mCELibProject; + String mCEDest; + +public: + bool CopyFile(const StringImpl& srcPath, const StringImpl& destPath); + + bool QueueFile(const char* data, size_t len); + bool QueuePath(const StringImpl& path); + +public: + FuzzApp(); + ~FuzzApp(); + + void SetTargetType(BfTargetType value) { mTargetType = value; } + void SetTargetTriple(const String& value) { mTargetTriple = value; } + void SetOptLevel(BfOptLevel value) { mOptLevel = value; } + void SetToolset(BfToolsetType value) { mToolset = value; } + void SetBuildDir(const String& value) { mBuildDir = value; } + void SetWorkingDir(const String& value) { mWorkingDir = value; } + void AddDefine(const String& value) { mDefines += mDefines.IsEmpty() ? value : "\n" + value; } + void SetStartupObject(const String& value) { mStartupObject = value; } + void SetTargetPath(const String& value) { mTargetPath = value; } + void SetLinkParams(const String& value) { mLinkParams = value; } + void SetCEDest(const String& value) { mCEDest = value; } + + bool Init(); + + void PrepareCompiler(); + bool Compile(); + void ReleaseCompiler(); +}; + +extern FuzzApp* gApp; + +NS_BF_END diff --git a/BeefLibs/Beefy2D/src/BFApp.bf b/BeefLibs/Beefy2D/src/BFApp.bf index 9159aeef..f1f1aefa 100644 --- a/BeefLibs/Beefy2D/src/BFApp.bf +++ b/BeefLibs/Beefy2D/src/BFApp.bf @@ -792,9 +792,23 @@ namespace Beefy BFApp_SetCursor((int32)cursor); } - public virtual void* GetClipboardData(String format, out int32 size) + public virtual void* GetClipboardData(String format, out int32 size, int waitTime = 500) { - return BFApp_GetClipboardData(format, out size); + Stopwatch sw = null; + repeat + { + if (sw != null) + Thread.Sleep(1); + void* result = BFApp_GetClipboardData(format, out size); + if (size != -1) + return result; + if (waitTime == 0) + return null; + if (sw == null) + sw = scope:: .()..Start(); + } + while (waitTime < sw.ElapsedMilliseconds); + return null; } public virtual void ReleaseClipboardData(void* ptr) @@ -802,9 +816,9 @@ namespace Beefy BFApp_ReleaseClipboardData(ptr); } - public virtual bool GetClipboardText(String outStr) + public virtual bool GetClipboardText(String outStr, int waitTime = 500) { - return GetClipboardTextData("text", outStr); + return GetClipboardTextData("text", outStr, waitTime); } public virtual bool GetClipboardText(String outStr, String extra) @@ -813,10 +827,10 @@ namespace Beefy return GetClipboardTextData("text", outStr); } - public bool GetClipboardTextData(String format, String outStr) + public bool GetClipboardTextData(String format, String outStr, int waitTime = 500) { int32 aSize; - void* clipboardData = GetClipboardData(format, out aSize); + void* clipboardData = GetClipboardData(format, out aSize, waitTime); if (clipboardData == null) return false; diff --git a/BeefLibs/Beefy2D/src/Utils.bf b/BeefLibs/Beefy2D/src/Utils.bf index 9ff8fb2e..f2eaecb0 100644 --- a/BeefLibs/Beefy2D/src/Utils.bf +++ b/BeefLibs/Beefy2D/src/Utils.bf @@ -170,7 +170,7 @@ namespace Beefy if (autoRetry) { if (fileOpenErr == .SharingViolation) - retry = true; + retry = i != 99; } if (!retry) return .Err(.OpenError(fileOpenErr)); diff --git a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf index 8a1d7975..0e2dc3d8 100644 --- a/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf +++ b/BeefLibs/Beefy2D/src/theme/dark/DarkEditWidget.bf @@ -33,7 +33,7 @@ namespace Beefy.theme.dark } - public virtual void MouseDown(float x, float y, int btn, int btnCount) + public virtual void MouseDown(Rect rect, float x, float y, int btn, int btnCount) { } @@ -63,6 +63,7 @@ namespace Beefy.theme.dark public bool mScrollToStartOnLostFocus; public bool mHiliteCurrentLine; public Dictionary mEmbeds = new .() ~ DeleteDictionaryAndValues!(_); + public Embed mEmbedSelected; public Range? mLineRange; protected static uint32[] sDefaultColors = new uint32[] ( Color.White ) ~ delete _; @@ -457,6 +458,12 @@ namespace Beefy.theme.dark LineStartsChanged(); } + public override void ClearText() + { + mLineRange = null; + base.ClearText(); + } + public virtual float DrawText(Graphics g, String str, float x, float y, uint16 typeIdAndFlags) { using (g.PushColor(mTextColors[typeIdAndFlags & 0xFF])) diff --git a/BeefLibs/MiniZ/src/Zip.bf b/BeefLibs/MiniZ/src/Zip.bf index cc740203..d9ff58b4 100644 --- a/BeefLibs/MiniZ/src/Zip.bf +++ b/BeefLibs/MiniZ/src/Zip.bf @@ -2781,6 +2781,11 @@ namespace MiniZ array_ptr.m_element_size = element_size; } + static mixin ZIP_ARRAY_ELEMENT_PTR(var array_ptr, int index) + { + &((T*)(array_ptr.m_p))[index] + } + static mixin ZIP_ARRAY_ELEMENT(var array_ptr, int index) { ((T*)(array_ptr.m_p))[index] @@ -2929,9 +2934,9 @@ namespace MiniZ static bool zip_reader_filename_less(ZipArray* pCentral_dir_array, ZipArray* pCentral_dir_offsets, uint32 l_index, uint32 r_index) { - uint8* pL = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index)); + uint8* pL = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index)); uint8* pE; - uint8* pR = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, r_index)); + uint8* pR = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, r_index)); uint32 l_len = ReadLE16!(pL + ZIP_CDH_FILENAME_LEN_OFS), r_len = ReadLE16!(pR + ZIP_CDH_FILENAME_LEN_OFS); char8 l = 0, r = 0; pL += ZIP_CENTRAL_DIR_HEADER_SIZE; pR += ZIP_CENTRAL_DIR_HEADER_SIZE; @@ -2951,7 +2956,7 @@ namespace MiniZ ZipInternalState* pState = pZip.m_pState; ZipArray* pCentral_dir_offsets = &pState.m_central_dir_offsets; ZipArray* pCentral_dir = &pState.m_central_dir; - uint32* pIndices = &ZIP_ARRAY_ELEMENT!(&pState.m_sorted_central_dir_offsets, 0); + uint32* pIndices = ZIP_ARRAY_ELEMENT_PTR!(&pState.m_sorted_central_dir_offsets, 0); int size = (int)pZip.m_total_files; int start = (size - 2) >> 1, end; while (start >= 0) @@ -3063,9 +3068,9 @@ namespace MiniZ int32 total_header_size, comp_size, decomp_size, disk_index; if ((n < ZIP_CENTRAL_DIR_HEADER_SIZE) || (ReadLE32!(p) != ZIP_CENTRAL_DIR_HEADER_SIG)) return false; - ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, i) = (uint32)(p - (uint8*)pZip.m_pState.m_central_dir.m_p); + *ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir_offsets, i) = (uint32)(p - (uint8*)pZip.m_pState.m_central_dir.m_p); if (sort_central_dir) - ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_sorted_central_dir_offsets, i) = (uint32)i; + *ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_sorted_central_dir_offsets, i) = (uint32)i; comp_size = (int32)ReadLE32!(p + ZIP_CDH_COMPRESSED_SIZE_OFS); decomp_size = (int32)ReadLE32!(p + ZIP_CDH_DECOMPRESSED_SIZE_OFS); if (((ReadLE32!(p + ZIP_CDH_METHOD_OFS) == 0) && (decomp_size != comp_size)) || ((decomp_size != 0) && (comp_size == 0)) || (decomp_size == -1) || (comp_size == -1)) @@ -3210,7 +3215,7 @@ namespace MiniZ { if ((pZip == null) || (pZip.m_pState == null) || (file_index >= pZip.m_total_files) || (pZip.m_zip_mode != .Reading)) return null; - return &ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index)); + return ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index)); } static bool zip_reader_is_file_encrypted(ZipArchive* pZip, int32 file_index) @@ -3313,7 +3318,7 @@ namespace MiniZ { char8* pR = pR_in; - uint8* pL = &ZIP_ARRAY_ELEMENT!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index)); + uint8* pL = ZIP_ARRAY_ELEMENT_PTR!(pCentral_dir_array, ZIP_ARRAY_ELEMENT!(pCentral_dir_offsets, l_index)); uint8* pE; int32 l_len = ReadLE16!(pL + ZIP_CDH_FILENAME_LEN_OFS); char8 l = 0, r = 0; @@ -3334,7 +3339,7 @@ namespace MiniZ ZipInternalState* pState = pZip.m_pState; ZipArray* pCentral_dir_offsets = &pState.m_central_dir_offsets; ZipArray* pCentral_dir = &pState.m_central_dir; - uint32* pIndices = &ZIP_ARRAY_ELEMENT!(&pState.m_sorted_central_dir_offsets, 0); + uint32* pIndices = ZIP_ARRAY_ELEMENT_PTR!(&pState.m_sorted_central_dir_offsets, 0); int32 size = pZip.m_total_files; int32 filename_len = (int32)Internal.CStrLen(pFilename); int32 l = 0, h = size - 1; @@ -3363,7 +3368,7 @@ namespace MiniZ comment_len = (pComment != null) ? Internal.CStrLen(pComment) : 0; if (comment_len > 0xFFFF) return -1; for (file_index = 0; file_index < pZip.m_total_files; file_index++) { - uint8* pHeader = &ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index)); + uint8* pHeader = ZIP_ARRAY_ELEMENT_PTR!(&pZip.m_pState.m_central_dir, ZIP_ARRAY_ELEMENT!(&pZip.m_pState.m_central_dir_offsets, file_index)); int32 filename_len = ReadLE16!(pHeader + ZIP_CDH_FILENAME_LEN_OFS); char8* pFilename = (char8*)pHeader + ZIP_CENTRAL_DIR_HEADER_SIZE; if (filename_len < name_len) diff --git a/BeefLibs/corlib/src/Allocator.bf b/BeefLibs/corlib/src/Allocator.bf index 10a9c7dd..9f2fab0d 100644 --- a/BeefLibs/corlib/src/Allocator.bf +++ b/BeefLibs/corlib/src/Allocator.bf @@ -5,8 +5,13 @@ namespace System { interface IRawAllocator { - void* Alloc(int size, int align); - void Free(void* ptr); + void* Alloc(int size, int align) mut; + void Free(void* ptr) mut; + } + + interface ITypedAllocator : IRawAllocator + { + void* AllocTyped(Type type, int size, int align) mut; } struct StdAllocator : IRawAllocator @@ -22,6 +27,76 @@ namespace System } } + class SingleAllocator : ITypedAllocator + { + void* mPtr; + int mSize; + Type mType; + + [AllowAppend] + public this(int size) + { + void* ptr = append uint8[size]*(?); + mPtr = ptr; + mSize = size; + } + + public ~this() + { + if ((mType != null) && (mType.IsObject)) + { + Object obj = Internal.UnsafeCastToObject(mPtr); + delete:null obj; + } + + if (mSize < 0) + delete mPtr; + } + + protected virtual void* AllocLarge(int size, int align) + { + return new uint8[size]*; + } + + protected virtual void FreeLarge(void* ptr) + { + delete ptr; + } + + public void* Alloc(int size, int align) + { + return AllocTyped(typeof(void), size, align); + } + + public void Free(void* ptr) + { + Runtime.Assert(ptr == mPtr); + mType = typeof(void); + } + + [Optimize] + public void* AllocTyped(Type type, int size, int align) + { + Runtime.Assert(mType == null, "SingleAllocator has been used for multiple allocations"); + + mType = type; + do + { + if (size > size) + break; + void* usePtr = (void*)(int)Math.Align((int)mPtr, align); + if ((uint8*)usePtr + size > (uint8*)mPtr + mSize) + break; + mPtr = usePtr; + mSize = 0; + return mPtr; + } + mSize = -1; + mPtr = AllocLarge(size, align); + return mPtr; + } + } + struct AllocWrapper where T : new, delete { alloctype(T) mVal; diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf index e0eb24ae..795eda52 100644 --- a/BeefLibs/corlib/src/Attribute.bf +++ b/BeefLibs/corlib/src/Attribute.bf @@ -425,10 +425,18 @@ namespace System } } - [AttributeUsage(.Field | .StaticField | .Method | .Property /*2*/)] + [AttributeUsage(.Field | .StaticField | .Method | .Property | .Types)] public struct NoShowAttribute : Attribute { + public this() + { + } + + public this(bool allowDirect) + { + + } } [AttributeUsage(.Parameter)] diff --git a/BeefLibs/corlib/src/Collections/List.bf b/BeefLibs/corlib/src/Collections/List.bf index fd86b82d..f712e655 100644 --- a/BeefLibs/corlib/src/Collections/List.bf +++ b/BeefLibs/corlib/src/Collections/List.bf @@ -71,6 +71,12 @@ namespace System.Collections Add(item); } + [AllowAppend] + public this(Span span) : this(span.Length) + { + AddRange(span); + } + [AllowAppend] public this(int capacity) { diff --git a/BeefLibs/corlib/src/Collections/SplitList.bf b/BeefLibs/corlib/src/Collections/SplitList.bf new file mode 100644 index 00000000..b3fec014 --- /dev/null +++ b/BeefLibs/corlib/src/Collections/SplitList.bf @@ -0,0 +1,626 @@ +using System; +using System.Reflection; +using System.Diagnostics; + +namespace System.Collections +{ + class SplitList : IEnumerable, IList, ICollection where T : struct + { + private const int_cosize cDefaultCapacity = 4; + + private void* mItems; + private int_cosize mSize; + private int_cosize mAllocSize; +#if VERSION_LIST + private int32 mVersion; + const String cVersionError = "List changed during enumeration"; +#endif + + [Inline] public int AllocSize => mAllocSize; + + static void GetFields(List fieldList) + { + if (typeof(T).IsUnion) + return; + for (var field in typeof(T).GetFields()) + { + if (field.IsStatic) + continue; + fieldList.Add(field); + } + } + + [Comptime, OnCompile(.TypeInit)] + static void Init() + { + var fields = GetFields(.. scope .()); + String code = scope $""" + int_cosize[{Math.Max(0, fields.Count - 1)}] mOffsets; + """; + Compiler.EmitTypeBody(typeof(Self), code); + + if (typeof(T).IsUnion) + Runtime.FatalError("Cannot use SplitList on a union"); + } + + public struct Data + { + SelfOuter mList; + + public this(SelfOuter list) + { + mList = list; + } + + [Comptime, OnCompile(.TypeInit)] + static void Init() + { + var fields = GetFields(.. scope .()); + String code = scope .(); + for (var field in fields) + { + code.AppendF($"[Inline] public Span<{field.FieldType}> {field.Name} => .((.)((uint8*)mList.mItems"); + if (@field.Index > 0) + code.AppendF($" + mList.mOffsets[{@field.Index - 1}]"); + code.AppendF($"), mList.mSize);\n"); + } + Compiler.EmitTypeBody(typeof(Self), code); + } + } + + [Comptime] + static void Emit_Get(String prefix, String idx, String item) + { + var fields = GetFields(.. scope .()); + String code = scope .(); + for (var field in fields) + { + code.AppendF($"{item}.[Friend]{field.Name} = (({field.FieldType}*)((uint8*){prefix}mItems"); + if (@field.Index > 0) + code.AppendF($" + {prefix}mOffsets[{@field.Index - 1}]"); + code.AppendF($"))[{idx}];\n"); + } + + Compiler.MixinRoot(code); + } + + [Comptime] + static void Emit_Set(String prefix, String idx, String item) + { + String code = scope .(); + var fields = GetFields(.. scope .()); + for (var field in fields) + { + if (field.IsStatic) + continue; + code.AppendF($"(({field.FieldType}*)((uint8*){prefix}mItems"); + if (@field.Index > 0) + code.AppendF($" + {prefix}mOffsets[{@field.Index - 1}]"); + code.AppendF($"))[{idx}] = {item}.[Friend]{field.Name};\n"); + } + + Compiler.MixinRoot(code); + } + + [Comptime] + static void Emit_Copy(String destOfs, String srcOfs, String length) + { + var fields = GetFields(.. scope .()); + String code = scope .(); + for (var field in fields) + { + if (@field.Index > 0) + code.AppendF($"Internal.MemMove((uint8*)mItems + mOffsets[{@field.Index - 1}] + {destOfs} * {field.FieldType.Stride}, (uint8*)mItems + mOffsets[{@field.Index - 1}] + {srcOfs} * {field.FieldType.Stride}, mSize * {field.FieldType.Stride});\n"); + else + code.AppendF($"Internal.MemMove((uint8*)mItems + {destOfs} * {field.FieldType.Stride}, (uint8*)mItems + {srcOfs} * {field.FieldType.Stride}, {length} * {field.FieldType.Stride});\n"); + } + Compiler.MixinRoot(code); + } + + public struct Entry + { + SelfOuter mList; + int_cosize mIdx; + + [Inline] + public this(SelfOuter list, int idx) + { + mList = list; + mIdx = (.)idx; + } + + [Comptime, OnCompile(.TypeInit)] + static void Init() + { + var fields = GetFields(.. scope .()); + String code = scope .(); + for (var field in fields) + { + code.AppendF($"[Inline] public ref {field.FieldType} {field.Name} => ref (({field.FieldType}*)((uint8*)mList.mItems"); + if (@field.Index > 0) + code.AppendF($" + mList.mOffsets[{@field.Index - 1}]"); + code.AppendF($"))[mIdx];\n"); + } + + Compiler.EmitTypeBody(typeof(Self), code); + } + + public T Value + { + get + { + T value = ?; + Emit_Get("mList.", "mIdx", "value"); + return value; + } + + set + { + Emit_Set("mList.", "mIdx", "value"); + } + } + + public static T operator implicit(Self self) => self.[Inline]Value; + } + + public ~this() + { + Free(mItems); + } + + public Entry this[int index] + { + [Checked] + get + { + Runtime.Assert((uint)index < (uint)mSize); + return .(this, index); + } + + [Unchecked, Inline] + get + { + return .(this, index); + } + } + + public int Count => mSize; + + [Inline] public Data Data => .(this); + + protected virtual void* Alloc(int byteSize) + { + return new uint8[byteSize]*; + } + + protected virtual void Free(void* val) + { + delete val; + } + + void* Realloc(int newSize, bool autoFree) + { + [Comptime] + void Emit_Start() + { + var fields = GetFields(.. scope .()); + String code = scope $"int_cosize[{Math.Max(0, fields.Count - 1)}] newOffsets;\n"; + FieldInfo prevFieldInfo = default; + for (var field in fields) + { + if (@field.Index > 0) + { + code.AppendF($"newOffsets[{@field.Index - 1}] = (.)Math.Align("); + if (@field.Index > 1) + code.AppendF($"newOffsets[{@field.Index - 2}] + "); + code.AppendF($"newSize * {prevFieldInfo.FieldType.Stride}, {field.FieldType.Align});\n"); + } + prevFieldInfo = field; + } + + if (fields.Count == 0) + code.AppendF("int newSizeBytes = 0;\n"); + else if (fields.Count == 1) + code.AppendF($"int newSizeBytes = newSize * {typeof(T).Stride};\n"); + else + code.AppendF($"int newSizeBytes = newOffsets[{fields.Count - 2}] + newSize * {fields[fields.Count - 1].FieldType.Stride};\n"); + + Compiler.MixinRoot(code); + } + + [Comptime] + void Emit_Copy() + { + var fields = GetFields(.. scope .()); + String code = scope .(); + for (var field in fields) + { + if (@field.Index > 0) + code.AppendF($"Internal.MemCpy((uint8*)newItems + newOffsets[{@field.Index - 1}], (uint8*)mItems + mOffsets[{@field.Index - 1}], mSize * {field.FieldType.Stride});\n"); + else + code.AppendF($"Internal.MemCpy(newItems, mItems, mSize * {field.FieldType.Stride});\n"); + } + Compiler.MixinRoot(code); + } + + void* oldAlloc = null; + if (newSize > 0) + { + Emit_Start(); + void* newItems = Alloc(newSizeBytes); + if (mSize > 0) + { + Emit_Copy(); + } + oldAlloc = mItems; + mItems = newItems; + mOffsets = newOffsets; + mAllocSize = (.)newSize; + } + else + { + oldAlloc = mItems; + mItems = null; + mAllocSize = 0; + } + + if ((autoFree) && (oldAlloc != null)) + { + Free(oldAlloc); + return null; + } + + return oldAlloc; + } + + public void* EnsureCapacity(int min, bool autoFree) + { + int allocSize = AllocSize; + if (allocSize >= min) + return null; + + int_cosize newCapacity = (int_cosize)(allocSize == 0 ? cDefaultCapacity : allocSize * 2); + // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. + // Note that this check works even when mItems.Length overflowed thanks to the (uint) cast + //if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength; + if (newCapacity < min) newCapacity = (int_cosize)min; + return Realloc(newCapacity, autoFree); + } + + public void Reserve(int size) + { + EnsureCapacity(size, true); + } + + /// Adds an item to the back of the list. + public void Add(T item) + { + if (mSize == AllocSize) + { + // We free after the insert to allow for inserting a ref to another list element + let oldPtr = EnsureCapacity(mSize + 1, false); + Emit_Set("", "mSize", "item"); + mSize++; + Free(oldPtr); + return; + } + + Emit_Set("", "mSize", "item"); + mSize++; +#if VERSION_LIST + mVersion++; +#endif + } + + protected override void GCMarkMembers() + { + [Comptime] + void Emit() + { + String code = scope .(); + var fields = GetFields(.. scope .()); + for (var field in fields) + { + if (!field.FieldType.WantsMark) + continue; + code.AppendF($"for (int i < mSize) {{ GC.Mark!((({field.FieldType}*)((uint8*)mItems"); + if (@field.Index > 0) + code.AppendF($" + mOffsets[{@field.Index - 1}]"); + code.Append("))[i]); }\n"); + } + Compiler.MixinRoot(code); + } + + if (mItems == null) + return; + let type = typeof(T); + if ((type.[Friend]mTypeFlags & .WantsMark) == 0) + return; + Emit(); + } + + public void Clear() + { + if (mSize > 0) + { + mSize = 0; +#if VERSION_LIST + mVersion++; +#endif + } + } + + public bool Contains(T item) + { + for (int i < mSize) + if (this[i].Value == item) + return true; + return false; + } + + public void CopyTo(Span span) + { + for (int i < span.Length) + span[i] = this[i].Value; + } + + public bool Remove(T item) + { + int index = IndexOf(item); + if (index >= 0) + { + RemoveAt(index); + return true; + } + + return false; + } + + public void RemoveAt(int index) + { + Debug.Assert((uint)index < (uint)mSize); + if (index < mSize - 1) + { + int copySize = mSize - index - 1; + (void)copySize; + Emit_Copy("index", "(index + 1)", "copySize"); + } + mSize--; +#if VERSION_LIST + mVersion++; +#endif + } + + public void RemoveRange(int index, int count) + { + Debug.Assert((uint)index + (uint)count <= (uint)mSize); + if (index + count <= mSize - 1) + { + for (int i = index; i < mSize - count; i++) + mItems[i] = mItems[i + count]; + } + mSize -= (.)count; +#if VERSION_LIST + mVersion++; +#endif + } + + /// Will change the order of items in the list + public void RemoveAtFast(int index) + { + Debug.Assert((uint32)index < (uint32)mSize); + if (mSize > 1) + this[index].Value = this[mSize - 1].Value; + mSize--; +#if VERSION_LIST + mVersion++; +#endif + } + + Variant IList.this[int index] + { + get + { + return [Unbound]Variant.Create(this[index]); + } + + set + { + ThrowUnimplemented(); + } + } + + public Enumerator GetEnumerator() + { + return .(this); + } + + public int FindIndex(Predicate match) + { + for (int i = 0; i < mSize; i++) + if (match(this[i].Value)) + return i; + return -1; + } + + public int IndexOf(T item) + { + for (int i = 0; i < mSize; i++) + if (this[i].Value == item) + return i; + return -1; + } + + public int IndexOf(T item, int index) + { + for (int i = index; i < mSize; i++) + if (this[i].Value == item) + return i; + return -1; + } + + public int IndexOf(T item, int index, int count) + { + for (int i = index; i < index + count; i++) + if (this[i].Value == item) + return i; + return -1; + } + + public int IndexOfStrict(T item) + { + for (int i = 0; i < mSize; i++) + if (this[i].Value === item) + return i; + return -1; + } + + public int IndexOfStrict(T item, int index) + { + for (int i = index; i < mSize; i++) + if (this[i].Value === item) + return i; + return -1; + } + + public int IndexOfStrict(T item, int index, int count) + { + for (int i = index; i < index + count; i++) + if (this[i].Value === item) + return i; + return -1; + } + + public int IndexOfAlt(TAlt item) where TAlt : IHashable where bool : operator T == TAlt + { + for (int i = 0; i < mSize; i++) + if (this[i].Value == item) + return i; + return -1; + } + + public int LastIndexOf(T item) + { + for (int i = mSize - 1; i >= 0; i--) + if (this[i].Value == item) + return i; + return -1; + } + + public int LastIndexOfStrict(T item) + { + for (int i = mSize - 1; i >= 0; i--) + if (this[i].Value === item) + return i; + return -1; + } + + public struct Enumerator : IEnumerator, IResettable + { + private SplitList mList; + private int mIndex; +#if VERSION_LIST + private int32 mVersion; +#endif + public this(SplitList list) + { + mList = list; + mIndex = 0; +#if VERSION_LIST + mVersion = list.mVersion; +#endif + } + +#if VERSION_LIST + void CheckVersion() + { + if (mVersion != mList.mVersion) + Runtime.FatalError(cVersionError); + } +#endif + + public void Dispose() + { + } + + public bool MoveNext() mut + { + var localList = mList; + if ((uint(mIndex) < uint(localList.mSize))) + { + mIndex++; + return true; + } + return MoveNextRare(); + } + + private bool MoveNextRare() mut + { +#if VERSION_LIST + CheckVersion(); +#endif + mIndex = mList.mSize + 1; + return false; + } + + public Entry Current + { + get + { + return mList[mIndex - 1]; + } + } + + public int Index + { + get + { + return mIndex - 1; + } + } + + public int Count + { + get + { + return mList.Count; + } + } + + public void Remove() mut + { + int curIdx = mIndex - 1; + mList.RemoveAt(curIdx); +#if VERSION_LIST + mVersion = mList.mVersion; +#endif + mIndex = curIdx; + } + + public void RemoveFast() mut + { + int curIdx = mIndex - 1; + int lastIdx = mList.Count - 1; + if (curIdx < lastIdx) + mList[curIdx].Value = mList[lastIdx].Value; + mList.RemoveAt(lastIdx); +#if VERSION_LIST + mVersion = mList.mVersion; +#endif + mIndex = curIdx; + } + + public void Reset() mut + { + mIndex = 0; + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + } +} diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 17d7a8bf..1be6d59d 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -259,6 +259,9 @@ namespace System [LinkName("#CallerExpression")] public static extern String[0x00FFFFFF] CallerExpression; + [LinkName("#OrigCalleeType")] + public static extern Type OrigCalleeType; + [LinkName("#ProjectName")] public static extern String ProjectName; @@ -280,6 +283,9 @@ namespace System [LinkName("#CompileRev")] public static extern int32 CompileRev; + [LinkName("#NextId")] + public static extern int64 NextId; + [Comptime(ConstEval=true)] public static void Assert(bool cond) { @@ -287,6 +293,7 @@ namespace System Runtime.FatalError("Assert failed"); } + static extern void Comptime_SetReturnType(int32 typeId); static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str); static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags); static extern void Comptime_EmitTypeBody(int32 typeId, StringView text); @@ -309,6 +316,12 @@ namespace System Comptime_EmitTypeBody((.)owner.TypeId, text); } + [Comptime(OnlyFromComptime=true)] + public static void SetReturnType(Type type) + { + Comptime_SetReturnType((.)type.TypeId); + } + [Comptime(OnlyFromComptime=true)] public static void EmitAddInterface(Type owner, Type iface) { diff --git a/BeefLibs/corlib/src/Enum.bf b/BeefLibs/corlib/src/Enum.bf index d334bb17..08326d01 100644 --- a/BeefLibs/corlib/src/Enum.bf +++ b/BeefLibs/corlib/src/Enum.bf @@ -5,6 +5,62 @@ namespace System { struct Enum { + [NoShow(true)] + [Comptime(ConstEval=true)] + public static int GetCount() where T : Enum + { + int count = 0; + for (var field in typeof(T).GetFields()) + { + if (field.IsEnumCase) + count++; + } + return count; + } + + [NoShow(true)] + [Comptime(ConstEval=true)] + public static var GetMinValue() where T : Enum + { + Compiler.SetReturnType(typeof(T)); + + int? minValue = null; + for (var field in typeof(T).GetFields()) + { + if (field.IsEnumCase) + { + if (minValue == null) + minValue = field.[Friend]mFieldData.mData; + else + minValue = Math.Min(minValue.Value, field.[Friend]mFieldData.mData); + } + } + return minValue.ValueOrDefault; + } + + [NoShow(true)] + [Comptime(ConstEval=true)] + public static var GetMaxValue() where T : Enum + { + Compiler.SetReturnType(typeof(T)); + + int? maxValue = null; + for (var field in typeof(T).GetFields()) + { + if (field.IsEnumCase) + { + if (maxValue == null) + maxValue = field.[Friend]mFieldData.mData; + else + maxValue = Math.Max(maxValue.Value, field.[Friend]mFieldData.mData); + } + } + if (maxValue == null) + return -1; + return maxValue.ValueOrDefault; + } + + [NoShow(true)] public static void EnumToString(Type type, String strBuffer, int64 iVal) { for (var field in type.GetFields()) @@ -19,6 +75,7 @@ namespace System iVal.ToString(strBuffer); } + [NoShow(true)] public static Result Parse(StringView str, bool ignoreCase = false) where T : enum { for (var (name, data) in GetEnumerator()) @@ -32,7 +89,8 @@ namespace System return .Err; } - public static bool IsDefined(T value) + [NoShow(true)] + public static bool IsDefined(T value) where T : Enum where T : enum { for (var data in GetValues()) @@ -44,24 +102,28 @@ namespace System return false; } + [NoShow(true)] public static EnumEnumerator GetEnumerator() where TEnum : enum { return .(); } + [NoShow(true)] public static EnumValuesEnumerator GetValues() where TEnum : enum { return .(); } - + + [NoShow(true)] public static EnumNamesEnumerator GetNames() where TEnum : enum { return .(); } + [NoShow(true)] private struct EnumFieldsEnumerator where TEnum : enum { @@ -127,6 +189,7 @@ namespace System } } + [NoShow(true)] public struct EnumEnumerator : EnumFieldsEnumerator, IEnumerator<(StringView name, TEnum value)> where TEnum : enum { @@ -146,6 +209,7 @@ namespace System } } + [NoShow(true)] public struct EnumValuesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { @@ -165,6 +229,7 @@ namespace System } } + [NoShow(true)] public struct EnumNamesEnumerator : EnumFieldsEnumerator, IEnumerator where TEnum : enum { diff --git a/BeefLibs/corlib/src/Event.bf b/BeefLibs/corlib/src/Event.bf index 9e760c0d..51b71299 100644 --- a/BeefLibs/corlib/src/Event.bf +++ b/BeefLibs/corlib/src/Event.bf @@ -13,10 +13,17 @@ namespace System // If we are enumerating then mData points to the enumerator. int mData; +#if BF_64_BIT + const int sIsEnumerating = (.)0x8000'0000'0000'0000; + const int sHadEnumRemoves = 0x4000'0000'0000'0000; + const int sFlagsMask = (.)0xC000'0000'0000'0000; + const int sDataMask = ~sFlagsMask; +#else const int sIsEnumerating = 1; const int sHadEnumRemoves = 2; const int sFlagsMask = 3; const int sDataMask = ~sFlagsMask; +#endif public bool HasListeners { diff --git a/BeefLibs/corlib/src/GC.bf b/BeefLibs/corlib/src/GC.bf index f8c0e176..04153c0c 100644 --- a/BeefLibs/corlib/src/GC.bf +++ b/BeefLibs/corlib/src/GC.bf @@ -149,6 +149,22 @@ namespace System public static void ExcludeThreadId(int thereadId) {} #endif + [DisableObjectAccessChecks] + static void MarkAppendedObject(Object obj) + { +#if BF_ENABLE_REALTIME_LEAK_CHECK +#if BF_ENABLE_OBJECT_DEBUG_FLAGS + ClassVData* maskedVData = (ClassVData*)(void*)(obj.[Friend]mClassVData & ~(int)0xFF); + if (maskedVData == null) + return; +#else + if (obj.[Friend]mClassVData == null) + return; +#endif + obj.[Friend]GCMarkMembers(); +#endif + } + static void MarkDerefedObject(Object* obj) { #if BF_ENABLE_REALTIME_LEAK_CHECK diff --git a/BeefLibs/corlib/src/IO/File.bf b/BeefLibs/corlib/src/IO/File.bf index bfae4061..2926569c 100644 --- a/BeefLibs/corlib/src/IO/File.bf +++ b/BeefLibs/corlib/src/IO/File.bf @@ -31,7 +31,7 @@ namespace System.IO public static Result ReadAll(StringView path, List outData) { FileStream fs = scope FileStream(); - var result = fs.Open(path, .Open, .Read); + var result = fs.Open(path, .Open, .Read, .ReadWrite); if (result case .Err(let err)) return .Err(.OpenError(err)); diff --git a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf index 420757ac..1a73b017 100644 --- a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf +++ b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf @@ -110,7 +110,7 @@ namespace System.IO Windows.SHCreateItemFromParsingName(mSelectedPath.ToScopedNativeWChar!(), null, Windows.COM_IShellItem.sIID, (void**)&folderShellItem); if (folderShellItem != null) { - fileDialog.VT.SetDefaultFolder(fileDialog, folderShellItem); + fileDialog.VT.SetFolder(fileDialog, folderShellItem); folderShellItem.VT.Release(folderShellItem); } } diff --git a/BeefLibs/corlib/src/IO/MemoryStream.bf b/BeefLibs/corlib/src/IO/MemoryStream.bf index 53dbe501..1522dad0 100644 --- a/BeefLibs/corlib/src/IO/MemoryStream.bf +++ b/BeefLibs/corlib/src/IO/MemoryStream.bf @@ -4,7 +4,8 @@ namespace System.IO { class MemoryStream : Stream { - List mMemory ~ delete _; + bool mOwns; + List mMemory ~ { if (mOwns) delete _; } int mPosition = 0; public override int64 Position @@ -46,14 +47,18 @@ namespace System.IO public this() { + mOwns = true; mMemory = new List(); } - public this(List memory) + public this(List memory, bool owns = true) { + mOwns = owns; mMemory = memory; } + public List Memory => mMemory; + public override Result TryRead(Span data) { let count = data.Length; diff --git a/BeefLibs/corlib/src/IRefCounted.bf b/BeefLibs/corlib/src/IRefCounted.bf index 1a0b7ca3..a62a01d0 100644 --- a/BeefLibs/corlib/src/IRefCounted.bf +++ b/BeefLibs/corlib/src/IRefCounted.bf @@ -6,7 +6,7 @@ namespace System interface IRefCounted { void AddRef(); - void ReleaseRef(); + void Release(); } class RefCounted : IRefCounted @@ -63,5 +63,167 @@ namespace System Debug.Assert(refCount >= 0); return refCount; } + + void IRefCounted.Release() + { + ReleaseRef(); + } + + struct Alloc + { + public void* Alloc(Type type, int size, int align) + { + int sizeAdd = size + Math.Max(align, sizeof(int)); + + void* data = Internal.Malloc(sizeAdd); + return (uint8*)data + sizeAdd; + } + } + } + + class RefCounted : IRefCounted where T : class, delete + { + public T mVal; + public int mRefCount = 1; + + public int RefCount => mRefCount; + public T Value => mVal; + + protected this() + { + + } + + protected ~this() + { + Debug.Assert(mRefCount == 0); + delete mVal; + } + + [OnCompile(.TypeInit), Comptime] + static void Init() + { + String emitStr = scope .(); + + for (var methodInfo in typeof(T).GetMethods(.Public)) + { + if (methodInfo.IsStatic) + continue; + if (!methodInfo.IsConstructor) + continue; + + emitStr.AppendF("public static RefCounted Create("); + methodInfo.GetParamsDecl(emitStr); + emitStr.AppendF(")\n"); + emitStr.AppendF("{{\n"); + emitStr.AppendF("\treturn new [Friend] RefCountedAppend("); + methodInfo.GetArgsList(emitStr); + emitStr.AppendF(");\n}}\n"); + } + + Compiler.EmitTypeBody(typeof(Self), emitStr); + } + + public static RefCounted Attach(T val) + { + return new Self() { mVal = val }; + } + + public virtual void DeleteSelf() + { + delete this; + } + + public void DeleteUnchecked() + { + mRefCount = 0; + DeleteSelf(); + } + + public void AddRef() + { + Interlocked.Increment(ref mRefCount); + } + + public void Release() + { + int refCount = Interlocked.Decrement(ref mRefCount); + Debug.Assert(refCount >= 0); + if (refCount == 0) + DeleteSelf(); + } + + public void ReleaseLastRef() + { + int refCount = Interlocked.Decrement(ref mRefCount); + Debug.Assert(refCount == 0); + if (refCount == 0) + DeleteSelf(); + } + + public int ReleaseRefNoDelete() + { + int refCount = Interlocked.Decrement(ref mRefCount); + Debug.Assert(refCount >= 0); + return refCount; + } + + public virtual T Detach() + { + var val = mVal; + mVal = null; + return val; + } + + public static T operator->(Self self) + { + return self.mVal; + } + + public static T operator implicit(Self self) + { + return self.mVal; + } + } + + class RefCountedAppend : RefCounted where T : class, new, delete + { + protected ~this() + { + Debug.Assert(mRefCount == 0); + delete:append mVal; + mVal = null; + } + + [OnCompile(.TypeInit), Comptime] + static void Init() + { + String emitStr = scope .(); + + for (var methodInfo in typeof(T).GetMethods(.Public)) + { + if (methodInfo.IsStatic) + continue; + if (!methodInfo.IsConstructor) + continue; + + emitStr.AppendF("[AllowAppend]\nprotected this("); + methodInfo.GetParamsDecl(emitStr); + emitStr.AppendF(")\n"); + emitStr.AppendF("{{\n"); + emitStr.AppendF("\tvar val = append T("); + methodInfo.GetArgsList(emitStr); + emitStr.AppendF(");\n"); + emitStr.AppendF("\tmVal = val;\n"); + emitStr.AppendF("}}\n"); + } + + Compiler.EmitTypeBody(typeof(Self), emitStr); + } + + public override T Detach() + { + Runtime.FatalError("Can only detach from objects created via RefCounted.Attach"); + } } } diff --git a/BeefLibs/corlib/src/Internal.bf b/BeefLibs/corlib/src/Internal.bf index 26b1f49a..0ecbd02a 100644 --- a/BeefLibs/corlib/src/Internal.bf +++ b/BeefLibs/corlib/src/Internal.bf @@ -72,11 +72,6 @@ namespace System return &mVAList; #endif } - - public void* ToVAListPtr() mut - { - return &mVAList; - } } [AlwaysInclude] @@ -89,6 +84,8 @@ namespace System [CallingConvention(.Cdecl), NoReturn] public static extern void ThrowIndexOutOfRange(int stackOffset = 0); [CallingConvention(.Cdecl), NoReturn] + public static extern void ThrowObjectNotInitialized(int stackOffset = 0); + [CallingConvention(.Cdecl), NoReturn] public static extern void FatalError(String error, int stackOffset = 0); [Intrinsic("memcpy")] public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false); diff --git a/BeefLibs/corlib/src/Lazy.bf b/BeefLibs/corlib/src/Lazy.bf new file mode 100644 index 00000000..f33470c1 --- /dev/null +++ b/BeefLibs/corlib/src/Lazy.bf @@ -0,0 +1,288 @@ +using System.Threading; + +namespace System +{ + enum LazyThreadMode + { + None, + Lock, + Lockless + } + + class Lazy + { + protected struct Entry + { + public SelfOuter mSingleton; + public T mValue; + } + + protected Monitor mMonitor ~ delete _; + protected LazyThreadMode mThreadMode; + protected volatile int mInitId; + protected T mValue; + delegate T() mCreateDlg ~ delete _; + delegate void(T value) mReleaseDlg ~ delete _; + + public this() + { + + } + + public this(LazyThreadMode threadMode) + { + mThreadMode = threadMode; + Init(); + } + + public this(LazyThreadMode threadMode, delegate T() createDlg = null, delegate void(T value) releaseDlg = null) + { + mThreadMode = threadMode; + mCreateDlg = createDlg; + mReleaseDlg = releaseDlg; + Init(); + } + + public this(delegate void(T value) releaseDlg) : this() + { + mReleaseDlg = releaseDlg; + } + + void Init() + { + switch (mThreadMode) + { + case .None: + case .Lock: + mMonitor = new Monitor(); + case .Lockless: + } + + } + + public ~this() + { + ReleaseValue(mut mValue); + } + + protected T DefaultCreateValue() + { + return default; + } + + protected T DefaultCreateValue() where T : struct, new + { + return T(); + } + + protected T DefaultCreateValue() where T : class + { + Runtime.FatalError("No create delegate specified and no public default constructor is available"); + } + + protected T DefaultCreateValue() where T : class, new + { + return new T(); + } + + protected virtual T CreateValue() + { + return DefaultCreateValue(); + } + + protected void DefaultReleaseValue(mut T val) + { + + } + + protected void DefaultReleaseValue(mut T val) where T : struct, IDisposable + { + val.Dispose(); + } + + protected void DefaultReleaseValue(mut T val) where T : class + { + delete (Object)val; + } + + protected virtual void ReleaseValue(mut T val) + { + DefaultReleaseValue(mut val); + } + + public ref T Value + { + get + { + if (mInitId == -1) + return ref mValue; + + switch (mThreadMode) + { + case .None: + mValue = CreateValue(); + case .Lock: + using (mMonitor.Enter()) + { + if (mInitId != -1) + { + mValue = CreateValue(); + Interlocked.Fence(); + mInitId = -1; + } + } + case .Lockless: + int threadId = Thread.CurrentThreadId; + while (true) + { + int initId = Interlocked.CompareExchange(ref mInitId, 0, threadId); + if (initId == -1) + break; + + if (initId == 0) + { + Interlocked.Fence(); + mValue = CreateValue(); + Interlocked.Fence(); + mInitId = -1; + break; + } + } + } + return ref mValue; + } + } + + public bool IsValueCreated => mInitId != 0; + + public static ref T operator->(Self self) => ref self.[Inline]Value; + + public override void ToString(String strBuffer) + { + if (IsValueCreated) + strBuffer.AppendF($"Value: {Value}"); + else + strBuffer.AppendF($"No Value"); + } + } + + class LazyTLS + { + protected struct Entry + { + public SelfOuter mSingleton; + public T mValue; + } + + void* mData; + delegate T() mCreateDlg ~ delete _; + delegate void(T value) mReleaseDlg ~ delete _; + + public this() + { + InitTLS(); + } + + public this(delegate T() createDlg = null, delegate void(T value) releaseDlg = null) + { + mCreateDlg = createDlg; + mReleaseDlg = releaseDlg; + InitTLS(); + } + + void InitTLS() + { + mData = Platform.BfpTLS_Create((ptr) => + { + var entry = (Entry*)ptr; + if (entry.mSingleton.mReleaseDlg != null) + entry.mSingleton.mReleaseDlg(entry.mValue); + else + entry.mSingleton.ReleaseValue(mut entry.mValue); + delete entry; + }); + } + + public ~this() + { + Platform.BfpTLS_Release((.)mData); + } + + protected T DefaultCreateValue() + { + return default; + } + + protected T DefaultCreateValue() where T : struct, new + { + return T(); + } + + protected T DefaultCreateValue() where T : class + { + Runtime.FatalError("No create delegate specified and no public default constructor is available"); + } + + protected T DefaultCreateValue() where T : class, new + { + return new T(); + } + + protected virtual T CreateValue() + { + return DefaultCreateValue(); + } + + protected void DefaultReleaseValue(mut T val) + { + + } + + protected void DefaultReleaseValue(mut T val) where T : struct, IDisposable + { + val.Dispose(); + } + + + protected void DefaultReleaseValue(mut T val) where T : class + { + delete (Object)val; + } + + protected virtual void ReleaseValue(mut T val) + { + DefaultReleaseValue(mut val); + } + + public ref T Value + { + get + { + void* ptr = Platform.BfpTLS_GetValue((.)mData); + if (ptr != null) + return ref ((Entry*)ptr).mValue; + + Entry* entry = new Entry(); + entry.mSingleton = this; + if (mCreateDlg != null) + entry.mValue = mCreateDlg(); + else + entry.mValue = CreateValue(); + Platform.BfpTLS_SetValue((.)mData, entry); + return ref entry.mValue; + } + } + + public bool IsValueCreated => Platform.BfpTLS_GetValue((.)mData) != null; + + public static ref T operator->(Self self) => ref self.[Inline]Value; + + public override void ToString(String strBuffer) + { + if (IsValueCreated) + strBuffer.AppendF($"Value: {Value}"); + else + strBuffer.AppendF($"No Value"); + } + } +} diff --git a/BeefLibs/corlib/src/Math.bf b/BeefLibs/corlib/src/Math.bf index ccd1aab0..3777f47b 100644 --- a/BeefLibs/corlib/src/Math.bf +++ b/BeefLibs/corlib/src/Math.bf @@ -192,8 +192,18 @@ namespace System [CLink] private static extern double modf(double x, out double intpart); + +#if BF_PLATFORM_WINDOWS && BF_64_BIT [CLink] private static extern float modff(float x, out float intpart); +#else + private static float modff(float x, out float intpart) + { + var f = modf(x, var i); + intpart = (.)i; + return (.)f; + } +#endif public static float Truncate(float f) { diff --git a/BeefLibs/corlib/src/Nullable.bf b/BeefLibs/corlib/src/Nullable.bf index 1e195af7..6830b790 100644 --- a/BeefLibs/corlib/src/Nullable.bf +++ b/BeefLibs/corlib/src/Nullable.bf @@ -35,6 +35,15 @@ namespace System } } + public T ValueOrDefault + { + [Inline] + get + { + return mValue; + } + } + public ref T ValueRef { [Inline] @@ -96,9 +105,19 @@ namespace System [Inline] public static explicit operator T(Nullable value) { + if (!value.mHasValue) + Debug.FatalError("Value requested for null nullable."); return value.mValue; } + [Inline] + public static ref T operator->(ref Nullable value) + { + if (!value.mHasValue) + Debug.FatalError("Value requested for null nullable."); + return ref value.mValue; + } + [Inline, Commutable] public static bool operator==(Nullable lhs, T rhs) { @@ -401,31 +420,6 @@ namespace System return Nullable(lhs.mValue | rhs.mValue); } - // - - public static T operator??(Nullable lhs, T rhs) - { - return (lhs.mHasValue) ? lhs.mValue : rhs; - } - - public static TResult? operator??(TOther lhs, Nullable rhs) where TResult : operator TOther ?? T where TResult : struct - { - if (!rhs.mHasValue) return null; - return Nullable(lhs ?? rhs.mValue); - } - - public static TResult? operator??(Nullable lhs, TOther rhs) where TResult : operator T ?? TOther where TResult : struct - { - if (!lhs.mHasValue) return null; - return Nullable(lhs.mValue ?? rhs); - } - - public static TResult? operator??(Nullable lhs, Nullable rhs) where TOther : struct where TResult : operator T ?? TOther where TResult : struct - { - if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null; - return Nullable(lhs.mValue ?? rhs.mValue); - } - // public static TResult? operator<< (TOther lhs, Nullable rhs) where TResult : operator TOther << T where TResult : struct diff --git a/BeefLibs/corlib/src/Platform.bf b/BeefLibs/corlib/src/Platform.bf index b23c378f..7fc94710 100644 --- a/BeefLibs/corlib/src/Platform.bf +++ b/BeefLibs/corlib/src/Platform.bf @@ -42,6 +42,7 @@ namespace System public struct BfpEvent {}; public struct BfpFileWatcher {} public struct BfpProcess {} + public struct BfpTLS; public enum BfpSystemResult : int32 { @@ -95,6 +96,18 @@ namespace System [CallingConvention(.Stdcall), CLink] public static extern void BfpSystem_GetComputerName(char8* outStr, int32* inOutStrSize, BfpSystemResult* outResult); + [CallingConvention(.Stdcall), CLink] + public static extern int BfpThread_GetCurrentId(); + + [CallingConvention(.Stdcall), CLink] + public static extern BfpTLS* BfpTLS_Create(function [CallingConvention(.Stdcall)] void(void*) exitProc); + [CallingConvention(.Stdcall), CLink] + public static extern void BfpTLS_Release(BfpTLS* tls); + [CallingConvention(.Stdcall), CLink] + public static extern void BfpTLS_SetValue(BfpTLS* tls, void* value); + [CallingConvention(.Stdcall), CLink] + public static extern void* BfpTLS_GetValue(BfpTLS* tls); + public enum BfpFileWatcherFlags : int32 { None = 0, diff --git a/BeefLibs/corlib/src/Range.bf b/BeefLibs/corlib/src/Range.bf index 7614d3c6..2ff245fc 100644 --- a/BeefLibs/corlib/src/Range.bf +++ b/BeefLibs/corlib/src/Range.bf @@ -225,6 +225,187 @@ namespace System } } + struct Range where T : operator T + int where int : operator T - T where bool : operator T >= T + { + protected T mStart; + protected T mEnd; + + public this() + { + mStart = default; + mEnd = default; + } + + [Inline] + public this(T start, T end) + { + Debug.Assert(end >= start); + mStart = start; + mEnd = end; + } + + public int Length + { + [Inline] + get + { + return mEnd - mStart; + } + + [Inline] + set mut + { + mEnd = mStart + value; + } + } + + public T Start + { + [Inline] + get + { + return mStart; + } + + [Inline] + set mut + { + mStart = value; + } + } + + public T End + { + [Inline] + get + { + return mEnd; + } + + set mut + { + mEnd = value; + } + } + + public bool IsEmpty + { + [Inline] + get + { + return mEnd == mStart; + } + } + + public ReverseEnumerator Reversed + { + [Inline] + get + { + return ReverseEnumerator(mEnd + -1, mStart); + } + } + + public bool Contains(T idx) + { + return (idx >= mStart) && !(idx >= mEnd); + } + + public bool Contains(Range val) + { + return (val.[Friend]mStart >= mStart) && (val.[Friend]mEnd <= mEnd); + } + + public void Clear() mut + { + mStart = default; + mEnd = default; + } + + [Inline] + public Enumerator GetEnumerator() + { + return Enumerator(this); + } + + public override void ToString(String strBuffer) + { + strBuffer.AppendF($"{mStart}..<{mEnd}"); + } + + public struct Enumerator : IEnumerator + { + private T mEnd; + private T mIndex; + + [Inline] + public this(Range range) + { + mIndex = range.mStart + -1; + mEnd = range.mEnd; + } + + public void Dispose() + { + } + + public ref T Index + { + get mut + { + return ref mIndex; + } + } + + public T End => mEnd; + + [Inline] + public Result GetNext() mut + { + if (mIndex + 1 >= mEnd) + return .Err; + mIndex += 1; + return mIndex; + } + } + + public struct ReverseEnumerator : IEnumerator + { + private T mEnd; + private T mIndex; + + [Inline] + public this(T start, T end) + { + mIndex = start + 1; + mEnd = end; + } + + public void Dispose() + { + } + + public ref T Index + { + get mut + { + return ref mIndex; + } + } + + public T End => mEnd; + + [Inline] + public Result GetNext() mut + { + if (mIndex <= mEnd) + return .Err; + mIndex += -1; + return mIndex; + } + } + } + struct IndexRange : RangeExpression { protected Index mStart; diff --git a/BeefLibs/corlib/src/Reflection/FieldInfo.bf b/BeefLibs/corlib/src/Reflection/FieldInfo.bf index e75d8f57..e3066926 100644 --- a/BeefLibs/corlib/src/Reflection/FieldInfo.bf +++ b/BeefLibs/corlib/src/Reflection/FieldInfo.bf @@ -8,7 +8,8 @@ namespace System.Reflection public enum Error { InvalidTargetType, - InvalidValueType + InvalidValueType, + AppendedField } TypeInstance mTypeInstance; @@ -24,6 +25,8 @@ namespace System.Reflection public int32 MemberOffset => (int32)mFieldData.mData; public Type FieldType => Type.[Friend]GetType(mFieldData.mFieldTypeId); public bool IsConst => mFieldData.mFlags.HasFlag(.Const); + public bool IsAppended => mFieldData.mFlags.HasFlag(.Appended); + public bool IsEnumCase => mFieldData.mFlags.HasFlag(.EnumCase); public bool IsReadOnly => mFieldData.mFlags.HasFlag(.ReadOnly); public bool IsStatic => mFieldData.mFlags.HasFlag(.Static); public bool IsPublic => (mFieldData.mFlags & .FieldAccessMask) == .Public; @@ -85,7 +88,12 @@ namespace System.Reflection if (valueType == fieldType) { if (valueType.IsObject) + { + if (mFieldData.mFlags.HasFlag(.Appended)) + return .Err(.AppendedField); + *((void**)dataAddr) = Internal.UnsafeCastToPtr(value); + } else Internal.MemCpy(dataAddr, valueDataAddr, fieldType.[Friend]mSize); } @@ -384,7 +392,10 @@ namespace System.Reflection if (typeCode == TypeCode.Object) { value.[Friend]mStructType = 0; - value.[Friend]mData = *(int*)targetDataAddr; + if (mFieldData.mFlags.HasFlag(.Appended)) + value.[Friend]mData = (int)targetDataAddr; + else + value.[Friend]mData = *(int*)targetDataAddr; } else { diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index cf814559..8ec9dd4f 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -50,6 +50,9 @@ namespace System.Reflection public bool IsReadOnly => Compiler.IsComptime ? Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.ReadOnly) : mData.mMethodData.[Friend]mFlags.HasFlag(.ReadOnly); + public bool IsStatic => Compiler.IsComptime ? + Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.Static) : + mData.mMethodData.[Friend]mFlags.HasFlag(.Static); public StringView Name => Compiler.IsComptime ? Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) : @@ -112,6 +115,19 @@ namespace System.Reflection } } + public TypeInstance.ParamFlags GetParamFlags(int paramIdx) + { + if (Compiler.IsComptime) + { + return Type.[Friend]Comptime_Method_GetParamInfo(mData.mComptimeMethodInstance, (.)paramIdx).mParamFlags; + } + else + { + Debug.Assert((uint)paramIdx < (uint)mData.mMethodData.mParamCount); + return mData.mMethodData.mParamData[paramIdx].mParamFlags; + } + } + public Result GetParamCustomAttribute(int paramIdx) where T : Attribute { if (Compiler.IsComptime) @@ -967,19 +983,60 @@ namespace System.Reflection strBuffer.Append(' '); strBuffer.Append(mData.mMethodData.mName); strBuffer.Append('('); + + int useParamIdx = 0; for (int paramIdx < mData.mMethodData.mParamCount) { - if (paramIdx > 0) - strBuffer.Append(", "); let paramData = mData.mMethodData.mParamData[paramIdx]; let paramType = Type.[Friend]GetType(paramData.mType); + if (paramData.mParamFlags.HasFlag(.Implicit)) + continue; + if (useParamIdx > 0) + strBuffer.Append(", "); paramType.ToString(strBuffer); strBuffer.Append(' '); strBuffer.Append(paramData.mName); + useParamIdx++; } strBuffer.Append(')'); } + public void GetParamsDecl(String strBuffer) + { + int useParamIdx = 0; + for (int paramIdx < ParamCount) + { + var flag = GetParamFlags(paramIdx); + if (flag.HasFlag(.Implicit)) + continue; + if (useParamIdx > 0) + strBuffer.Append(", "); + if (flag.HasFlag(.Params)) + strBuffer.Append("params "); + strBuffer.Append(GetParamType(paramIdx)); + strBuffer.Append(" "); + strBuffer.Append(GetParamName(paramIdx)); + useParamIdx++; + } + } + + public void GetArgsList(String strBuffer) + { + int useParamIdx = 0; + for (int paramIdx < ParamCount) + { + var flag = GetParamFlags(paramIdx); + if (flag.HasFlag(.Implicit)) + continue; + if (useParamIdx > 0) + strBuffer.Append(", "); + if (flag.HasFlag(.Params)) + strBuffer.Append("params "); + strBuffer.Append(GetParamName(paramIdx)); + useParamIdx++; + } + } + public struct Enumerator : IEnumerator { BindingFlags mBindingFlags; diff --git a/BeefLibs/corlib/src/Result.bf b/BeefLibs/corlib/src/Result.bf index a4aa719c..2b6fe451 100644 --- a/BeefLibs/corlib/src/Result.bf +++ b/BeefLibs/corlib/src/Result.bf @@ -27,6 +27,22 @@ namespace System } } + public ref T ValueRef + { + [Inline] + get mut + { + switch (this) + { + case .Ok(var ref val): return ref val; + case .Err: + { + Internal.FatalError("Unhandled error in result", 2); + } + } + } + } + [Inline] public static implicit operator Result(T value) { @@ -39,6 +55,19 @@ namespace System return result.Unwrap(); } + [Inline] + public static mut T operator->(ref Result result) + { + switch (result) + { + case .Ok(var mut val): return mut val; + case .Err: + { + Internal.FatalError("Unhandled error in result", 2); + } + } + } + [Inline] public void IgnoreError() { @@ -99,7 +128,7 @@ namespace System extension Result where T : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); @@ -116,9 +145,9 @@ namespace System switch (this) { case .Ok(var val): return val; - case .Err(var err): + case .Err: { - Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n {}", err), 2); + Internal.FatalError("Unhandled error in result", 2); } } } @@ -131,16 +160,47 @@ namespace System } } + public ref T ValueRef + { + [Inline] + get mut + { + switch (this) + { + case .Ok(var ref val): return ref val; + case .Err: + { + Internal.FatalError("Unhandled error in result", 2); + } + } + } + } + + [Inline] public static implicit operator Result(T value) { return .Ok(value); } + [Inline] public static implicit operator T(Result result) { return result.Unwrap(); } + [Inline] + public static mut T operator->(ref Result result) + { + switch (result) + { + case .Ok(var mut val): return mut val; + case .Err: + { + Internal.FatalError("Unhandled error in result", 2); + } + } + } + public void IgnoreError() { } @@ -203,7 +263,7 @@ namespace System extension Result where T : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); @@ -212,7 +272,7 @@ namespace System extension Result where TErr : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Err(var err)) err.Dispose(); @@ -221,7 +281,7 @@ namespace System extension Result where T : IDisposable where TErr : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); diff --git a/BeefLibs/corlib/src/Runtime.bf b/BeefLibs/corlib/src/Runtime.bf index b2861236..528a672c 100644 --- a/BeefLibs/corlib/src/Runtime.bf +++ b/BeefLibs/corlib/src/Runtime.bf @@ -9,7 +9,7 @@ namespace System [StaticInitPriority(101)] static class Runtime { - const int32 cVersion = 9; + const int32 cVersion = 10; [CRepr, AlwaysInclude] struct BfDebugMessageData @@ -118,6 +118,7 @@ namespace System function bool (Object thread) mThread_IsAutoDelete; function void (Object thread) mThread_AutoDelete; function int32 (Object thread) mThread_GetMaxStackSize; + function void () mThread_Exiting; function void () mGC_MarkAllStaticMembers; function bool () mGC_CallRootCallbacks; function void () mGC_Shutdown; @@ -146,7 +147,7 @@ namespace System static Type Object_GetType(Object obj) { #if BF_DBG_RUNTIME - return obj.[Friend]RawGetType(); + return obj.[Friend, DisableObjectAccessChecks]RawGetType(); #else return null; #endif diff --git a/BeefLibs/corlib/src/Span.bf b/BeefLibs/corlib/src/Span.bf index 4931bbaf..758f6e89 100644 --- a/BeefLibs/corlib/src/Span.bf +++ b/BeefLibs/corlib/src/Span.bf @@ -276,6 +276,7 @@ namespace System public void RemoveFromEnd(int length) mut { + Debug.Assert((uint)length <= (uint)mLength); mLength -= length; } diff --git a/BeefLibs/corlib/src/String.bf b/BeefLibs/corlib/src/String.bf index 514981be..5b93082a 100644 --- a/BeefLibs/corlib/src/String.bf +++ b/BeefLibs/corlib/src/String.bf @@ -40,7 +40,7 @@ namespace System [Ordered] class String : IHashable, IFormattable, IPrintable { - enum CreateFlags + public enum CreateFlags { None = 0, NullTerminate = 1 @@ -48,7 +48,7 @@ namespace System int_strsize mLength; uint_strsize mAllocSizeAndFlags; - char8* mPtr = null; + char8* mPtrOrBuffer = null; extern const String* sStringLiterals; extern const String* sIdStringLiterals; @@ -210,8 +210,8 @@ namespace System [AllowAppend] public this(StringView strView) { - let tryBufferSize = strView.Length - sizeof(char8*); - let bufferSize = (tryBufferSize >= 0) ? tryBufferSize : 0; + let count = strView.Length; + int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1); #unwarn char8* addlPtr = append char8[bufferSize]*(?); Init(bufferSize); @@ -326,7 +326,7 @@ namespace System public ~this() { if (IsDynAlloc) - delete:this mPtr; + delete:this mPtrOrBuffer; } void FakeMethod () @@ -390,7 +390,7 @@ namespace System //[Optimize] get { - return ((mAllocSizeAndFlags & cStrPtrFlag) != 0) ? mPtr : (char8*)&mPtr; + return ((mAllocSizeAndFlags & cStrPtrFlag) != 0) ? mPtrOrBuffer : (char8*)&mPtrOrBuffer; } } @@ -660,10 +660,10 @@ namespace System { if (str.IsDynAlloc) { - delete str.mPtr; + delete str.mPtrOrBuffer; } - str.mPtr = mPtr; + str.mPtrOrBuffer = mPtrOrBuffer; str.mAllocSizeAndFlags = mAllocSizeAndFlags; str.mLength = mLength; @@ -673,7 +673,7 @@ namespace System } else { - mPtr = null; + mPtrOrBuffer = null; mAllocSizeAndFlags = (int_strsize)sizeof(char8*); mLength = 0; } @@ -689,8 +689,8 @@ namespace System public void Reference(String str) { if (IsDynAlloc) - delete:this mPtr; - mPtr = str.Ptr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = str.Ptr; mLength = str.mLength; mAllocSizeAndFlags = cStrPtrFlag; } @@ -698,8 +698,8 @@ namespace System public void Reference(char8* ptr, int length, int allocSize) { if (IsDynAlloc) - delete:this mPtr; - mPtr = ptr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = ptr; mLength = (int_strsize)length; mAllocSizeAndFlags = cStrPtrFlag; } @@ -707,8 +707,8 @@ namespace System public void Reference(char8* ptr, int length) { if (IsDynAlloc) - delete:this mPtr; - mPtr = ptr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = ptr; mLength = (int_strsize)length; mAllocSizeAndFlags = cStrPtrFlag; } @@ -721,8 +721,8 @@ namespace System public void Reference(char8* ptr) { if (IsDynAlloc) - delete:this mPtr; - mPtr = ptr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = ptr; mLength = StrLen(ptr); mAllocSizeAndFlags = cStrPtrFlag; } @@ -734,7 +734,7 @@ namespace System Debug.Assert(!IsDynAlloc); Debug.Assert(AllocSize == 0); // Assert is reference Debug.Assert((uint)mLength >= (uint)adjBytes); - mPtr += adjBytes; + mPtrOrBuffer += adjBytes; mLength -= (int_strsize)adjBytes; } @@ -763,8 +763,8 @@ namespace System Internal.MemSet(newPtr + mLength, 0, newSize - mLength); #endif if (IsDynAlloc) - delete:this mPtr; - mPtr = newPtr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = newPtr; mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag; } @@ -780,8 +780,8 @@ namespace System Debug.Assert((uint)newSize <= cSizeFlags); Internal.MemCpy(newPtr, Ptr, mLength); if (IsDynAlloc) - delete:this mPtr; - mPtr = newPtr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = newPtr; mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag; } @@ -1313,7 +1313,7 @@ namespace System if (pos == len || (ch = format[pos]) < '0' || ch > '9') { if ((pos < len) && - ((ch == '}') || (ch == ':'))) + ((ch == '}') || (ch == ':') || (ch == ','))) index = autoArgIdx++; else return FormatError(); @@ -1603,8 +1603,8 @@ namespace System newPtr[outIdx] = '\0'; if (IsDynAlloc) - delete mPtr; - mPtr = newPtr; + delete mPtrOrBuffer; + mPtrOrBuffer = newPtr; mAllocSizeAndFlags = (uint_strsize)newSize | cDynAllocFlag | cStrPtrFlag; } } @@ -1633,8 +1633,8 @@ namespace System int newLen = UTF8Map(Ptr, mLength, newStr, allocSize, (int32)unicodeNormalizationOptions); if (IsDynAlloc) - delete:this mPtr; - mPtr = newStr; + delete:this mPtrOrBuffer; + mPtrOrBuffer = newStr; mLength = (int_strsize)newLen; mAllocSizeAndFlags = (uint32)(allocSize) | cDynAllocFlag | cStrPtrFlag; return .Ok; @@ -1656,8 +1656,8 @@ namespace System int newLen = UTF8Map(Ptr, mLength, newStr, allocSize, (int32)unicodeNormalizationOptions); if (destStr.IsDynAlloc) - delete:destStr destStr.mPtr; - destStr.mPtr = newStr; + delete:destStr destStr.mPtrOrBuffer; + destStr.mPtrOrBuffer = newStr; destStr.mLength = (int_strsize)newLen; destStr.mAllocSizeAndFlags = (uint_strsize)(newLen + 1) | cDynAllocFlag | cStrPtrFlag; return .Ok; @@ -2059,7 +2059,7 @@ namespace System { if (mLength != str.[Friend]mLength) return false; - return EqualsHelper(str.Ptr, mPtr, mLength); + return EqualsHelper(str.Ptr, Ptr, mLength); } public bool Equals(StringView str, StringComparison comparisonType = StringComparison.Ordinal) @@ -2067,8 +2067,8 @@ namespace System if (mLength != str.[Friend]mLength) return false; if (comparisonType == StringComparison.OrdinalIgnoreCase) - return EqualsIgnoreCaseHelper(str.Ptr, mPtr, mLength); - return EqualsHelper(str.Ptr, mPtr, mLength); + return EqualsIgnoreCaseHelper(str.Ptr, Ptr, mLength); + return EqualsHelper(str.Ptr, Ptr, mLength); } public bool StartsWith(StringView b, StringComparison comparisonType = StringComparison.Ordinal) @@ -2488,6 +2488,56 @@ namespace System return StringSplitEnumerator(Ptr, Length, separators, count, options); } + public StringSplitEnumerator Split(char8[] separators, StringSplitOptions options) + { + return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options); + } + + public StringStringSplitEnumerator Split(StringView sv) + { + return StringStringSplitEnumerator(Ptr, Length, sv, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView separator, int count) + { + return StringStringSplitEnumerator(Ptr, Length, separator, count, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView separator, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separator, Int32.MaxValue, options); + } + + public StringStringSplitEnumerator Split(StringView separator, int count, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separator, count, options); + } + + public StringStringSplitEnumerator Split(params StringView[] separators) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators, int count) + { + return StringStringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators, int count, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separators, count, options); + } + + public StringStringSplitEnumerator Split(StringView[] separators, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options); + } + public static mixin NewOrSet(var target, var source) { if (target == null) @@ -2914,11 +2964,11 @@ namespace System RemoveEmptyEntries = 1 } - struct StringSplitEnumerator : IEnumerator + public struct StringSplitEnumerator : IEnumerator { StringSplitOptions mSplitOptions; - char8 mSplitChar0; - char8[] mSplitChars; + char8 mFirstSeparator; + char8[] mSeparators; char8* mPtr; int_strsize mStrLen; int32 mCurCount; @@ -2926,15 +2976,15 @@ namespace System int_strsize mPos; int_strsize mMatchPos; - public this(char8* ptr, int strLength, char8[] splitChars, int count, StringSplitOptions splitOptions) + public this(char8* ptr, int strLength, char8[] separators, int count, StringSplitOptions splitOptions) { mPtr = ptr; mStrLen = (int_strsize)strLength; - if (splitChars.Count > 0) - mSplitChar0 = splitChars[0]; + if (separators?.Count > 0) + mFirstSeparator = separators[0]; else - mSplitChar0 = '\0'; - mSplitChars = splitChars; + mFirstSeparator = '\0'; + mSeparators = separators; mCurCount = 0; mMaxCount = (int32)count; mPos = 0; @@ -2942,12 +2992,12 @@ namespace System mSplitOptions = splitOptions; } - public this(char8* ptr, int strLength, char8 splitChar, int count, StringSplitOptions splitOptions) + public this(char8* ptr, int strLength, char8 separator, int count, StringSplitOptions splitOptions) { mPtr = ptr; mStrLen = (int_strsize)strLength; - mSplitChar0 = splitChar; - mSplitChars = null; + mFirstSeparator = separator; + mSeparators = null; mCurCount = 0; mMaxCount = (int32)count; mPos = 0; @@ -3028,14 +3078,18 @@ namespace System else { char8 c = mPtr[mMatchPos]; - if (c == mSplitChar0) + if (c.IsWhiteSpace && mFirstSeparator == '\0' && (mSeparators == null || mSeparators.IsEmpty)) { foundMatch = true; } - else if (mSplitChars != null) + else if (c == mFirstSeparator) { - for (int i = 1; i < mSplitChars.Count; i++) - if (c == mSplitChars[i]) + foundMatch = true; + } + else if (mSeparators != null) + { + for (int i = 1; i < mSeparators.Count; i++) + if (c == mSeparators[i]) foundMatch = true; } } @@ -3070,6 +3124,179 @@ namespace System } } + public struct StringStringSplitEnumerator : IEnumerator + { + StringSplitOptions mSplitOptions; + StringView mFirstSeparator; + StringView[] mSeparators; + char8* mPtr; + int_strsize mStrLen; + int32 mCurCount; + int32 mMaxCount; + int_strsize mPos; + int_strsize mMatchPos; + int_strsize mMatchLen; + + public this(char8* ptr, int strLength, StringView[] separators, int count, StringSplitOptions splitOptions) + { + mPtr = ptr; + mStrLen = (int_strsize)strLength; + if (separators?.Count > 0) + mFirstSeparator = separators[0]; + else + mFirstSeparator = .(); + mSeparators = separators; + mCurCount = 0; + mMaxCount = (int32)count; + mPos = 0; + mMatchPos = -1; + mMatchLen = 1; + mSplitOptions = splitOptions; + } + + public this(char8* ptr, int strLength, StringView separator, int count, StringSplitOptions splitOptions) + { + mPtr = ptr; + mStrLen = (int_strsize)strLength; + mFirstSeparator = separator; + mSeparators = null; + mCurCount = 0; + mMaxCount = (int32)count; + mPos = 0; + mMatchPos = -1; + mMatchLen = 1; + mSplitOptions = splitOptions; + } + + public StringView Current + { + get + { + return StringView(mPtr + mPos, mMatchPos - mPos); + } + } + + public int_strsize Pos + { + get + { + return mPos; + } + } + + public int_strsize MatchPos + { + get + { + return mMatchPos; + } + } + + public int32 MatchIndex + { + get + { + return mCurCount - 1; + } + } + + public bool HasMore + { + get + { + return mMatchPos < mStrLen; + } + } + + public bool MoveNext() mut + { + if (mCurCount >= mMaxCount) + return false; + + mPos = mMatchPos + mMatchLen; + + mCurCount++; + if (mCurCount == mMaxCount) + { + mMatchPos = (int_strsize)mStrLen; + if (mPos > mMatchPos) + return false; + if ((mMatchPos == mPos) && (mSplitOptions.HasFlag(.RemoveEmptyEntries))) + return false; + return true; + } + + int endDiff = mStrLen - mMatchPos; + if (endDiff == 0) + return false; + while (true) + { + mMatchPos++; + endDiff--; + bool foundMatch = false; + if (endDiff == 0) + { + foundMatch = true; + } + else + { + if (mFirstSeparator.IsNull && (mSeparators == null || mSeparators.IsEmpty) && mPtr[mMatchPos].IsWhiteSpace) + { + foundMatch = true; + mMatchLen = 1; + } + else if (mFirstSeparator.Length <= mStrLen - mMatchPos && StringView(&mPtr[mMatchPos], mFirstSeparator.Length) == mFirstSeparator) + { + foundMatch = true; + mMatchLen = (int_strsize)mFirstSeparator.Length; + } + else if (mSeparators != null) + { + for (int i = 1; i < mSeparators.Count; i++) + { + if (mSeparators[i].Length <= mStrLen - mMatchPos && StringView(&mPtr[mMatchPos], mSeparators[i].Length) == mSeparators[i]) + { + foundMatch = true; + mMatchLen = (int_strsize)mSeparators[i].Length; + } + } + } + } + + if (foundMatch) + { + if ((mMatchPos >= mPos + 1) || (!mSplitOptions.HasFlag(StringSplitOptions.RemoveEmptyEntries))) + return true; + mPos = mMatchPos + mMatchLen; + if (mPos >= mStrLen) + return false; + } + else + { + mMatchLen = 1; + } + } + } + + public void Reset() mut + { + mPos = 0; + mMatchPos = -1; + } + + public void Dispose() + { + + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + public struct StringView : Span, IFormattable, IPrintable, IHashable { public this() @@ -3080,12 +3307,23 @@ namespace System public this(String string) { + if (string == null) + { + this = default; + return; + } mPtr = string.Ptr; mLength = string.Length; } public this(String string, int offset) { + if (string == null) + { + Debug.Assert(offset == 0); + this = default; + return; + } Debug.Assert((uint)offset <= (uint)string.Length); mPtr = string.Ptr + offset; mLength = string.Length - offset; @@ -3093,6 +3331,12 @@ namespace System public this(String string, int offset, int length) { + if (string == null) + { + Debug.Assert(offset == 0 && length == 0); + this = default; + return; + } Debug.Assert((uint)offset + (uint)length <= (uint)string.Length); mPtr = string.Ptr + offset; mLength = length; @@ -3120,6 +3364,12 @@ namespace System public this(char8[] arr, int offset, int length) { + if (arr == null) + { + Debug.Assert(offset == 0 && length == 0); + this = default; + return; + } Debug.Assert((uint)offset + (uint)length <= (uint)arr.Count); mPtr = arr.CArray() + offset; mLength = length; @@ -3127,13 +3377,23 @@ namespace System public this(char8* ptr) { + if (ptr == null) + { + this = default; + return; + } mPtr = ptr; mLength = String.StrLen(ptr); } public this(char8* ptr, int length) - { + if (ptr == null) + { + Debug.Assert(length == 0); + this = default; + return; + } mPtr = ptr; mLength = length; } @@ -3749,11 +4009,71 @@ namespace System return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); } - public StringSplitEnumerator Split(char8[] separators, int count = Int32.MaxValue, StringSplitOptions options = .None) + public StringSplitEnumerator Split(char8[] separators) + { + return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); + } + + public StringSplitEnumerator Split(char8[] separators, int count) + { + return StringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None); + } + + public StringSplitEnumerator Split(char8[] separators, int count, StringSplitOptions options) { return StringSplitEnumerator(Ptr, Length, separators, count, options); } + public StringSplitEnumerator Split(char8[] separators, StringSplitOptions options) + { + return StringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options); + } + + public StringStringSplitEnumerator Split(StringView c) + { + return StringStringSplitEnumerator(Ptr, Length, c, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView separator, int count) + { + return StringStringSplitEnumerator(Ptr, Length, separator, count, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView separator, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separator, Int32.MaxValue, options); + } + + public StringStringSplitEnumerator Split(StringView separator, int count, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separator, count, options); + } + + public StringStringSplitEnumerator Split(params StringView[] separators) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators, int count) + { + return StringStringSplitEnumerator(Ptr, Length, separators, count, StringSplitOptions.None); + } + + public StringStringSplitEnumerator Split(StringView[] separators, int count, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separators, count, options); + } + + public StringStringSplitEnumerator Split(StringView[] separators, StringSplitOptions options) + { + return StringStringSplitEnumerator(Ptr, Length, separators, Int32.MaxValue, options); + } + public String Intern() { using (String.[Friend]sMonitor.Enter()) @@ -3820,18 +4140,21 @@ namespace System public mixin ToScopedNativeWChar() { int encodedLen = UTF16.GetEncodedLen(this); - char16* buf; + c_wchar* buf; if (encodedLen < 128) { - buf = scope:mixin char16[encodedLen+1]* ( ? ); + buf = scope:mixin c_wchar[encodedLen+1]* ( ? ); } else { - buf = new char16[encodedLen+1]* ( ? ); + buf = new c_wchar[encodedLen+1]* ( ? ); defer:mixin delete buf; } - UTF16.Encode(this, buf, encodedLen); + if (sizeof(c_wchar) == 2) + UTF16.Encode(this, (.)buf, encodedLen); + else + UTF32.Encode(this, (.)buf, encodedLen); buf[encodedLen] = 0; buf } diff --git a/BeefLibs/corlib/src/Threading/Thread.bf b/BeefLibs/corlib/src/Threading/Thread.bf index 4fb76c2e..ed529803 100644 --- a/BeefLibs/corlib/src/Threading/Thread.bf +++ b/BeefLibs/corlib/src/Threading/Thread.bf @@ -20,8 +20,13 @@ namespace System.Threading private Object mThreadStartArg; bool mAutoDelete; - public static Thread sMainThread = new Thread() ~ delete _; - + + static Monitor sMonitor = new .() ~ delete _; + static Event sOnExit ~ _.Dispose(); + Event mOnExit ~ _.Dispose(); + + public static Thread sMainThread = new Thread() ~ delete _; + [StaticInitPriority(102)] struct RuntimeThreadInit { @@ -62,6 +67,14 @@ namespace System.Threading return ((Thread)thread).mMaxStackSize; } + static void Thread_Exiting() + { + using (sMonitor.Enter()) + { + sOnExit(); + } + } + static void Thread_StartProc(Object threadObj) { Thread thread = (Thread)threadObj; @@ -103,6 +116,7 @@ namespace System.Threading cb.[Friend]mThread_IsAutoDelete = => Thread_IsAutoDelete; cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete; cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize; + cb.[Friend]mThread_Exiting = => Thread_Exiting; } } @@ -178,6 +192,38 @@ namespace System.Threading } } + public void AddExitNotify(delegate void() dlg) + { + using (sMonitor.Enter()) + { + mOnExit.Add(dlg); + } + } + + public Result RemovedExitNotify(delegate void() dlg, bool delegateDelegate = false) + { + using (sMonitor.Enter()) + { + return mOnExit.Remove(dlg, delegateDelegate); + } + } + + public static void AddGlobalExitNotify(delegate void() dlg) + { + using (sMonitor.Enter()) + { + sOnExit.Add(dlg); + } + } + + public static Result RemoveGlobalExitNotify(delegate void() dlg, bool delegateDelegate = false) + { + using (sMonitor.Enter()) + { + return sOnExit.Remove(dlg, delegateDelegate); + } + } + extern void ManualThreadInit(); extern void StartInternal(); extern void SetStackStart(void* ptr); @@ -217,6 +263,7 @@ namespace System.Threading } } + public static extern void RequestExitNotify(); public extern void Suspend(); public extern void Resume(); @@ -316,9 +363,10 @@ namespace System.Threading } } - extern int32 GetThreadId(); + [CallingConvention(.Cdecl)] + extern int GetThreadId(); - public int32 Id + public int Id { get { @@ -326,6 +374,8 @@ namespace System.Threading } } + public static int CurrentThreadId => Platform.BfpThread_GetCurrentId(); + [CallingConvention(.Cdecl)] private static extern Thread GetCurrentThreadNative(); @@ -337,6 +387,12 @@ namespace System.Threading public ~this() { + using (sMonitor.Enter()) + { + mOnExit(); + sOnExit(); + } + // Make sure we're not deleting manually if mAutoDelete is set Debug.Assert((!mAutoDelete) || (CurrentThread == this)); // Delegate to the unmanaged portion. diff --git a/BeefLibs/corlib/src/TimeSpan.bf b/BeefLibs/corlib/src/TimeSpan.bf index fb92c0c4..34bb6b92 100644 --- a/BeefLibs/corlib/src/TimeSpan.bf +++ b/BeefLibs/corlib/src/TimeSpan.bf @@ -196,5 +196,7 @@ namespace System { TimeSpanFormat.[Friend]Format(this, format, formatProvider, outStr); } + + public static TimeSpan operator-(Self lhs, Self rhs) => .((int64)lhs - (int64)rhs); } } diff --git a/BeefLibs/corlib/src/TimeZoneInfo.bf b/BeefLibs/corlib/src/TimeZoneInfo.bf index a14a4127..cda8c21d 100644 --- a/BeefLibs/corlib/src/TimeZoneInfo.bf +++ b/BeefLibs/corlib/src/TimeZoneInfo.bf @@ -1942,7 +1942,8 @@ namespace System { } // the data returned from the PAL is completely bogus; return a dummy entry return CreateCustomTimeZone(c_localId, TimeSpan.Zero, c_localId, c_localId);*/ - Runtime.NotImplemented(); + // TODO: Not implemented. + return Utc; } #endif // !FEATURE_WIN32_REGISTRY diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index f4159dfa..0420a43d 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -852,7 +852,8 @@ namespace System.Reflection None = 0, Splat = 1, Implicit = 2, - AppendIdx = 4 + AppendIdx = 4, + Params = 8 } [CRepr, AlwaysInclude] @@ -1479,6 +1480,7 @@ namespace System.Reflection EnumDiscriminator = 0x0200, EnumCase = 0x0400, ReadOnly = 0x0800, + Appended = 0x1000, } public enum MethodFlags : uint16 diff --git a/BeefLibs/corlib/src/ValueType.bf b/BeefLibs/corlib/src/ValueType.bf index 52005fbe..86c7d0ec 100644 --- a/BeefLibs/corlib/src/ValueType.bf +++ b/BeefLibs/corlib/src/ValueType.bf @@ -2,6 +2,7 @@ namespace System { struct ValueType { + [NoShow(true)] public static extern bool Equals(T val1, T val2); } } diff --git a/BeefLink/BeefLink.vcxproj b/BeefLink/BeefLink.vcxproj index f9ae5447..6bc21290 100644 --- a/BeefLink/BeefLink.vcxproj +++ b/BeefLink/BeefLink.vcxproj @@ -94,6 +94,7 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true Console @@ -112,6 +113,7 @@ false MultiThreadedDebug false + true Console @@ -128,6 +130,7 @@ true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true Console @@ -149,6 +152,7 @@ ../;../BeefySysLib;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm\include;..\extern\llvm_win64\include;..\extern\llvm\lib\Target;..\extern\llvm_win64\lib\Target\X86;..\extern\llvm\tools\clang\include MultiThreaded false + true Console diff --git a/BeefRT/BeefDbg/BeefDbg.vcxproj b/BeefRT/BeefDbg/BeefDbg.vcxproj index f8702896..1b36a3ba 100644 --- a/BeefRT/BeefDbg/BeefDbg.vcxproj +++ b/BeefRT/BeefDbg/BeefDbg.vcxproj @@ -140,6 +140,7 @@ + @@ -356,6 +357,7 @@ + @@ -526,6 +528,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreadedDebug ProgramDatabase + true Windows @@ -589,6 +592,7 @@ false MultiThreadedDebug ProgramDatabase + true Windows @@ -664,6 +668,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreaded false + true Windows @@ -724,6 +729,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows false MultiThreaded + true Windows diff --git a/BeefRT/BeefDbg/BeefDbg.vcxproj.filters b/BeefRT/BeefDbg/BeefDbg.vcxproj.filters index 05028bff..a3a371a5 100644 --- a/BeefRT/BeefDbg/BeefDbg.vcxproj.filters +++ b/BeefRT/BeefDbg/BeefDbg.vcxproj.filters @@ -25,6 +25,9 @@ {0027c869-120a-44d3-80e6-e2ab12ce83bc} + + {59aee039-211d-47df-abb4-ca95d75d2c56} + {8e5503bc-1b01-46f1-be03-bb504d93f05d} @@ -105,6 +108,9 @@ BeefySysLib\third_party\utf8proc + + BeefySysLib\third_party\putty + BeefySysLib\util @@ -326,6 +332,9 @@ BeefySysLib\third_party\utf8proc + + BeefySysLib\third_party\putty + BeefySysLib\util diff --git a/BeefRT/BeefRT.vcxproj b/BeefRT/BeefRT.vcxproj index f4e02f8c..47794e20 100644 --- a/BeefRT/BeefRT.vcxproj +++ b/BeefRT/BeefRT.vcxproj @@ -252,6 +252,7 @@ TurnOffAllWarnings + @@ -271,6 +272,7 @@ + @@ -479,6 +481,7 @@ false false ProgramDatabase + true Windows @@ -541,6 +544,7 @@ stdcpp17 false ProgramDatabase + true Windows @@ -612,6 +616,7 @@ stdcpp17 MultiThreaded false + true Windows @@ -681,6 +686,7 @@ false false stdcpp17 + true Windows diff --git a/BeefRT/BeefRT.vcxproj.filters b/BeefRT/BeefRT.vcxproj.filters index 2c8d57e8..b911d04f 100644 --- a/BeefRT/BeefRT.vcxproj.filters +++ b/BeefRT/BeefRT.vcxproj.filters @@ -28,6 +28,9 @@ {f94ea9c5-428b-4925-a59e-b7688752d7d7} + + {e790c845-8b10-4edd-b2c0-71e35b0d80b2} + @@ -87,6 +90,9 @@ BeefySysLib\third_party\libffi + + BeefySysLib\third_party\putty + rt @@ -148,6 +154,9 @@ BeefySysLib\third_party\libffi\x86 + + BeefySysLib\third_party\putty + diff --git a/BeefRT/CMakeLists.txt b/BeefRT/CMakeLists.txt index ed65705b..83703bab 100644 --- a/BeefRT/CMakeLists.txt +++ b/BeefRT/CMakeLists.txt @@ -25,9 +25,9 @@ if(NOT CMAKE_BUILD_TYPE) endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros -add_definitions( - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC +add_definitions( + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -45,16 +45,16 @@ if (HAVE_BACKTRACE_HEADERS) add_definitions(-DBFP_HAS_BACKTRACE) endif () -if (${IOS}) +if (${IOS}) include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/build_iphoneos-arm64/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -63,13 +63,13 @@ if (${IOS}) elseif (${APPLE}) include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/x86_64-apple-darwin${CMAKE_HOST_SYSTEM_VERSION}/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -79,13 +79,13 @@ elseif (${ANDROID}) if (ANDROID_ABI STREQUAL "x86") include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/i686-pc-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -94,13 +94,13 @@ elseif (${ANDROID}) elseif (ANDROID_ABI STREQUAL "x86_64") include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/x86_64-pc-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -109,28 +109,28 @@ elseif (${ANDROID}) elseif (ANDROID_ABI STREQUAL "armeabi-v7a") include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/arm-unknown-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target ../BeefySysLib/platform/android ) - else() + else() include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/aarch64-unknown-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -140,13 +140,13 @@ elseif (${ANDROID}) else() include_directories( . - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target @@ -175,16 +175,16 @@ endif() # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -196,14 +196,14 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") endif(MSVC) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof") endif(NOT MSVC) ################ Files ################ # -- Add files to project. -- # ####################################### -file(GLOB SRC_FILES +file(GLOB SRC_FILES rt/Internal.cpp rt/Chars.cpp rt/Object.cpp @@ -219,8 +219,9 @@ file(GLOB SRC_FILES ../BeefySysLib/util/BeefPerf.cpp ../BeefySysLib/util/String.cpp ../BeefySysLib/util/UTF8.cpp - ../BeefySysLib/util/Hash.cpp - ../BeefySysLib/third_party/utf8proc/utf8proc.c + ../BeefySysLib/util/Hash.cpp + ../BeefySysLib/third_party/utf8proc/utf8proc.c + ../BeefySysLib/third_party/putty/wildcard.c ) if (${IOS}) @@ -282,10 +283,10 @@ endif() if (${APPLE}) target_link_libraries(${PROJECT_NAME} pthread ffi) -elseif (${ANDROID}) +elseif (${ANDROID}) #target_link_libraries(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../BeefySysLib/third_party/libffi/aarch64-unknown-linux-gnu/.libs/libffi.a) #target_link_libraries(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../BeefySysLib/third_party/libffi/i686-pc-linux-gnu/.libs/libffi.a) -else() +else() target_link_libraries(${PROJECT_NAME} pthread ffi ${TARGET_LIBS_OS}) endif() diff --git a/BeefRT/JEMalloc/jemalloc.vcxproj b/BeefRT/JEMalloc/jemalloc.vcxproj index 561f2802..394b0f98 100644 --- a/BeefRT/JEMalloc/jemalloc.vcxproj +++ b/BeefRT/JEMalloc/jemalloc.vcxproj @@ -275,6 +275,9 @@ include;include\msvc_compat;%(AdditionalIncludeDirectories) 4090;4146;4267;4334 $(OutputPath)$(TargetName).pdb + true + true + true Windows @@ -292,6 +295,7 @@ MultiThreadedDebug 4090;4146;4267;4334 $(OutputPath)$(TargetName).pdb + true Windows @@ -310,6 +314,7 @@ $(OutputPath)$(TargetName).pdb false MultiThreadedDebug + true Windows @@ -329,6 +334,7 @@ OldStyle false false + true Windows @@ -348,6 +354,7 @@ OldStyle false false + true Windows @@ -366,6 +373,7 @@ include;include\msvc_compat;%(AdditionalIncludeDirectories) 4090;4146;4267;4334 $(OutputPath)$(TargetName).pdb + true Windows @@ -387,6 +395,7 @@ MultiThreaded 4090;4146;4267;4334 $(OutputPath)$(TargetName).pdb + true Windows @@ -408,6 +417,7 @@ 4090;4146;4267;4334 $(OutputPath)$(TargetName).pdb MultiThreaded + true Windows @@ -429,6 +439,7 @@ MultiThreadedDLL 4090;4146;4267;4334 OldStyle + true Windows @@ -450,6 +461,7 @@ MultiThreaded 4090;4146;4267;4334 OldStyle + true Windows diff --git a/BeefRT/MinRT/MinRT.vcxproj b/BeefRT/MinRT/MinRT.vcxproj index 2281fe91..95c25711 100644 --- a/BeefRT/MinRT/MinRT.vcxproj +++ b/BeefRT/MinRT/MinRT.vcxproj @@ -173,6 +173,7 @@ MINRT_CONSOLE;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime false + true Windows @@ -188,6 +189,7 @@ MINRT_GUI;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime false + true Windows @@ -208,6 +210,7 @@ Default false /Zc:threadSafeInit- %(AdditionalOptions) + true Windows @@ -233,6 +236,7 @@ Default false /Zc:threadSafeInit- %(AdditionalOptions) + true Windows @@ -254,6 +258,7 @@ true MINRT_CONSOLE;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime + true Windows @@ -272,6 +277,7 @@ true MINRT_GUI;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime + true Windows @@ -291,6 +297,7 @@ MINRT_CONSOLE;BF_SMALL;BF_NO_BFAPP;BFSYSLIB_DYNAMIC;BFRT_DYNAMIC;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime /Zc:threadSafeInit- %(AdditionalOptions) + true Windows @@ -316,6 +323,7 @@ .;..;../BeefySysLib/third_party;../BeefySysLib;../BeefySysLib/platform/win;gperftools/src;gperftools/src/windows;../BeefySysLib/third_party/libffi/i686-pc-cygwin;../BeefySysLib/third_party/libffi/i686-pc-cygwin/include;../BeefySysLib/third_party/libffi/include;C:\Program Files (x86)\Microsoft Visual Studio\Preview\Professional\VC\Tools\MSVC\14.14.26412\crt\src\vcruntime /Zc:threadSafeInit- %(AdditionalOptions) false + true Windows diff --git a/BeefRT/TCMalloc/TCMalloc.vcxproj b/BeefRT/TCMalloc/TCMalloc.vcxproj index 9f889ff5..ba9202e5 100644 --- a/BeefRT/TCMalloc/TCMalloc.vcxproj +++ b/BeefRT/TCMalloc/TCMalloc.vcxproj @@ -502,6 +502,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreadedDebug ProgramDatabase + true Windows @@ -522,6 +523,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreadedDebug ProgramDatabase + true Windows @@ -542,6 +544,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreadedDebug ProgramDatabase + true Windows @@ -565,6 +568,7 @@ false MultiThreadedDebug ProgramDatabase + true Windows @@ -591,6 +595,7 @@ MultiThreadedDebug ProgramDatabase false + true Windows @@ -616,6 +621,7 @@ false MultiThreadedDebugDLL ProgramDatabase + true Windows @@ -640,6 +646,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreaded false + true Windows @@ -660,6 +667,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreaded false + true Windows @@ -680,6 +688,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows MultiThreadedDLL false + true Windows @@ -700,6 +709,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows false MultiThreaded + true Windows @@ -722,6 +732,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows false MultiThreaded + true Windows @@ -744,6 +755,7 @@ .;../;../..;../../BeefySysLib/third_party;../../BeefySysLib;../../BeefySysLib/platform/win;../gperftools/src;../gperftools/src/windows false MultiThreadedDLL + true Windows diff --git a/BeefRT/rt/BfObjects.h b/BeefRT/rt/BfObjects.h index 237d69c9..d8573e58 100644 --- a/BeefRT/rt/BfObjects.h +++ b/BeefRT/rt/BfObjects.h @@ -3,7 +3,7 @@ #include "BeefySysLib/Common.h" #include "BeefySysLib/util/String.h" -#define BFRT_VERSION 9 +#define BFRT_VERSION 10 #ifdef BFRT_DYNAMIC #define BFRT_EXPORT __declspec(dllexport) @@ -99,6 +99,7 @@ namespace bf bool(*Thread_IsAutoDelete)(bf::System::Threading::Thread* thread); void(*Thread_AutoDelete)(bf::System::Threading::Thread* thread); int32(*Thread_GetMaxStackSize)(bf::System::Threading::Thread* thread); + void(*Thread_Exiting)(); void(*GC_MarkAllStaticMembers)(); bool(*GC_CallRootCallbacks)(); void(*GC_Shutdown)(); @@ -107,7 +108,7 @@ namespace bf void(*DebugMessageData_SetupProfilerCmd)(const char* str); void(*DebugMessageData_Fatal)(); void(*DebugMessageData_Clear)(); - int(*CheckErrorHandler)(const char* kind, const char* arg1, const char* arg2, intptr arg3); + int(*CheckErrorHandler)(const char* kind, const char* arg1, const char* arg2, intptr arg3); }; public: diff --git a/BeefRT/rt/Internal.cpp b/BeefRT/rt/Internal.cpp index 4bcc49a4..ba90fc5c 100644 --- a/BeefRT/rt/Internal.cpp +++ b/BeefRT/rt/Internal.cpp @@ -55,6 +55,12 @@ static Beefy::StringT<0> gCmdLineString; bf::System::Runtime::BfRtCallbacks gBfRtCallbacks; BfRtFlags gBfRtFlags = (BfRtFlags)0; +#ifdef BF_PLATFORM_WINDOWS +DWORD gBfTLSKey = 0; +#else +pthread_key_t gBfTLSKey = 0; +#endif + static int gTestMethodIdx = -1; static uint32 gTestStartTick = 0; static bool gTestBreakOnFailure = false; @@ -86,6 +92,7 @@ namespace bf BFRT_EXPORT static void ObjectDynCheck(Object* object, int typeId, bool allowNull); BFRT_EXPORT static void ObjectDynCheckFailed(Object* object, int typeId); BFRT_EXPORT static void ThrowIndexOutOfRange(intptr stackOffset); + BFRT_EXPORT static void ThrowObjectNotInitialized(intptr stackOffset); BFRT_EXPORT static void FatalError(String* error, intptr stackOffset = 0); BFRT_EXPORT static void MemCpy(void* dest, void* src, intptr length); BFRT_EXPORT static void MemMove(void* dest, void* src, intptr length); @@ -286,6 +293,11 @@ static void GetCrashInfo() } } +static void NTAPI TlsFreeFunc(void* ptr) +{ + gBfRtCallbacks.Thread_Exiting(); +} + void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks) { BfpSystemInitFlags sysInitFlags = BfpSystemInitFlag_InstallCrashCatcher; @@ -342,6 +354,12 @@ void bf::System::Runtime::Init(int version, int flags, BfRtCallbacks* callbacks) useCmdLineStr++; } gCmdLineString = useCmdLineStr; + +#ifdef BF_PLATFORM_WINDOWS + gBfTLSKey = FlsAlloc(TlsFreeFunc); +#else + pthread_key_create(&gBfTLSKey, TlsFreeFunc); +#endif } void bf::System::Runtime::SetErrorString(char* errorStr) @@ -423,6 +441,30 @@ void Internal::ThrowIndexOutOfRange(intptr stackOffset) Internal_FatalError("Index out of range"); } +void Internal::ThrowObjectNotInitialized(intptr stackOffset) +{ + if (gClientPipe != NULL) + { + if (gTestBreakOnFailure) + { + SETUP_ERROR("Object not initialized", (int)(2 + stackOffset)); + BF_DEBUG_BREAK(); + } + + Beefy::String str = ":TestFail\tObject not initialized\n"; + TestString(str); + exit(1); + } + + if ((stackOffset != -1) && (::IsDebuggerPresent())) + { + SETUP_ERROR("Object not initialized", (int)(2 + stackOffset)); + BF_DEBUG_BREAK(); + } + + Internal_FatalError("Object not initialized"); +} + void Internal::FatalError(bf::System::String* error, intptr stackOffset) { if (gClientPipe != NULL) diff --git a/BeefRT/rt/Thread.cpp b/BeefRT/rt/Thread.cpp index 0e79e8a3..37114d63 100644 --- a/BeefRT/rt/Thread.cpp +++ b/BeefRT/rt/Thread.cpp @@ -19,6 +19,12 @@ BF_TLS_DECLSPEC Thread* Thread::sCurrentThread; static volatile int gLiveThreadCount; static Beefy::SyncEvent gThreadsDoneEvent; +#ifdef BF_PLATFORM_WINDOWS +extern DWORD gBfTLSKey; +#else +extern pthread_key_t gBfTLSKey; +#endif + bf::System::Threading::Thread* BfGetCurrentThread() { #ifdef BF_THREAD_TLS @@ -133,7 +139,8 @@ static void BF_CALLTYPE CStartProc(void* threadParam) bool wantsDelete = false; // { - internalThread->ThreadStopped(); + internalThread->ThreadStopped(); + Beefy::AutoCrit autoCrit(internalThread->mCritSect); if (isAutoDelete) gBfRtCallbacks.Thread_AutoDelete(thread); @@ -207,15 +214,28 @@ void Thread::StartInternal() #endif } +void Thread::RequestExitNotify() +{ + // Do we already have implicit exiting notification? + if (BfGetCurrentThread() != NULL) + return; + +#ifdef BF_PLATFORM_WINDOWS + FlsSetValue(gBfTLSKey, (void*)&gBfRtCallbacks); +#else + pthread_setspecific(gBfTLSKey, (void*)&gBfRtCallbacks); +#endif +} + void Thread::ThreadStarted() { auto internalThread = GetInternalThread(); internalThread->mCritSect.Unlock(); } -int Thread::GetThreadId() +intptr Thread::GetThreadId() { - return (int)GetInternalThread()->mThreadId; + return GetInternalThread()->mThreadId; } void Thread::SetStackStart(void* ptr) diff --git a/BeefRT/rt/Thread.h b/BeefRT/rt/Thread.h index 17bfec7e..22ea4d93 100644 --- a/BeefRT/rt/Thread.h +++ b/BeefRT/rt/Thread.h @@ -39,7 +39,7 @@ namespace bf private: BfInternalThread* SetupInternalThread(); - BFRT_EXPORT void ManualThreadInit(); + BFRT_EXPORT void ManualThreadInit(); BFRT_EXPORT int GetPriorityNative(); BFRT_EXPORT void SetPriorityNative(int priority); BFRT_EXPORT void SetJoinOnDelete(bool joinOnDelete); @@ -59,7 +59,7 @@ namespace bf BFRT_EXPORT void SetBackgroundNative(bool isBackground); BFRT_EXPORT int GetThreadStateNative(); BFRT_EXPORT void InformThreadNameChange(String* name); - BFRT_EXPORT int GetThreadId(); + BFRT_EXPORT intptr GetThreadId(); BFRT_EXPORT void Dbg_CreateInternal(); @@ -68,6 +68,7 @@ namespace bf BFRT_EXPORT void Resume(); BFRT_EXPORT void Abort(); + BFRT_EXPORT static void RequestExitNotify(); BFRT_EXPORT static void MemoryBarrier(); static Thread* Alloc() diff --git a/BeefRT/rt/ThreadLocalStorage.cpp b/BeefRT/rt/ThreadLocalStorage.cpp index 439f81b8..6861f501 100644 --- a/BeefRT/rt/ThreadLocalStorage.cpp +++ b/BeefRT/rt/ThreadLocalStorage.cpp @@ -35,7 +35,7 @@ uint32 BfTLSManager::Alloc() } } - mAllocatedKeys[idx] = BfpTLS_Create(); + mAllocatedKeys[idx] = BfpTLS_Create(NULL); mAssociatedTLSDatums[idx] = NULL; return idx; } diff --git a/BeefRT/rt/ThreadLocalStorage.h b/BeefRT/rt/ThreadLocalStorage.h index 93c171d1..ff1ea718 100644 --- a/BeefRT/rt/ThreadLocalStorage.h +++ b/BeefRT/rt/ThreadLocalStorage.h @@ -43,7 +43,7 @@ public: BfTLSManager() { - sInternalThreadKey = BfpTLS_Create(); + sInternalThreadKey = BfpTLS_Create(NULL); mAssociatedTLSDatums = NULL; mAllocSize = 0; mAllocIdx = 1; diff --git a/BeefTools/BeefMem/CMakeLists.txt b/BeefTools/BeefMem/CMakeLists.txt index 2d6d5b3c..1e9ffff1 100644 --- a/BeefTools/BeefMem/CMakeLists.txt +++ b/BeefTools/BeefMem/CMakeLists.txt @@ -23,9 +23,9 @@ endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros add_definitions( - -D_DEBUG - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC + -D_DEBUG + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -40,9 +40,9 @@ include_directories( ../BeefySysLib/third_party ../BeefySysLib/third_party/freetype/include ../BeefySysLib/third_party/libffi/x86_64-unknown-linux-gnu/include - ../ + ../ ../extern - ../extern/llvm/include + ../extern/llvm/include ../extern/llvm_linux/include ../extern/llvm/lib/Target ../extern/llvm_linux/lib/Target/X86 @@ -66,16 +66,16 @@ endif() # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -87,7 +87,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") endif(MSVC) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -Wno-multichar -Wno-invalid-offsetof") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() @@ -97,8 +97,8 @@ endif(NOT MSVC) # -- Add files to project. -- # ####################################### -file(GLOB SRC_FILES - +file(GLOB SRC_FILES + ) # Add library to build. diff --git a/BeefTools/BeefPerf/src/BPApp.bf b/BeefTools/BeefPerf/src/BPApp.bf index fffe1822..2b255562 100644 --- a/BeefTools/BeefPerf/src/BPApp.bf +++ b/BeefTools/BeefPerf/src/BPApp.bf @@ -106,11 +106,6 @@ namespace BeefPerf delete client; } - Widget.RemoveAndDelete(mWorkspacePanel); - Widget.RemoveAndDelete(mBoard); - Widget.RemoveAndDelete(mProfilePanel); - Widget.RemoveAndDelete(mFindPanel); - if (!mLogLines.IsEmpty) { var fs = scope FileStream(); @@ -122,7 +117,7 @@ namespace BeefPerf } } } - + static uint32 TimeToUnixTime(DateTime ft) { // takes the last modified date @@ -267,6 +262,15 @@ namespace BeefPerf { base.Stop(); mListenSocket.Close(); + + Widget.RemoveAndDelete(mWorkspacePanel); + mWorkspacePanel = null; + Widget.RemoveAndDelete(mBoard); + mBoard = null; + Widget.RemoveAndDelete(mProfilePanel); + mProfilePanel = null; + Widget.RemoveAndDelete(mFindPanel); + mFindPanel = null; } void ShowWorkspacePanel() @@ -517,7 +521,6 @@ namespace BeefPerf public override void Shutdown() { base.Shutdown(); - mShutdownEvent.Set(true); } diff --git a/BeefTools/TestDLL/TestDLL.cpp b/BeefTools/TestDLL/TestDLL.cpp index d889c73b..377d4eb2 100644 --- a/BeefTools/TestDLL/TestDLL.cpp +++ b/BeefTools/TestDLL/TestDLL.cpp @@ -138,9 +138,7 @@ void TestMem() char* mem = (char*)::VirtualAlloc(0, 4096 * 2, MEM_RESERVE, PAGE_READWRITE); ::VirtualAlloc(mem, 4096, MEM_COMMIT, PAGE_READWRITE); - char* str = "Hey"; - char* cPtr = mem + 4096 - 3; - memcpy(cPtr, str, 3); + } void Test6() @@ -163,10 +161,41 @@ void Test3(int a) Test4(100, 200, 300); } + +#pragma pack(1) +class TestStruct +{ +public: + int mA; + int mB; + int mC; + int mD; +}; + +enum EnumVal +{ + EnumVal_A, + EnumVal_B, + EnumVal_C +}; + +struct Color +{ + float r, g, b, a; +}; + // THIS IS VERSION 6. extern "C" -__declspec(dllexport) void Test2(int aa, int bb, int cc, int dd) +__declspec(dllexport) void Test2(int aa, int bb, int cc, int dd, Color func(int a, int b)) { + Color clr = func(100, 200); + + EnumVal ev = EnumVal_A; + + TestStruct ts; + ts.mA = 123; + ts.mB = 234; + int a = 1234; for (int i = 0; i < 100; i++) @@ -174,9 +203,7 @@ __declspec(dllexport) void Test2(int aa, int bb, int cc, int dd) a++; } - Test3(10); - - char* strP = "Hey yo"; + Test3(10); TestMem(); diff --git a/BeefTools/TestDLL/TestDLL.vcxproj b/BeefTools/TestDLL/TestDLL.vcxproj index c4b1c718..4d5c6e14 100644 --- a/BeefTools/TestDLL/TestDLL.vcxproj +++ b/BeefTools/TestDLL/TestDLL.vcxproj @@ -22,32 +22,32 @@ {14700A80-0FC4-4A3D-99EF-8B78D4B070F1} Win32Proj TestDLL - 10.0.17763.0 + 10.0.16299.0 DynamicLibrary true - v141 + v142 Unicode Application false - v141 + v142 true Unicode DynamicLibrary true - v141 + v142 Unicode DynamicLibrary false - v141 + v142 true Unicode @@ -104,7 +104,7 @@ Level3 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - \Beef\BeefySysLib;\Beef\BeefySysLib\third_party + \Beef\BeefySysLib;\Beef\BeefySysLib\third_party;C:\temp\Chipmunk-7.0.3\include stdcpplatest @@ -112,7 +112,8 @@ DebugFull - copy C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll c:\beef\ide\mintest\build\release_win64\mintest + + @@ -152,6 +153,7 @@ + diff --git a/BeefySysLib/BFApp.cpp b/BeefySysLib/BFApp.cpp index d95c0907..6b50391f 100644 --- a/BeefySysLib/BFApp.cpp +++ b/BeefySysLib/BFApp.cpp @@ -222,7 +222,7 @@ void BFApp::Process() mClientUpdateCntF = mUpdateCntF - 1; } - while ((int)mClientUpdateCntF < (int)mUpdateCntF) + while ((mRunning) && ((int)mClientUpdateCntF < (int)mUpdateCntF)) { Update(didUpdateCnt == 0); didUpdateCnt++; @@ -232,7 +232,7 @@ void BFApp::Process() } // Only attempt UpdateF updates if our rates aren't nearly the same - if ((mRefreshRate != 0) && (fabs(physRefreshRate - mRefreshRate) / (float)mRefreshRate > 0.1f)) + if ((mRunning) && (mRefreshRate != 0) && (fabs(physRefreshRate - mRefreshRate) / (float)mRefreshRate > 0.1f)) { float updateFAmt = (float)(mUpdateCntF - mClientUpdateCntF); if ((updateFAmt > 0.05f) && (updateFAmt < 1.0f) && (didUpdateCnt < maxUpdates)) diff --git a/BeefySysLib/BeefySysLib.vcxproj b/BeefySysLib/BeefySysLib.vcxproj index d9ee8d82..c6953223 100644 --- a/BeefySysLib/BeefySysLib.vcxproj +++ b/BeefySysLib/BeefySysLib.vcxproj @@ -188,6 +188,7 @@ ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include MultiThreadedDebugDLL false + true Windows @@ -224,6 +225,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreadedDebug false false + true Windows @@ -311,6 +313,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"BFP_NOEXPORT;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) MultiThreadedDLL ./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include;;../extern/fbxsdk/include + true Windows @@ -348,6 +351,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"MultiThreaded ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include false + true Windows @@ -1926,6 +1930,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"TurnOffAllWarnings TurnOffAllWarnings + @@ -2152,6 +2157,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\" + diff --git a/BeefySysLib/BeefySysLib.vcxproj.filters b/BeefySysLib/BeefySysLib.vcxproj.filters index 3b2dc190..f766dc93 100644 --- a/BeefySysLib/BeefySysLib.vcxproj.filters +++ b/BeefySysLib/BeefySysLib.vcxproj.filters @@ -78,6 +78,9 @@ {a159b9ee-1a71-44f5-a412-1e01e20b70c7} + + {0007a912-9292-4e32-8884-0f0cd276e42d} + @@ -731,6 +734,9 @@ src\util + + src\third_party\putty + @@ -1123,6 +1129,9 @@ src\util + + src\third_party\putty + diff --git a/BeefySysLib/BeefySysLib_static.vcxproj b/BeefySysLib/BeefySysLib_static.vcxproj index e81e9e3a..582167f8 100644 --- a/BeefySysLib/BeefySysLib_static.vcxproj +++ b/BeefySysLib/BeefySysLib_static.vcxproj @@ -102,6 +102,7 @@ BFP_INTERNAL;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;BF_NO_FBX;%(PreprocessorDefinitions) ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include MultiThreadedDebug + true Windows @@ -125,6 +126,7 @@ MultiThreadedDebug false false + true Windows @@ -143,6 +145,7 @@ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) MultiThreaded ./; ./platform/win/; ./platform/sdl/; third_party/agg-2.4/include; third_party/agg-2.4/include/platform/win32; third_party/; third_party/libffi/i686-pc-cygwin; third_party/libffi/i686-pc-cygwin/include; third_party/libffi/include; third_party/SDL2-2.0.1/include;;../extern/fbxsdk/include + true Windows @@ -167,6 +170,7 @@ MultiThreaded ./;./platform/win/;./platform/sdl/;third_party/agg-2.4/include;third_party/agg-2.4/include/platform/win32;third_party/;third_party/libffi/i686-pc-cygwin;third_party/libffi/i686-pc-cygwin/include;third_party/libffi/include;third_party/SDL2-2.0.1/include;../extern/fbxsdk/include;third_party/freetype/include false + true Windows @@ -859,6 +863,7 @@ Level1 Level1 + @@ -1025,6 +1030,7 @@ + diff --git a/BeefySysLib/BeefySysLib_static.vcxproj.filters b/BeefySysLib/BeefySysLib_static.vcxproj.filters index 34f64889..62458bbe 100644 --- a/BeefySysLib/BeefySysLib_static.vcxproj.filters +++ b/BeefySysLib/BeefySysLib_static.vcxproj.filters @@ -69,6 +69,9 @@ {d32cb9b0-e79b-49fe-82e2-33302be0baf6} + + {bec18ceb-a7ca-4150-99ee-60a16944b93c} + @@ -584,6 +587,9 @@ src\third_party\miniz + + src\third_party\putty + @@ -898,6 +904,9 @@ src\third_party\miniz + + src\third_party\putty + diff --git a/BeefySysLib/CMakeLists.txt b/BeefySysLib/CMakeLists.txt index 9a1f1e25..c335cb28 100644 --- a/BeefySysLib/CMakeLists.txt +++ b/BeefySysLib/CMakeLists.txt @@ -16,7 +16,7 @@ set(OUTPUT_RELEASE Release/bin) project(${PROJECT_NAME} CXX C) -# Define Release by default. +# Define Debug by default. if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Debug") message(STATUS "Build type not specified: Use Debug by default.") @@ -24,8 +24,8 @@ endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros add_definitions( - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -82,16 +82,16 @@ endif() # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -103,7 +103,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") endif(MSVC) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar") endif(NOT MSVC) ################ Files ################ @@ -119,9 +119,9 @@ file(GLOB SRC_FILES DataStream.cpp FileStream.cpp HeadlessApp.cpp - MemStream.cpp - ResLib.cpp - Startup.cpp + MemStream.cpp + ResLib.cpp + Startup.cpp fbx/FBXReader.cpp gfx/DrawLayer.cpp @@ -132,7 +132,7 @@ file(GLOB SRC_FILES gfx/RenderDevice.cpp gfx/RenderTarget.cpp gfx/Shader.cpp - gfx/Texture.cpp + gfx/Texture.cpp img/BFIData.cpp img/ImageAdjustments.cpp img/ImageData.cpp @@ -142,8 +142,8 @@ file(GLOB SRC_FILES img/PNGData.cpp img/PSDReader.cpp img/PVRData.cpp - img/TGAData.cpp - + img/TGAData.cpp + third_party/freetype/src/autofit/autofit.c third_party/freetype/src/base/ftbase.c third_party/freetype/src/base/ftbbox.c @@ -274,6 +274,7 @@ file(GLOB SRC_FILES third_party/zlib/uncompr.c third_party/zlib/zutil.c third_party/miniz/miniz.c + third_party/putty/wildcard.c util/AllocDebug.cpp util/BeefPerf.cpp util/BSpline.cpp @@ -323,6 +324,6 @@ add_library(${PROJECT_NAME} SHARED # Link with other dependencies. if(MSVC) - target_link_libraries(${PROJECT_NAME} imm32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib + target_link_libraries(${PROJECT_NAME} imm32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ) endif(MSVC) diff --git a/BeefySysLib/Common.h b/BeefySysLib/Common.h index 72c0de8a..e2a61beb 100644 --- a/BeefySysLib/Common.h +++ b/BeefySysLib/Common.h @@ -15,10 +15,10 @@ inline size_t HashBytes(const uint8* ptr, size_t count) noexcept { -#ifdef BF64 +#ifdef BF64 const size_t _FNV_offset_basis = 14695981039346656037ULL; const size_t _FNV_prime = 1099511628211ULL; -#else +#else const size_t _FNV_offset_basis = 2166136261U; const size_t _FNV_prime = 16777619U; #endif @@ -29,7 +29,7 @@ inline size_t HashBytes(const uint8* ptr, size_t count) noexcept val ^= (size_t)ptr[_Next]; val *= _FNV_prime; } - return (val); + return (val); } template @@ -245,7 +245,7 @@ int16 EndianSwap(int16 val); template struct RemoveTypePointer -{ +{ }; template diff --git a/BeefySysLib/platform/PlatformInterface.h b/BeefySysLib/platform/PlatformInterface.h index 79b08843..0a260f87 100644 --- a/BeefySysLib/platform/PlatformInterface.h +++ b/BeefySysLib/platform/PlatformInterface.h @@ -223,6 +223,7 @@ enum BfpThreadCreateFlags }; typedef void (BFP_CALLTYPE *BfpThreadStartProc)(void* threadParam); +typedef void (BFP_CALLTYPE* BfpTLSProc)(void* threadParam); enum BfpThreadPriority { @@ -273,8 +274,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Enter(BfpCritSect* critSect); BFP_EXPORT bool BFP_CALLTYPE BfpCritSect_TryEnter(BfpCritSect* critSect, int waitMS); BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect); + struct BfpTLS; -BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(); +BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc); BFP_EXPORT void BFP_CALLTYPE BfpTLS_Release(BfpTLS* tls); BFP_EXPORT void BFP_CALLTYPE BfpTLS_SetValue(BfpTLS* tls, void* value); BFP_EXPORT void* BFP_CALLTYPE BfpTLS_GetValue(BfpTLS* tls); diff --git a/BeefySysLib/platform/posix/PosixCommon.cpp b/BeefySysLib/platform/posix/PosixCommon.cpp index ebbc35b8..03f70b4b 100644 --- a/BeefySysLib/platform/posix/PosixCommon.cpp +++ b/BeefySysLib/platform/posix/PosixCommon.cpp @@ -22,6 +22,7 @@ #include "../../util/CritSect.h" #include "../../util/Dictionary.h" #include "../../util/Hash.h" +#include "../../third_party/putty/wildcard.h" #ifdef BFP_HAS_EXECINFO #include #endif @@ -1528,10 +1529,10 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect) pthread_mutex_unlock(&critSect->mPMutex); } -BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create() +BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc) { pthread_key_t key = 0; - pthread_key_create(&key, NULL); + pthread_key_create(&key, exitProc); return (BfpTLS*)(intptr)key; } @@ -2378,9 +2379,10 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData) { if ((findData->mFlags & BfpFindFileFlag_Files) == 0) return false; - } + } - //TODO: Check actual wildcards. + if (!wc_match(findData->mWildcard.c_str(), findData->mDirEnt->d_name)) + return false; return true; } diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 4893040e..da744546 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -25,6 +25,7 @@ #include "../util/CritSect.h" #include "../util/Dictionary.h" #include "../util/HashSet.h" +#include "../../third_party/putty/wildcard.h" #include "util/AllocDebug.h" @@ -2530,24 +2531,24 @@ BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect) #define BFPTLS_TO_DWORD(val) ((DWORD)(intptr)(val)) struct BfpTLS; -BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create() +BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create(BfpTLSProc exitProc) { - return DWORD_TO_BFPTLS(::TlsAlloc()); + return DWORD_TO_BFPTLS(::FlsAlloc(exitProc)); } BFP_EXPORT void BFP_CALLTYPE BfpTLS_Release(BfpTLS* tls) { - ::TlsFree(BFPTLS_TO_DWORD(tls)); + ::FlsFree(BFPTLS_TO_DWORD(tls)); } BFP_EXPORT void BFP_CALLTYPE BfpTLS_SetValue(BfpTLS* tls, void* value) { - ::TlsSetValue(BFPTLS_TO_DWORD(tls), value); + ::FlsSetValue(BFPTLS_TO_DWORD(tls), value); } BFP_EXPORT void* BFP_CALLTYPE BfpTLS_GetValue(BfpTLS* tls) { - return ::TlsGetValue(BFPTLS_TO_DWORD(tls)); + return ::FlsGetValue(BFPTLS_TO_DWORD(tls)); } BFP_EXPORT BfpEvent* BFP_CALLTYPE BfpEvent_Create(BfpEventFlags flags) @@ -3485,6 +3486,7 @@ struct BfpFindFileData { BfpFindFileFlags mFlags; WIN32_FIND_DATA mFindData; + Beefy::String mWildcard; HANDLE mHandle; }; @@ -3496,29 +3498,45 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData) bool isDir = (findData->mFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; if (isDir) { - if ((findData->mFlags & BfpFindFileFlag_Directories) != 0) - { - if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0)) - { - return false; - } - return true; - } + if ((findData->mFlags & BfpFindFileFlag_Directories) == 0) + return false; + + if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0)) + return false; } else { - if ((findData->mFlags & BfpFindFileFlag_Files) != 0) - return true; + if ((findData->mFlags & BfpFindFileFlag_Files) == 0) + return false; } - return false; + + Beefy::String fileName = UTF8Encode(findData->mFindData.cFileName); + Beefy::MakeUpper(fileName); + if (!wc_match(findData->mWildcard.c_str(), fileName.c_str())) + return false; + + return true; } BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const char* path, BfpFindFileFlags flags, BfpFileResult* outResult) { - UTF16String wPath = UTF8Decode(path); + Beefy::String findStr = path; + Beefy::String wildcard; + + int lastSlashPos = std::max((int)findStr.LastIndexOf('/'), (int)findStr.LastIndexOf('\\')); + if (lastSlashPos != -1) + { + wildcard = findStr.Substring(lastSlashPos + 1); + findStr = findStr.Substring(0, lastSlashPos + 1); + findStr.Append("*"); + } + if (wildcard == "*.*") + wildcard = "*"; BfpFindFileData* findData = new BfpFindFileData(); findData->mFlags = flags; + findData->mWildcard = wildcard; + Beefy::MakeUpper(findData->mWildcard); FINDEX_SEARCH_OPS searchOps; if ((flags & BfpFindFileFlag_Files) == 0) @@ -3526,6 +3544,7 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha else searchOps = FindExSearchNameMatch; + UTF16String wPath = UTF8Decode(findStr); findData->mHandle = ::FindFirstFileExW(wPath.c_str(), FindExInfoBasic, &findData->mFindData, searchOps, NULL, 0); if (findData->mHandle == INVALID_HANDLE_VALUE) { diff --git a/BeefySysLib/platform/win/WinBFApp.cpp b/BeefySysLib/platform/win/WinBFApp.cpp index c219b78e..b1d7cc83 100644 --- a/BeefySysLib/platform/win/WinBFApp.cpp +++ b/BeefySysLib/platform/win/WinBFApp.cpp @@ -39,7 +39,7 @@ static BOOL CALLBACK BFEnumResNameProc( LPWSTR lpszName, LONG_PTR lParam ) -{ +{ gMainIcon = ::LoadIconW(hModule, lpszName); return FALSE; } @@ -56,23 +56,23 @@ struct AdjustedMonRect static BOOL ClipToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg) { AdjustedMonRect* outRect = (AdjustedMonRect*)userArg; - + MONITORINFO monitorInfo = { sizeof(MONITORINFO) }; if (::GetMonitorInfo(mon, &monitorInfo) == 0) return TRUE; outRect->mMonCount++; - + if (outRect->mX < monitorInfo.rcWork.left) outRect->mX = monitorInfo.rcWork.left; else if (outRect->mX + outRect->mWidth >= monitorInfo.rcWork.right) outRect->mX = BF_MAX((int)monitorInfo.rcWork.left, monitorInfo.rcWork.right - outRect->mWidth); - + if (outRect->mY < monitorInfo.rcWork.top) outRect->mY = monitorInfo.rcWork.top; else if (outRect->mY + outRect->mHeight >= monitorInfo.rcWork.bottom) outRect->mY = BF_MAX((int)monitorInfo.rcWork.top, monitorInfo.rcWork.bottom - outRect->mHeight); - + return TRUE; } @@ -97,9 +97,9 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y //OutputDebugStrF("Wnd %p Create\n", this); HINSTANCE hInstance = GetModuleHandle(NULL); - + mMinWidth = 128; - mMinHeight = 128; + mMinHeight = 128; WNDCLASSW wc; wc.style = 0; @@ -107,7 +107,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y wc.cbWndExtra = 0; wc.hbrBackground = NULL; //wc.hbrBackground = ::CreateSolidBrush(::GetSysColor(COLOR_BTNFACE)); - wc.hCursor = NULL; + wc.hCursor = NULL; //wc.hIcon = (HICON) ::LoadImageA(hInstance, "MainIcon", IMAGE_ICON, 0, 0, 0); //wc.hIcon = (HICON) ::LoadImageA(hInstance, MAKEINTRESOURCEA(32512), IMAGE_ICON, 0, 0, 0); if (gMainIcon != NULL) @@ -117,7 +117,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y else { wc.hIcon = (HICON) ::LoadIconA(hInstance, "MainIcon"); - if (wc.hIcon == NULL) + if (wc.hIcon == NULL) { EnumResourceNamesW(hInstance, (LPCWSTR)RT_GROUP_ICON, BFEnumResNameProc, 0); wc.hIcon = gMainIcon; @@ -127,15 +127,15 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y wc.hInstance = hInstance; wc.lpfnWndProc = WindowProcStub; wc.lpszClassName = L"BFWindow"; - wc.lpszMenuName = NULL; - RegisterClassW(&wc); + wc.lpszMenuName = NULL; + RegisterClassW(&wc); int requestedX = x; int requestedY = y; int aWindowFlags = 0; bool hasDestAlpha = (windowFlags & BFWINDOW_DEST_ALPHA) != 0; - + if (windowFlags & BFWINDOW_MENU) { WinBFMenu* aMenu = new WinBFMenu(); @@ -143,8 +143,8 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y mHMenuMap[aMenu->mMenu] = aMenu; mMenu = aMenu; } - - int windowFlagsEx = /*WS_EX_COMPOSITED |*/ WS_EX_LAYERED; + + int windowFlagsEx = /*WS_EX_COMPOSITED |*/ WS_EX_LAYERED; if (windowFlags & BFWINDOW_TOOLWINDOW) windowFlagsEx |= WS_EX_TOOLWINDOW; if (windowFlags & BFWINDOW_BORDER) @@ -152,11 +152,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y if (windowFlags & BFWINDOW_THICKFRAME) aWindowFlags |= WS_THICKFRAME; if ((windowFlags & BFWINDOW_RESIZABLE) && (!hasDestAlpha)) - aWindowFlags |= WS_SIZEBOX; + aWindowFlags |= WS_SIZEBOX; if (windowFlags & BFWINDOW_SYSMENU) aWindowFlags |= WS_SYSMENU; if (windowFlags & BFWINDOW_CAPTION) - aWindowFlags |= WS_CAPTION; + aWindowFlags |= WS_CAPTION; else aWindowFlags |= WS_POPUP; if (windowFlags & BFWINDOW_MINIMIZE) @@ -177,10 +177,10 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y width = rect.right - rect.left; height = rect.bottom - rect.top; } - + if (windowFlags & BFWINDOW_POPUP_POSITION) { - AdjustedMonRect adjustRect = { 0, x, y, width, height }; + AdjustedMonRect adjustRect = { 0, x, y, width, height }; RECT wantRect = { x, y, x + width, y + height }; EnumDisplayMonitors(NULL, &wantRect, ClipToMonitor, (LPARAM)&adjustRect); @@ -191,7 +191,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y width = adjustRect.mWidth; height = adjustRect.mHeight; } - + mFlags = windowFlags; mMouseVisible = true; @@ -204,8 +204,8 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y { WinBFMenu* placeholderMenu = (WinBFMenu*) AddMenuItem(mMenu, 0, ": Placeholder Menu Item :", NULL, NULL, false, -1, false); placeholderMenu->mIsPlaceholder = true; - } - + } + mHWnd = CreateWindowExW(windowFlagsEx, L"BFWindow", UTF8Decode(title).c_str(), aWindowFlags, x, y, @@ -215,7 +215,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y (mMenu != NULL) ? ((WinBFMenu*) mMenu)->mMenu : NULL, hInstance, 0); - + if ((windowFlags & BFWINDOW_ALPHA_MASK) == 0) SetLayeredWindowAttributes(mHWnd, 0, 255, 0); @@ -225,7 +225,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y int showFlags = SWP_SHOWWINDOW; // if (windowFlags & BFWINDOW_SHOWMINIMIZED) // showFlags = SWP_ - mHasFocus = true; + mHasFocus = true; mSoftHasFocus = true; if (windowFlags & BFWINDOW_FAKEFOCUS) { @@ -253,7 +253,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y else if (windowFlags & BFWINDOW_SHOWMAXIMIZED) wndPlacement.showCmd = SW_SHOWMAXIMIZED; else - wndPlacement.showCmd = SW_SHOWNORMAL; + wndPlacement.showCmd = SW_SHOWNORMAL; wndPlacement.rcNormalPosition.left = x; wndPlacement.rcNormalPosition.top = y; @@ -266,11 +266,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y SetWindowPos(mHWnd, relativeWindow, x, y, width, height, showFlags); } - + SetTimer(mHWnd, 0, 10, NULL); - + mIsMouseInside = false; - mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, this, (windowFlags & BFWINDOW_FULLSCREEN) == 0); + mRenderWindow = new DXRenderWindow((DXRenderDevice*) gBFApp->mRenderDevice, this, (windowFlags & BFWINDOW_FULLSCREEN) == 0); gBFApp->mRenderDevice->AddRenderWindow(mRenderWindow); SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)this); @@ -281,7 +281,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y mAlphaMaskPixels = NULL; mAlphaMaskWidth = 0; mAlphaMaskHeight = 0; - mNeedsStateReset = false; + mNeedsStateReset = false; mAwaitKeyReleases = false; mAwaitKeyReleasesEventTick = 0; mAwaitKeyReleasesCheckIdx = 0; @@ -293,11 +293,11 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y DwmExtendFrameIntoClientArea(mHWnd, &dWMMargins); } - if (windowFlags & BFWINDOW_MODAL) - { - EnableWindow(parentHWnd, FALSE); + if (windowFlags & BFWINDOW_MODAL) + { + EnableWindow(parentHWnd, FALSE); } - + if (parent != NULL) { auto winParent = (WinBFWindow*)parent; @@ -310,7 +310,7 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y } WinBFWindow::~WinBFWindow() -{ +{ //OutputDebugStrF("Wnd %p Destroyed\n", this); if (mHWnd != NULL) @@ -354,7 +354,7 @@ void WinBFWindow::SetTitle(const char* title) } void WinBFWindow::LostFocus(BFWindow* newFocus) -{ +{ ///OutputDebugStrF("Lost focus\n"); mFocusLostTick = ::GetTickCount(); WinBFWindow* bfNewFocus = (WinBFWindow*)newFocus; @@ -362,8 +362,8 @@ void WinBFWindow::LostFocus(BFWindow* newFocus) for (int i = 0; i < KEYCODE_MAX; i++) { // Only transfer mode keys - if (mIsKeyDown[i]) - { + if (mIsKeyDown[i]) + { mIsKeyDown[i] = false; mKeyUpFunc(this, i); @@ -374,7 +374,7 @@ void WinBFWindow::LostFocus(BFWindow* newFocus) newFocus->mKeyDownFunc(newFocus, i, 0); } } - } + } } void WinBFWindow::GotFocus() @@ -388,7 +388,7 @@ void WinBFWindow::GotFocus() mAwaitKeyReleases = true; mAwaitKeyReleasesCheckIdx = 0; mAwaitKeyReleasesEventTick = ::GetTickCount(); - } + } } void WinBFWindow::SetForeground() @@ -405,7 +405,7 @@ void WinBFWindow::SetForeground() ::SetFocus(mHWnd); ::SetForegroundWindow(mHWnd); - + //OutputDebugStrF("SetForeground %p %d %d %d\n", mHWnd, hadFocus, ::GetTickCount() - prevFocusLostTick, mAwaitKeyReleases); } @@ -450,7 +450,7 @@ bool WinBFWindow::CheckKeyReleases(bool isKeyDown) bool hasKeyDown = false; uint8 keysDown[256] = { 0 }; - ::GetKeyboardState((PBYTE)&keysDown); + ::GetKeyboardState((PBYTE)&keysDown); for (int i = 1; i < 256; i++) if (keysDown[i] & 0x80) hasKeyDown = true; @@ -476,7 +476,7 @@ bool WinBFWindow::CheckKeyReleases(bool isKeyDown) } LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ +{ WinBFApp* app = (WinBFApp*) gBFApp; if (app == NULL) @@ -494,7 +494,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar { auto childWindow = (WinBFWindow*)child; if ((childWindow->mSoftHasFocus) && (childWindow->mFlags & BFWINDOW_FAKEFOCUS)) - { + { return childWindow->WindowProc(hWnd, uMsg, wParam, lParam); } } @@ -521,8 +521,8 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar for (auto checkChild : winWindow->mChildren) { auto checkWinChild = (WinBFWindow*)checkChild; - if (checkWinChild->mFlags & BFWINDOW_FAKEFOCUS) - altFocusWindow = checkWinChild; + if (checkWinChild->mFlags & BFWINDOW_FAKEFOCUS) + altFocusWindow = checkWinChild; } if (altFocusWindow == NULL) break; @@ -541,7 +541,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar case WM_DESTROY: /*if (mFlags & BFWINDOW_QUIT_ON_CLOSE) { - gBFApp->mRunning = false; + gBFApp->mRunning = false; }*/ SetWindowLongPtr(mHWnd, GWLP_USERDATA, (LONG_PTR)0); mHWnd = NULL; @@ -549,7 +549,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar { NOP; } - break; + break; } LRESULT result = 0; @@ -558,7 +558,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if (!app->mInMsgProc) { if (mNeedsStateReset) - { + { for (int i = 0; i < KEYCODE_MAX; i++) { if (mIsKeyDown[i]) @@ -585,21 +585,21 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar //OutputDebugStrF("Rehup ReleaseCapture()\n"); ReleaseCapture(); - + mNeedsStateReset = false; mIsMouseInside = false; } - + WinBFWindow* menuTarget = this; - if (mFlags & BFWINDOW_USE_PARENT_MENU) - menuTarget = ((WinBFWindow*)mParent); - auto* menuIDMap = &menuTarget->mMenuIDMap; + if (mFlags & BFWINDOW_USE_PARENT_MENU) + menuTarget = ((WinBFWindow*)mParent); + auto* menuIDMap = &menuTarget->mMenuIDMap; auto* hMenuMap = &menuTarget->mHMenuMap; app->mInMsgProc = true; switch (uMsg) - { + { case WM_DISPLAYCHANGE: ((DXRenderWindow*)mRenderWindow)->mRefreshRate = 0; break; @@ -608,7 +608,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if (mMovedFunc != NULL) mMovedFunc(this); break; - case WM_PAINT: + case WM_PAINT: break; case WM_NCHITTEST: { @@ -618,23 +618,23 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar int y = (short)HIWORD(lParam); result = mHitTestFunc(this, x, y); - doResult = (result != -3); + doResult = (result != -3); } break; - case WM_LBUTTONDOWN: + case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_XBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: - case WM_LBUTTONUP: - case WM_RBUTTONUP: + case WM_LBUTTONUP: + case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_XBUTTONUP: case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: case WM_MOUSEMOVE: - { + { int x = (short)LOWORD(lParam); int y = (short)HIWORD(lParam); @@ -660,7 +660,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar bool isMouseOver = windowAtPoint == hWnd; RehupMouseOver(isMouseOver); //OutputDebugStrF("HWnd: %X Focus Window: %X Capture: %X\n", hWnd, windowAtPoint, ::GetCapture()); - + bool checkNonTransparentMousePosition = mNonExclusiveMouseCapture; auto _BtnDown = [&](int btn) @@ -688,7 +688,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } mIsMouseDown[btn] = true; BFCoord mouseCoords = { x, y }; - if ((mouseCoords.mX != mMouseDownCoords[btn].mX) || (mouseCoords.mY != mMouseDownCoords[btn].mY) || + if ((mouseCoords.mX != mMouseDownCoords[btn].mX) || (mouseCoords.mY != mMouseDownCoords[btn].mY) || (tickNow - mMouseDownTicks[btn] > ::GetDoubleClickTime())) mMouseClickCount[btn] = 0; mMouseDownCoords[btn] = mouseCoords; @@ -722,19 +722,19 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar break; case WM_MBUTTONDOWN: _BtnDown(2); - break; + break; case WM_XBUTTONDOWN: _BtnDown((int)(wParam >> 16) + 2); break; case WM_LBUTTONUP: - _BtnUp(0); + _BtnUp(0); break; - case WM_RBUTTONUP: + case WM_RBUTTONUP: _BtnUp(1); break; - case WM_MBUTTONUP: + case WM_MBUTTONUP: _BtnUp(2); - break; + break; case WM_XBUTTONUP: _BtnUp((int)(wParam >> 16) + 2); break; @@ -746,21 +746,21 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if ((gBFApp->mWindowList.size() > 1) && (GetCapture() == NULL)) { // See if our mouse is down and has entered into another window's space - POINT point = { x, y }; - HWND windowAtPoint = ::WindowFromPoint(point); + POINT point = { x, y }; + HWND windowAtPoint = ::WindowFromPoint(point); BFWindowList::iterator itr = gBFApp->mWindowList.begin(); while (itr != gBFApp->mWindowList.end()) { - WinBFWindow* aWindow = (WinBFWindow*) *itr; + WinBFWindow* aWindow = (WinBFWindow*) *itr; LONG targetStyle = ::GetWindowLong(aWindow->mHWnd, GWL_EXSTYLE); if ((::IsWindowEnabled(aWindow->mHWnd)) && ((targetStyle & WS_EX_TRANSPARENT) == 0)) { if (aWindow->mHWnd == windowAtPoint) - { + { aWindow->mIsMouseInside = true; cursorWindow = aWindow; - } + } } ++itr; } @@ -779,7 +779,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar POINT pt = {x, y}; ScreenToClient(cursorWindow->mHWnd, &pt); - + if (uMsg == WM_MOUSEWHEEL) { float delta = ((int16)HIWORD(wParam)) / 120.0f * (float)ucNumLines; @@ -804,7 +804,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar LONG captureStyle = ::GetWindowLong(captureWindow, GWL_EXSTYLE); if ((captureStyle & WS_EX_TRANSPARENT) != 0) checkNonTransparentMousePosition = true; - } + } } break; } @@ -832,18 +832,18 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar POINT clientPt = point; ::ScreenToClient(aWindow->mHWnd, &clientPt); aWindow->mMouseProxyMoveFunc(aWindow, clientPt.x, clientPt.y); - aWindow->mIsMouseInside = true; + aWindow->mIsMouseInside = true; } else if (aWindow->mIsMouseInside) { aWindow->mMouseLeaveFunc(aWindow); - aWindow->mIsMouseInside = false; + aWindow->mIsMouseInside = false; } } } ++itr; } - } + } if (releaseCapture) { @@ -871,11 +871,11 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar ++itr; } } - } + } break; - + case WM_COMMAND: - { + { WinBFMenu* aMenu = (*menuIDMap)[(uint32)wParam]; if (aMenu != NULL) menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu); @@ -910,7 +910,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } break; - case WM_MOUSEACTIVATE: + case WM_MOUSEACTIVATE: if (mFlags & BFWINDOW_NO_MOUSE_ACTIVATE) { doResult = true; @@ -930,7 +930,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar //OutputDebugStrF("WM_KILLFOCUS %p\n", hWnd); mHasFocus = false; mSoftHasFocus = false; - LostFocus(NULL); + LostFocus(NULL); mLostFocusFunc(this); break; case WM_SETFOCUS: @@ -951,7 +951,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if (mMenu != NULL) mNeedsStateReset = true; break; - case WM_NCMOUSELEAVE: + case WM_NCMOUSELEAVE: mIsMouseInside = false; mMouseLeaveFunc(this); break; @@ -967,7 +967,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar pD3DDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); pD3DDebug->Release(); } - }*/ + }*/ //NOTE: This line broke Alt+Gr for braces and such. Determine why this was needed. //if ((!mIsKeyDown[VK_MENU]) && (!mIsKeyDown[VK_CONTROL])) @@ -998,7 +998,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar keyCode = VK_RMENU; mIsKeyDown[keyCode] = true; - + // if ((keyCode == 192) && (mIsKeyDown[VK_MENU])) // { // ((DXRenderDevice*)mRenderWindow->mRenderDevice)->mNeedsReinitNative = true; @@ -1014,9 +1014,9 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar { mIsMenuKeyHandled = true; menuTarget->mMenuItemSelectedFunc(menuTarget, aMenu); - doResult = true; + doResult = true; break; - } + } } if (!mIsMenuKeyHandled) @@ -1024,14 +1024,14 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if ((CheckKeyReleases(true)) && (mKeyDownFunc(this, keyCode, (lParam & 0x7FFF) != 0))) { mIsMenuKeyHandled = true; - doResult = true; + doResult = true; } } } - break; + break; case WM_SYSCHAR: { - int keyCode = toupper((int) wParam); + int keyCode = toupper((int) wParam); for (auto& menuKV : *menuIDMap) { @@ -1040,11 +1040,11 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar (aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) && (aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) && (aMenu->mKeyAlt == mIsKeyDown[VK_MENU])) - { + { if (CheckKeyReleases(true)) - doResult = true; + doResult = true; break; - } + } } if (!mIsKeyDown[VK_MENU]) @@ -1068,7 +1068,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } CheckKeyReleases(false); } - break; + break; case WM_SYSCOMMAND: // Ignore F10 if ((wParam == SC_KEYMENU) && (lParam == 0)) @@ -1091,18 +1091,18 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar break; case WM_TIMER: if (gBFApp->mSysDialogCnt == 0) - { + { auto checkNonFake = this; while (checkNonFake->mFlags & BFWINDOW_FAKEFOCUS) { checkNonFake = (WinBFWindow*)checkNonFake->mParent; } bool isFocused = GetForegroundWindow() == checkNonFake->mHWnd; - + if ((!isFocused) && (mHasFocus)) { mSoftHasFocus = false; - mHasFocus = false; + mHasFocus = false; LostFocus(NULL); mLostFocusFunc(this); //OutputDebugStrF("Timer detected lost focus %p\r\n", hWnd); @@ -1137,7 +1137,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar doResult = true; } break; - + case WM_MOVE: case WM_MOVING: if (mMovedFunc != NULL) @@ -1148,7 +1148,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar if (mMovedFunc != NULL) mMovedFunc(this); if (gBFApp->mSysDialogCnt == 0) - gBFApp->Process(); + gBFApp->Process(); break; case WM_INPUTLANGCHANGE: @@ -1159,7 +1159,7 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar { HDROP hDropInfo = (HDROP)wParam; char sItem[MAX_PATH]; - + for(int i = 0; DragQueryFileA(hDropInfo, i, (LPSTR)sItem, sizeof(sItem)); i++) mDragDropFileFunc(this, sItem); @@ -1167,19 +1167,19 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } break; } - + app->mInMsgProc = false; } else { // We got messages we couldn't process (due to reentrancy) switch (uMsg) - { + { case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_MOUSEMOVE: - case WM_KEYUP: + case WM_KEYUP: case WM_MOUSELEAVE: mNeedsStateReset = true; break; @@ -1239,9 +1239,9 @@ static int WinBFReportHook( int reportType, char *message, int *returnValue ) /* Ignore: continue execution */ return 0; - - + + return 1; } @@ -1252,7 +1252,7 @@ static GetDpiForWindow_t gGetDpiForWindow = NULL; static HMODULE gUserDll = NULL; WinBFApp::WinBFApp() -{ +{ #ifndef BF_MINGW //_CrtSetReportHook(WinBFReportHook); #endif @@ -1264,7 +1264,7 @@ WinBFApp::WinBFApp() } mRunning = false; - mRenderDevice = NULL; + mRenderDevice = NULL; mInstallDir = "Hey"; @@ -1281,7 +1281,7 @@ WinBFApp::WinBFApp() mDataDir = mInstallDir; mInMsgProc = false; mDSoundManager = NULL; - mDInputManager = NULL; + mDInputManager = NULL; mVSyncThreadId = 0; mClosing = false; @@ -1312,8 +1312,8 @@ void WinBFApp::VSyncThreadProc() AutoCrit autoCrit(mCritSect); if ((mRenderDevice != NULL) && (!mRenderDevice->mRenderWindowList.IsEmpty())) { - auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0]; - renderWindow->mDXSwapChain->GetContainingOutput(&output); + auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0]; + renderWindow->mDXSwapChain->GetContainingOutput(&output); } } @@ -1321,8 +1321,8 @@ void WinBFApp::VSyncThreadProc() { DWORD startTick = GetTickCount(); bool success = output->WaitForVBlank() == 0; - DWORD endTick = GetTickCount(); - + DWORD endTick = GetTickCount(); + if (success) { int elapsed = (int)(endTick - startTick); @@ -1341,7 +1341,7 @@ void WinBFApp::VSyncThreadProc() if (!hadNonZero) success = false; } - } + } if (success) { @@ -1353,7 +1353,7 @@ void WinBFApp::VSyncThreadProc() output->Release(); } - if (!didWait) + if (!didWait) { mVSyncActive = false; BfpThread_Sleep(20); @@ -1362,7 +1362,7 @@ void WinBFApp::VSyncThreadProc() } WinBFApp::~WinBFApp() -{ +{ mClosing = true; BfpThread_WaitFor(mVSyncThread, -1); BfpThread_Release(mVSyncThread); @@ -1373,14 +1373,14 @@ WinBFApp::~WinBFApp() } void WinBFApp::Init() -{ +{ BP_ZONE("WinBFApp::Init"); AutoCrit autoCrit(mCritSect); mRunning = true; mInMsgProc = false; - + mRenderDevice = new DXRenderDevice(); mRenderDevice->Init(this); } @@ -1391,14 +1391,14 @@ void WinBFApp::Run() while (mRunning) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { + { TranslateMessage(&msg); DispatchMessage(&msg); } if (mRunning) Process(); - } + } } void WinBFApp::Process() @@ -1416,9 +1416,9 @@ void WinBFApp::Process() void WinBFApp::Draw() { - mRenderDevice->FrameStart(); + mRenderDevice->FrameStart(); BFApp::Draw(); - mRenderDevice->FrameEnd(); + mRenderDevice->FrameEnd(); } void WinBFApp::GetDesktopResolution(int& width, int& height) @@ -1460,7 +1460,7 @@ static BOOL InflateRectToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM u } void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height) -{ +{ AdjustedMonRect inflateRect = { 0 }; EnumDisplayMonitors(NULL, NULL, InflateRectToMonitor, (LPARAM)&inflateRect); @@ -1494,12 +1494,12 @@ void WinBFApp::GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fro } BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) -{ +{ AutoCrit autoCrit(mCritSect); BFWindow* aWindow = new WinBFWindow(parent, title, x, y, width, height, windowFlags); mWindowList.push_back(aWindow); - + return aWindow; } @@ -1535,7 +1535,7 @@ void WinBFWindow::SetMinimumSize(int minWidth, int minHeight, bool clientSized) DWORD windowFlagsEx = ::GetWindowLong(mHWnd, GWL_EXSTYLE); RECT rect = { 0, 0, minWidth, minHeight }; - AdjustWindowRectEx(&rect, windowFlags, mMenu != NULL, windowFlagsEx); + AdjustWindowRectEx(&rect, windowFlags, mMenu != NULL, windowFlagsEx); minWidth = rect.right - rect.left; minHeight = rect.bottom - rect.top; } @@ -1615,14 +1615,14 @@ void WinBFWindow::GetPlacement(int* normX, int* normY, int* normWidth, int* norm default: *showKind = 0; break; - } + } } void WinBFWindow::Resize(int x, int y, int width, int height, int showKind) -{ +{ WINDOWPLACEMENT wndPlacement = { sizeof(WINDOWPLACEMENT), 0 }; ::GetWindowPlacement(mHWnd, &wndPlacement); - + switch (showKind) { case 1: @@ -1634,7 +1634,7 @@ void WinBFWindow::Resize(int x, int y, int width, int height, int showKind) case 3: wndPlacement.showCmd = SW_SHOWNORMAL; break; - } + } wndPlacement.rcNormalPosition.left = x; wndPlacement.rcNormalPosition.top = y; @@ -1645,31 +1645,31 @@ void WinBFWindow::Resize(int x, int y, int width, int height, int showKind) //::MoveWindow(mHWnd, x, y, width, height, FALSE); mRenderWindow->Resized(); if (mMovedFunc != NULL) - mMovedFunc(this); + mMovedFunc(this); } void WinBFApp::PhysSetCursor() { - static HCURSOR cursors [] = - { + static HCURSOR cursors [] = + { ::LoadCursor(NULL, IDC_ARROW), - + //TODO: mApp->mHandCursor); ::LoadCursor(NULL, IDC_HAND), //TODO: mApp->mDraggingCursor); ::LoadCursor(NULL, IDC_SIZEALL), ::LoadCursor(NULL, IDC_IBEAM), - - ::LoadCursor(NULL, IDC_NO), + + ::LoadCursor(NULL, IDC_NO), ::LoadCursor(NULL, IDC_SIZEALL), ::LoadCursor(NULL, IDC_SIZENESW), - ::LoadCursor(NULL, IDC_SIZENS), + ::LoadCursor(NULL, IDC_SIZENS), ::LoadCursor(NULL, IDC_SIZENWSE), - ::LoadCursor(NULL, IDC_SIZEWE), - ::LoadCursor(NULL, IDC_WAIT), + ::LoadCursor(NULL, IDC_SIZEWE), + ::LoadCursor(NULL, IDC_WAIT), NULL - }; + }; ::SetCursor(cursors[mCursor]); } @@ -1705,7 +1705,7 @@ void WinBFWindow::SetMouseVisible(bool isMouseVisible) void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) { if (destAlphaSrcMask != 0) - { + { if (mAlphaMaskBitmap == NULL) { RECT clientRect; @@ -1727,7 +1727,7 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis bi.bmiHeader.biWidth = aWidth; bi.bmiHeader.biHeight = -aHeight; bi.bmiHeader.biCompression = BI_RGB; - bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biPlanes = 1; mAlphaMaskBitmap = CreateDIBSection(mAlphaMaskDC, &bi, DIB_RGB_COLORS, (void**)&mAlphaMaskPixels, NULL, 0); @@ -1741,9 +1741,9 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis DXRenderWindow* renderWindow = (DXRenderWindow*) mRenderWindow; renderWindow->CopyBitsTo(mAlphaMaskPixels, mAlphaMaskWidth, mAlphaMaskHeight); - //for (int i = 0; i < mAlphaMaskWidth*mAlphaMaskHeight/2; i++) - //mAlphaMaskPixels[i] = 0x80FF8000; - + //for (int i = 0; i < mAlphaMaskWidth*mAlphaMaskHeight/2; i++) + //mAlphaMaskPixels[i] = 0x80FF8000; + HGDIOBJ hPrevObj = 0; POINT ptDest = {0, 0}; POINT ptSrc = {0, 0}; @@ -1752,28 +1752,28 @@ void WinBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVis hPrevObj = SelectObject(mAlphaMaskDC, mAlphaMaskBitmap); ClientToScreen(mHWnd, &ptDest); - + BOOL worked = ::UpdateLayeredWindow(mHWnd, hdc, NULL, &client, mAlphaMaskDC, &ptSrc, 0, &blendFunc, ULW_ALPHA); DWORD error = GetLastError(); SelectObject(mAlphaMaskDC, hPrevObj); - ReleaseDC(mHWnd, hdc); + ReleaseDC(mHWnd, hdc); } } else { ::SetLayeredWindowAttributes(mHWnd, 0, (int) (alpha * 255), LWA_ALPHA); } - SetMouseVisible(isMouseVisible); + SetMouseVisible(isMouseVisible); } void WinBFWindow::CaptureMouse() { //OutputDebugStrF("Wnd %p CaptureMouse", this); ::SetCapture(mHWnd); - + for (auto window : gBFApp->mWindowList) { if (window == this) @@ -1813,7 +1813,7 @@ uint32 WinBFApp::GetClipboardFormat(const StringImpl& format) uint32 aFormat; if (mClipboardFormatMap.TryGetValue(format, &aFormat)) return aFormat; - + aFormat = ::RegisterClipboardFormatA(format.c_str()); mClipboardFormatMap[format] = aFormat; return aFormat; @@ -1840,7 +1840,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) if (aFormat == CF_UNICODETEXT) { CloseClipboard(); - // Return ascii text + // Return ascii text return (char*)GetClipboardData("atext", size); } @@ -1851,7 +1851,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) *size = (int)::GlobalSize(globalHandle); void* aPtr = ::GlobalLock(globalHandle); - + if (aFormat == CF_UNICODETEXT) { gClipboardData = UTF8Encode((WCHAR*)aPtr); @@ -1862,11 +1862,16 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) gClipboardData.Clear(); gClipboardData.Insert(0, (char*)aPtr, *size); } - + ::GlobalUnlock(globalHandle); CloseClipboard(); return (void*)gClipboardData.c_str(); } + else + { + *size = -1; + return NULL; + } } *size = 0; @@ -1875,7 +1880,7 @@ void* WinBFApp::GetClipboardData(const StringImpl& format, int* size) void WinBFApp::ReleaseClipboardData(void* ptr) { - + } void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) @@ -1887,7 +1892,7 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s aWindow = ((WinBFWindow*) mWindowList.front())->mHWnd; uint32 aFormat = GetClipboardFormat(format); - + if (aFormat != 0) { if (OpenClipboard(aWindow)) @@ -1897,7 +1902,7 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s BP_ZONE("WinBFApp::SetClipboardData:empty"); EmptyClipboard(); } - + if (format == "text") { BP_ZONE("WinBFApp::SetClipboardData:text"); @@ -1922,14 +1927,14 @@ void WinBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int s GlobalUnlock(globalHandle); ::SetClipboardData(aFormat, globalHandle); } - + CloseClipboard(); } } } BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck) -{ +{ UTF16String lText; if (text != NULL) lText = UTF8Decode(text); @@ -1938,7 +1943,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text lHotKey = UTF8Decode(hotKey); bool wasEmpty = mMenu->mBFMenuList.size() == 0; - + if (parent == NULL) parent = mMenu; @@ -1949,7 +1954,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text RemoveMenuItem(placeholderMenuItem); delete placeholderMenuItem; } - + WinBFMenu* winBFMenuParent = (WinBFMenu*) parent; WinBFMenu* newMenu = new WinBFMenu(); newMenu->mMenuId = ++WinBFMenu::mMenuCount; @@ -1969,14 +1974,14 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text menuItem.cbSize = sizeof(MENUITEMINFO); menuItem.fMask = MIIM_SUBMENU; menuItem.hSubMenu = winBFMenuParent->mMenu; - - ::SetMenuItemInfo(((WinBFMenu*) winBFMenuParent->mParent)->mMenu, winBFMenuParent->mMenuId, FALSE, &menuItem); + + ::SetMenuItemInfo(((WinBFMenu*) winBFMenuParent->mParent)->mMenu, winBFMenuParent->mMenuId, FALSE, &menuItem); } mMenuIDMap[newMenu->mMenuId] = newMenu; BF_ASSERT(insertIdx <= (int) parent->mBFMenuList.size()); - + //// UTF16String lCombinedName; @@ -1986,11 +1991,11 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text menuItem.fMask = MIIM_FTYPE | MIIM_ID; if (text != NULL) { - menuItem.fMask |= MIIM_STRING; + menuItem.fMask |= MIIM_STRING; menuItem.fType = MFT_STRING; } else - menuItem.fType = MFT_SEPARATOR; + menuItem.fType = MFT_SEPARATOR; menuItem.fState = enabled ? MFS_DEFAULT : MFS_GRAYED; if (checkState == 0) menuItem.fState |= MFS_UNCHECKED; @@ -1998,14 +2003,14 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text menuItem.fState |= MFS_CHECKED; if (radioCheck) menuItem.fType = MFT_RADIOCHECK; - + menuItem.wID = newMenu->mMenuId; if (text != NULL) { menuItem.dwTypeData = (WCHAR*)lText.c_str(); } - if (hotKey != NULL) + if (hotKey != NULL) { String combinedName = String(text); combinedName += "\t"; @@ -2033,7 +2038,7 @@ BFMenu* WinBFWindow::AddMenuItem(BFMenu* parent, int insertIdx, const char* text ModifyMenuItem(newMenu, text, hotKey, sysBitmap, enabled, checkState, radioCheck); - parent->mBFMenuList.push_back(newMenu); + parent->mBFMenuList.push_back(newMenu); return newMenu; } @@ -2051,11 +2056,11 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot WinBFMenu* parentMenu = (WinBFMenu*) item->mParent; UTF16String lCombinedName; - + MENUITEMINFOW menuItem; memset(&menuItem, 0, sizeof(MENUITEMINFO)); menuItem.cbSize = sizeof(MENUITEMINFO); - menuItem.fMask = MIIM_FTYPE | MIIM_ID; + menuItem.fMask = MIIM_FTYPE | MIIM_ID; ::GetMenuItemInfoW(parentMenu->mMenu, aMenu->mMenuId, FALSE, &menuItem); @@ -2082,12 +2087,12 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot menuItem.fType = MFT_RADIOCHECK; menuItem.wID = aMenu->mMenuId; - menuItem.dwTypeData = (WCHAR*)lText.c_str(); + menuItem.dwTypeData = (WCHAR*)lText.c_str(); if (hotKey != NULL) { menuItem.fMask |= MIIM_DATA; - + String combinedName = String(text); combinedName += "\t"; if (hotKey[0] == '#') @@ -2107,7 +2112,7 @@ void WinBFWindow::ModifyMenuItem(BFMenu* item, const char* text, const char* hot } void WinBFWindow::RemoveMenuItem(BFMenu* item) -{ +{ WinBFMenu* aMenu = (WinBFMenu*) item; WinBFMenu* parentMenu = (WinBFMenu*) item->mParent; @@ -2115,7 +2120,7 @@ void WinBFWindow::RemoveMenuItem(BFMenu* item) //mMenuIDMap.erase(itr); mMenuIDMap.Remove(aMenu->mMenuId); - ::RemoveMenu(parentMenu->mMenu, aMenu->mMenuId, MF_BYCOMMAND); + ::RemoveMenu(parentMenu->mMenu, aMenu->mMenuId, MF_BYCOMMAND); } BFSysBitmap* WinBFApp::LoadSysBitmap(const WCHAR* fileName) @@ -2148,8 +2153,8 @@ DrawLayer* WinBFApp::CreateDrawLayer(BFWindow* window) { DXDrawLayer* drawLayer = new DXDrawLayer(); if (window != NULL) - { - drawLayer->mRenderWindow = window->mRenderWindow; + { + drawLayer->mRenderWindow = window->mRenderWindow; window->mRenderWindow->mDrawLayerList.push_back(drawLayer); } drawLayer->mRenderDevice = mRenderDevice; diff --git a/BeefySysLib/third_party/putty/LICENSE b/BeefySysLib/third_party/putty/LICENSE new file mode 100644 index 00000000..478b68d8 --- /dev/null +++ b/BeefySysLib/third_party/putty/LICENSE @@ -0,0 +1,28 @@ +PuTTY is copyright 1997-2020 Simon Tatham. + +Portions copyright Robert de Bath, Joris van Rantwijk, Delian +Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, +Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus +Kuhn, Colin Watson, Christopher Staite, Lorenz Diener, Christian +Brabandt, Jeff Smith, Pavel Kryukov, Maxim Kuznetsov, Svyatoslav +Kuzmich, Nico Williams, Viktor Dukhovni, Josh Dersch, Lars Brinkhoff, +and CORE SDI S.A. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation files +(the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/BeefySysLib/third_party/putty/wildcard.c b/BeefySysLib/third_party/putty/wildcard.c new file mode 100644 index 00000000..2b1f858f --- /dev/null +++ b/BeefySysLib/third_party/putty/wildcard.c @@ -0,0 +1,340 @@ +/* + * Wildcard matching engine for use with SFTP-based file transfer + * programs (PSFTP, new-look PSCP): since SFTP has no notion of + * getting the remote side to do globbing (and rightly so) we have + * to do it locally, by retrieving all the filenames in a directory + * and checking each against the wildcard pattern. + */ + +#include +#include +#include + +#include "wildcard.h" + +/* + * Definition of wildcard syntax: + * + * - * matches any sequence of characters, including zero. + * - ? matches exactly one character which can be anything. + * - [abc] matches exactly one character which is a, b or c. + * - [a-f] matches anything from a through f. + * - [^a-f] matches anything _except_ a through f. + * - [-_] matches - or _; [^-_] matches anything else. (The - is + * non-special if it occurs immediately after the opening + * bracket or ^.) + * - [a^] matches an a or a ^. (The ^ is non-special if it does + * _not_ occur immediately after the opening bracket.) + * - \*, \?, \[, \], \\ match the single characters *, ?, [, ], \. + * - All other characters are non-special and match themselves. + */ + +/* + * Some notes on differences from POSIX globs (IEEE Std 1003.1, 2003 ed.): + * - backslashes act as escapes even within [] bracket expressions + * - does not support [!...] for non-matching list (POSIX are weird); + * NB POSIX allows [^...] as well via "A bracket expression starting + * with an unquoted circumflex character produces unspecified + * results". If we wanted to allow [!...] we might want to define + * [^!] as having its literal meaning (match '^' or '!'). + * - none of the scary [[:class:]] stuff, etc + */ + +/* + * The wildcard matching technique we use is very simple and + * potentially O(N^2) in running time, but I don't anticipate it + * being that bad in reality (particularly since N will be the size + * of a filename, which isn't all that much). Perhaps one day, once + * PuTTY has grown a regexp matcher for some other reason, I might + * come back and reimplement wildcards by translating them into + * regexps or directly into NFAs; but for the moment, in the + * absence of any other need for the NFA->DFA translation engine, + * anything more than the simplest possible wildcard matcher is + * vast code-size overkill. + * + * Essentially, these wildcards are much simpler than regexps in + * that they consist of a sequence of rigid fragments (? and [...] + * can never match more or less than one character) separated by + * asterisks. It is therefore extremely simple to look at a rigid + * fragment and determine whether or not it begins at a particular + * point in the test string; so we can search along the string + * until we find each fragment, then search for the next. As long + * as we find each fragment in the _first_ place it occurs, there + * will never be a danger of having to backpedal and try to find it + * again somewhere else. + */ + +enum { + WC_TRAILINGBACKSLASH = 1, + WC_UNCLOSEDCLASS, + WC_INVALIDRANGE +}; + +/* + * Error reporting is done by returning various negative values + * from the wildcard routines. Passing any such value to wc_error + * will give a human-readable message. + */ +const char *wc_error(int value) +{ + value = abs(value); + switch (value) { + case WC_TRAILINGBACKSLASH: + return "'\' occurred at end of string (expected another character)"; + case WC_UNCLOSEDCLASS: + return "expected ']' to close character class"; + case WC_INVALIDRANGE: + return "character range was not terminated (']' just after '-')"; + } + return "INTERNAL ERROR: unrecognised wildcard error number"; +} + +/* + * This is the routine that tests a target string to see if an + * initial substring of it matches a fragment. If successful, it + * returns 1, and advances both `fragment' and `target' past the + * fragment and matching substring respectively. If unsuccessful it + * returns zero. If the wildcard fragment suffers a syntax error, + * it returns <0 and the precise value indexes into wc_error. + */ +static int wc_match_fragment(const char **fragment, const char **target, + const char *target_end) +{ + const char *f, *t; + + f = *fragment; + t = *target; + /* + * The fragment terminates at either the end of the string, or + * the first (unescaped) *. + */ + while (*f && *f != '*' && t < target_end) { + /* + * Extract one character from t, and one character's worth + * of pattern from f, and step along both. Return 0 if they + * fail to match. + */ + if (*f == '\\') { + /* + * Backslash, which means f[1] is to be treated as a + * literal character no matter what it is. It may not + * be the end of the string. + */ + if (!f[1]) + return -WC_TRAILINGBACKSLASH; /* error */ + if (f[1] != *t) + return 0; /* failed to match */ + f += 2; + } else if (*f == '?') { + /* + * Question mark matches anything. + */ + f++; + } else if (*f == '[') { + bool invert = false; + bool matched = false; + /* + * Open bracket introduces a character class. + */ + f++; + if (*f == '^') { + invert = true; + f++; + } + while (*f != ']') { + if (*f == '\\') + f++; /* backslashes still work */ + if (!*f) + return -WC_UNCLOSEDCLASS; /* error again */ + if (f[1] == '-') { + int lower, upper, ourchr; + lower = (unsigned char) *f++; + f++; /* eat the minus */ + if (*f == ']') + return -WC_INVALIDRANGE; /* different error! */ + if (*f == '\\') + f++; /* backslashes _still_ work */ + if (!*f) + return -WC_UNCLOSEDCLASS; /* error again */ + upper = (unsigned char) *f++; + ourchr = (unsigned char) *t; + if (lower > upper) { + int t = lower; lower = upper; upper = t; + } + if (ourchr >= lower && ourchr <= upper) + matched = true; + } else { + matched |= (*t == *f++); + } + } + if (invert == matched) + return 0; /* failed to match character class */ + f++; /* eat the ] */ + } else { + /* + * Non-special character matches itself. + */ + if (*f != *t) + return 0; + f++; + } + /* + * Now we've done that, increment t past the character we + * matched. + */ + t++; + } + if (!*f || *f == '*') { + /* + * We have reached the end of f without finding a mismatch; + * so we're done. Update the caller pointers and return 1. + */ + *fragment = f; + *target = t; + return 1; + } + /* + * Otherwise, we must have reached the end of t before we + * reached the end of f; so we've failed. Return 0. + */ + return 0; +} + +/* + * This is the real wildcard matching routine. It returns 1 for a + * successful match, 0 for an unsuccessful match, and <0 for a + * syntax error in the wildcard. + */ +static int wc_match_inner( + const char *wildcard, const char *target, size_t target_len) +{ + const char *target_end = target + target_len; + int ret; + + /* + * Every time we see a '*' _followed_ by a fragment, we just + * search along the string for a location at which the fragment + * matches. The only special case is when we see a fragment + * right at the start, in which case we just call the matching + * routine once and give up if it fails. + */ + if (*wildcard != '*') { + ret = wc_match_fragment(&wildcard, &target, target_end); + if (ret <= 0) + return ret; /* pass back failure or error alike */ + } + + while (*wildcard) { + assert(*wildcard == '*'); + while (*wildcard == '*') + wildcard++; + + /* + * It's possible we've just hit the end of the wildcard + * after seeing a *, in which case there's no need to + * bother searching any more because we've won. + */ + if (!*wildcard) + return 1; + + /* + * Now `wildcard' points at the next fragment. So we + * attempt to match it against `target', and if that fails + * we increment `target' and try again, and so on. When we + * find we're about to try matching against the empty + * string, we give up and return 0. + */ + ret = 0; + while (*target) { + const char *save_w = wildcard, *save_t = target; + + ret = wc_match_fragment(&wildcard, &target, target_end); + + if (ret < 0) + return ret; /* syntax error */ + + if (ret > 0 && !*wildcard && target != target_end) { + /* + * Final special case - literally. + * + * This situation arises when we are matching a + * _terminal_ fragment of the wildcard (that is, + * there is nothing after it, e.g. "*a"), and it + * has matched _too early_. For example, matching + * "*a" against "parka" will match the "a" fragment + * against the _first_ a, and then (if it weren't + * for this special case) matching would fail + * because we're at the end of the wildcard but not + * at the end of the target string. + * + * In this case what we must do is measure the + * length of the fragment in the target (which is + * why we saved `target'), jump straight to that + * distance from the end of the string using + * strlen, and match the same fragment again there + * (which is why we saved `wildcard'). Then we + * return whatever that operation returns. + */ + target = target_end - (target - save_t); + wildcard = save_w; + return wc_match_fragment(&wildcard, &target, target_end); + } + + if (ret > 0) + break; + target++; + } + if (ret > 0) + continue; + return 0; + } + + /* + * If we reach here, it must be because we successfully matched + * a fragment and then found ourselves right at the end of the + * wildcard. Hence, we return 1 if and only if we are also + * right at the end of the target. + */ + return target == target_end; +} + +int wc_match(const char *wildcard, const char *target) +{ + return wc_match_inner(wildcard, target, strlen(target)); +} + +/* + * Another utility routine that translates a non-wildcard string + * into its raw equivalent by removing any escaping backslashes. + * Expects a target string buffer of anything up to the length of + * the original wildcard. You can also pass NULL as the output + * buffer if you're only interested in the return value. + * + * Returns true on success, or false if a wildcard character was + * encountered. In the latter case the output string MAY not be + * zero-terminated and you should not use it for anything! + */ +bool wc_unescape(char *output, const char *wildcard) +{ + while (*wildcard) { + if (*wildcard == '\\') { + wildcard++; + /* We are lenient about trailing backslashes in non-wildcards. */ + if (*wildcard) { + if (output) + *output++ = *wildcard; + wildcard++; + } + } else if (*wildcard == '*' || *wildcard == '?' || + *wildcard == '[' || *wildcard == ']') { + return false; /* it's a wildcard! */ + } else { + if (output) + *output++ = *wildcard; + wildcard++; + } + } + if (output) + *output = '\0'; + return true; /* it's clean */ +} \ No newline at end of file diff --git a/BeefySysLib/third_party/putty/wildcard.h b/BeefySysLib/third_party/putty/wildcard.h new file mode 100644 index 00000000..3c4a75ee --- /dev/null +++ b/BeefySysLib/third_party/putty/wildcard.h @@ -0,0 +1,18 @@ +#ifndef PUTTY_WILDCARD_H_INCLUDE +#define PUTTY_WILDCARD_H_INCLUDE + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const char *wc_error(int value); +int wc_match(const char *wildcard, const char *target); +bool wc_unescape(char *output, const char *wildcard); + +#ifdef __cplusplus +} +#endif + +#endif // PUTTY_WILDCARD_H_INCLUDE \ No newline at end of file diff --git a/BeefySysLib/util/BeefPerf.cpp b/BeefySysLib/util/BeefPerf.cpp index 49ffeef1..e1dae1c1 100644 --- a/BeefySysLib/util/BeefPerf.cpp +++ b/BeefySysLib/util/BeefPerf.cpp @@ -757,10 +757,15 @@ bool BpManager::Connect() if (mShutdownEvent.WaitFor(0)) { // We are shutting down - have we waited enough? - int minWaitMS = isLocalhost ? 50 : 20*1000; + int minWaitMS = isLocalhost ? 50 : 5*1000; if (totalWaitedMS >= minWaitMS) return false; } + + // We don't want to wait too long, otherwise we will buffer up too much + int maxWaitMS = isLocalhost ? 5*1000 : 15*1000; + if (totalWaitedMS >= maxWaitMS) + return false; } return true; diff --git a/BeefySysLib/util/SizedArray.h b/BeefySysLib/util/SizedArray.h index 63b328ad..51071e59 100644 --- a/BeefySysLib/util/SizedArray.h +++ b/BeefySysLib/util/SizedArray.h @@ -925,6 +925,8 @@ public: this->mSize = val.mSize; this->mAllocSize = val.mAllocSize; val.mVals = (T*)&val.mFirstVal; + val.mSize = 0; + val.mAllocSize = TInternalSize; } } @@ -1006,6 +1008,8 @@ public: this->mAllocSize = val.mAllocSize; val.mVals = NULL; + val.mSize = 0; + val.mAllocSize = 0; } } @@ -1079,6 +1083,8 @@ public: this->mAllocSize = val.mAllocSize; val.mVals = &val.mInternalBuffer; + val.mSize = 0; + val.mAllocSize = 1; } } diff --git a/Debugger32/Debugger32.vcxproj b/Debugger32/Debugger32.vcxproj index 9c1e17a8..a724f12c 100644 --- a/Debugger32/Debugger32.vcxproj +++ b/Debugger32/Debugger32.vcxproj @@ -132,6 +132,7 @@ BF_DBG_32;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include false + true Windows @@ -150,6 +151,7 @@ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) false MultiThreadedDebug + true Windows @@ -166,6 +168,7 @@ true BF_DBG_32;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include + true Windows @@ -186,6 +189,7 @@ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include MultiThreaded false + true Windows diff --git a/Debugger64/Debugger64.vcxproj b/Debugger64/Debugger64.vcxproj index 57e46574..933ad4f2 100644 --- a/Debugger64/Debugger64.vcxproj +++ b/Debugger64/Debugger64.vcxproj @@ -132,6 +132,7 @@ BF_DBG_64;WIN32;_DEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include false + true Windows @@ -150,6 +151,7 @@ -D_SCL_SECURE_NO_WARNINGS %(AdditionalOptions) false MultiThreadedDebug + true Windows @@ -166,6 +168,7 @@ true BF_DBG_64;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin64\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin64\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include + true Windows @@ -186,6 +189,7 @@ ../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include MultiThreaded false + true Windows diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index 237b630b..ce73e660 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -13,7 +13,7 @@ Description = "Beef IDE" Company = "BeefyTech LLC" Product = "Beef IDE" Copyright = "Copyright 2019 BeefyTech" -FileVersion = "0.43.3" +FileVersion = "0.43.4" ProductVersion = "0000000000000000" [Configs.Debug.Win32] @@ -24,7 +24,7 @@ OtherLinkFlags = "" TargetDirectory = "$(WorkspaceDir)/dist" TargetName = "BeefIDE_d" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib" -DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDEHelper\\Tests\"" +DebugCommandArguments = "-proddir=\"$(WorkspaceDir)\\..\\IDE\"" DebugWorkingDirectory = "$(WorkspaceDir)\\.." EnvironmentVars = ["_NO_DEBUG_HEAP=1"] @@ -36,7 +36,7 @@ OtherLinkFlags = "" TargetDirectory = "$(WorkspaceDir)/dist" TargetName = "BeefIDE" OtherLinkFlags = "Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib Beef042RT64.lib IDEHelper64.lib BeefySysLib64.lib" -DebugCommandArguments = "-proddir=C:\\Beef\\IDE\\Tests\\Rando" +DebugCommandArguments = "-workspace=C:\\proj\\BeefTest" DebugWorkingDirectory = "$(ProjectDir)\\dist" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] @@ -48,8 +48,9 @@ OtherLinkFlags = "" TargetDirectory = "$(WorkspaceDir)/dist" TargetName = "BeefIDE_d2" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib BeefySysLib64_d.lib wsock32.lib" -DebugCommandArguments = "-workspace=c:\\proj\\BeefTest" -DebugWorkingDirectory = "$(ProjectDir)\\dist" +BeefLibType = "DynamicDebug" +DebugCommandArguments = "-proddir=C:\\proj\\BeefTest" +DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] [Configs.Paranoid.Win64] diff --git a/IDE/Tests/CompileFail001/src/Generics.bf b/IDE/Tests/CompileFail001/src/Generics.bf index 447928b4..d0ac2f3f 100644 --- a/IDE/Tests/CompileFail001/src/Generics.bf +++ b/IDE/Tests/CompileFail001/src/Generics.bf @@ -119,6 +119,38 @@ namespace IDETest { } + + public class TestExt where T : struct + { + public struct InnerA + { + + } + + public struct InnerB where T2 : struct + { + + } + } + + extension TestExt + where T : Int + { + public int a = 0; + + public struct InnerC + { + } + } + + static void TestExtMethod() + { + TestExt.InnerA a; //FAIL + TestExt.InnerB b; //FAIL + TestExt.InnerB c; + TestExt.InnerC d; + TestExt.InnerC e; //FAIL + } } } diff --git a/IDE/Tests/CompileFail001/src/LocalVars.bf b/IDE/Tests/CompileFail001/src/LocalVars.bf index 54361d2d..96246310 100644 --- a/IDE/Tests/CompileFail001/src/LocalVars.bf +++ b/IDE/Tests/CompileFail001/src/LocalVars.bf @@ -342,5 +342,112 @@ namespace IDETest int b3 = b; //FAIL int c3 = c; //FAIL } + + Result Read() + { + return 0; + } + + public void Local8() + { + int read; + loop: repeat + { + switch (Read()) + { + case .Err: return; + case .Ok(let val): read = val; + } + } + while (read > 0); + } + + public void Local9() + { + int read; + loop: repeat + { + switch (Read()) + { + case .Err: break loop; + case .Ok(let val): read = val; + } + int a = read; + } + while (read > 0); + } + + public void Local10() + { + int read; + loop: repeat + { + switch (Read()) + { + case .Err: break; + case .Ok(let val): read = val; + } + int a = read; //FAIL + } + while (read > 0); //FAIL + } + + public void Local11() + { + int a = 123; + + int read; + Loop: repeat + { + break; + } + while (read > 0); + } + + public void Local12() + { + int a = 123; + + int read; + Loop: repeat + { + if (a == 123) + break; + } + while (read > 0); //FAIL + } + + public void Local13() + { + int a = 123; + int b; + switch (a) + { + default: b = 0; + } + int c = b; + } + + public void Local14() + { + int a = 123; + int b; + switch (a) + { + default: b = 0; break; + } + int c = b; + } + + public void Local15() + { + int a = 123; + int b; + switch (a) + { + default: break; + } + int c = b; //FAIL + } } } diff --git a/IDE/Tests/Test1/scripts/UsingFields.txt b/IDE/Tests/Test1/scripts/UsingFields.txt new file mode 100644 index 00000000..9104aae8 --- /dev/null +++ b/IDE/Tests/Test1/scripts/UsingFields.txt @@ -0,0 +1,13 @@ +ShowFile("src/UsingFields.bf") +GotoText("//Test_Start") +ToggleBreakpoint() +RunWithCompiling() + +AssertEvalEquals("v0.x", "123") +AssertEvalEquals("v1.x", "345") + +# Temporarily broken in LLVM +if (platform != "Win64") Stop() + +AssertEvalEquals("v0.GetX()", "123") +AssertEvalEquals("v1.GetX()", "345") \ No newline at end of file diff --git a/IDE/Tests/Test1/src/Program.bf b/IDE/Tests/Test1/src/Program.bf index 7db5c7da..e17d8dd2 100644 --- a/IDE/Tests/Test1/src/Program.bf +++ b/IDE/Tests/Test1/src/Program.bf @@ -31,6 +31,7 @@ namespace IDETest Stepping_Scope.Test(); TypedPrimitives.Test(); Unions.Test(); + UsingFields.Test(); Virtuals.Test(); Bug001.Test(); diff --git a/IDE/Tests/Test1/src/UsingFields.bf b/IDE/Tests/Test1/src/UsingFields.bf new file mode 100644 index 00000000..f7952135 --- /dev/null +++ b/IDE/Tests/Test1/src/UsingFields.bf @@ -0,0 +1,43 @@ +#pragma warning disable 168 + +using System; + +namespace IDETest +{ + class UsingFields + { + struct Vector2Int + { + [Union] + struct XWidth + { + public int x; + public int width; + + public int GetX() => x; + } + [Union] struct YHeight : this(int y, int height); + + public using XWidth xWidth; + public using YHeight yHeight; + } + + struct TestVec : Vector2Int + { + } + + public static void Test() + { + Vector2Int v0; + v0.x = 123; + v0.y = 234; + + TestVec v1; + v1.x = 345; + v0.y = 456; + + //Test_Start + int v = v0.GetX(); + } + } +} \ No newline at end of file diff --git a/IDE/dist/BeefDbgVis.toml b/IDE/dist/BeefDbgVis.toml index eae78df5..ddde0d0f 100644 --- a/IDE/dist/BeefDbgVis.toml +++ b/IDE/dist/BeefDbgVis.toml @@ -21,18 +21,18 @@ ValuePointer = "/*(mMethodId < 0) ? &this :*/ __cast(\"_BF_DeferredData_\", mMet [[Type]] Name = "System.Event<*>" -DisplayString = "{{ data={__cast(\"System.Object\", mData & ~3)} }}" +DisplayString = "{{ data={__cast(\"System.Object\", mData & sDataMask)} }}" [[Type.Expand.Item]] Name = "[target]" Value = "__cast(\"System.Object\", mData)" -Condition = "(mData & 1) == 0" +Condition = "(mData & sIsEnumerating) == 0" [[Type.Expand.Item]] Name = "[target]" -Value = "((System.Event<$T1>.Enumerator*)(mData & ~3)).mTarget" -Condition = "(mData & 1) != 0" +Value = "((System.Event<$T1>.Enumerator*)(mData & sDataMask)).mTarget" +Condition = "(mData & sIsEnumerating) != 0" [[Type.Expand.Item]] Name = "[flags]" -Value = "mData & 3" +Value = "mData & sFlagsMask" [[Type]] Name = "_BF_DeferredData_*" @@ -52,14 +52,14 @@ String = "{{ {__demangleFakeMember(this)} }}" Name = "System.String" [[Type.DisplayString]] Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0" -String = "{(char8*)&mPtr,s8,count=mLength}" +String = "{(char8*)&mPtrOrBuffer,s8,count=mLength}" [[Type.DisplayString]] -String = "{mPtr,s8,count=mLength}" +String = "{mPtrOrBuffer,s8,count=mLength}" [[Type.StringView]] Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0" -String = "{(char8*)&mPtr,s8,count=mLength}" +String = "{(char8*)&mPtrOrBuffer,s8,count=mLength}" [[Type.StringView]] -String = "{mPtr,s8,count=mLength}" +String = "{mPtrOrBuffer,s8,count=mLength}" [[Type.Expand.Item]] Name = "[Length]" Value = "mLength" @@ -78,11 +78,11 @@ Value = "__clearHighBits(mAllocSizeAndFlags, 2)" [[Type.Expand.Item]] Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) == 0" Name = "[RawChars]" -Value = "(char8*)&mPtr,arraysize=mLength" +Value = "(char8*)&mPtrOrBuffer,arraysize=mLength" [[Type.Expand.Item]] Condition = "(__getHighBits(mAllocSizeAndFlags, 2) & 1) != 0" Name = "[RawChars]" -Value = "mPtr,arraysize=mLength" +Value = "mPtrOrBuffer,arraysize=mLength" [[Type]] Name = "System.StringView" diff --git a/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf b/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf index 5df17c60..6c52f3ed 100644 --- a/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf +++ b/IDE/mintest/minlib/src/System/Diagnostics/Profiler.bf @@ -38,7 +38,7 @@ namespace System.Diagnostics } } - static Result StartSampling(int32 threadId, StringView profileDesc) + static Result StartSampling(int threadId, StringView profileDesc) { //int32 curId = Interlocked.Increment(ref gProfileId); int32 curId = gProfileId++; diff --git a/IDE/mintest/minlib/src/System/Result.bf b/IDE/mintest/minlib/src/System/Result.bf index 7b5da210..30958aeb 100644 --- a/IDE/mintest/minlib/src/System/Result.bf +++ b/IDE/mintest/minlib/src/System/Result.bf @@ -95,7 +95,7 @@ namespace System extension Result where T : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); @@ -199,7 +199,7 @@ namespace System extension Result where T : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); @@ -208,7 +208,7 @@ namespace System extension Result where TErr : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Err(var err)) err.Dispose(); @@ -217,7 +217,7 @@ namespace System extension Result where T : IDisposable where TErr : IDisposable { - public void Dispose() + public new void Dispose() { if (this case .Ok(var val)) val.Dispose(); diff --git a/IDE/mintest/minlib/src/System/Runtime.bf b/IDE/mintest/minlib/src/System/Runtime.bf index 7e0b9687..c4235009 100644 --- a/IDE/mintest/minlib/src/System/Runtime.bf +++ b/IDE/mintest/minlib/src/System/Runtime.bf @@ -7,7 +7,7 @@ namespace System [StaticInitPriority(100)] class Runtime { - const int32 cVersion = 9; + const int32 cVersion = 10; [CRepr, AlwaysInclude] struct BfDebugMessageData @@ -116,6 +116,7 @@ namespace System function bool (Object thread) mThread_IsAutoDelete; function void (Object thread) mThread_AutoDelete; function int32 (Object thread) mThread_GetMaxStackSize; + function void () mThread_Exiting; function void () mGC_MarkAllStaticMembers; function bool () mGC_CallRootCallbacks; function void () mGC_Shutdown; diff --git a/IDE/mintest/minlib/src/System/Threading/Thread.bf b/IDE/mintest/minlib/src/System/Threading/Thread.bf index 08ed8546..b4c49b6f 100644 --- a/IDE/mintest/minlib/src/System/Threading/Thread.bf +++ b/IDE/mintest/minlib/src/System/Threading/Thread.bf @@ -78,6 +78,11 @@ namespace System.Threading } } + static void Thread_Exiting() + { + + } + public static this() { var cb = ref Runtime.BfRtCallbacks.[Friend]sCallbacks; @@ -90,6 +95,7 @@ namespace System.Threading cb.[Friend]mThread_IsAutoDelete = => Thread_IsAutoDelete; cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete; cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize; + cb.[Friend]mThread_Exiting = => Thread_Exiting; } } @@ -280,9 +286,10 @@ namespace System.Threading } } - extern int32 GetThreadId(); + [CallingConvention(.Cdecl)] + extern int GetThreadId(); - public int32 Id + public int Id { get { diff --git a/IDE/mintest/src/main.bf b/IDE/mintest/src/main.bf index 24d0505d..7156c5e5 100644 --- a/IDE/mintest/src/main.bf +++ b/IDE/mintest/src/main.bf @@ -21,6 +21,11 @@ namespace Hey.Dude.Bro } } + struct Color + { + public float r, g, b, a; + } + class TestClass { /*static void TestFunc() @@ -37,8 +42,27 @@ namespace Hey.Dude.Bro }*/ + //private const uint16[] DebugIndexes = scope uint16[](0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7); + + + + [Import(@"C:\Beef\BeefTools\TestDLL\x64\Debug\TestDLL.dll"), LinkName("Test2")] + public static extern void Test2(int32 a, int32 b, int32 c, int32 d, function Color(int32 a, int32 b) func); + + public static Color GetColor(int32 a, int32 b) + { + Color c; + c.r = 1.2f; + c.g = 2.3f; + c.b = 3.4f; + c.a = 4.5f; + return c; + } + public static int Main(String[] args) { + Test2(1, 2, 3, 4, => GetColor); + //Blurg.Hey(); return 1; } diff --git a/IDE/src/BeefConfig.bf b/IDE/src/BeefConfig.bf index 361c1757..bdb1e1fc 100644 --- a/IDE/src/BeefConfig.bf +++ b/IDE/src/BeefConfig.bf @@ -13,6 +13,7 @@ namespace IDE public class RegistryEntry { public String mProjName ~ delete _; + public Project.TargetType mTargetType; public SemVer mVersion ~ delete _; public VerSpec mLocation ~ _.Dispose(); public ConfigFile mConfigFile; @@ -51,6 +52,29 @@ namespace IDE using (mMonitor.Enter()) entry.mProjName.Set(projName); } + + if (sd.Contains("StartupObject")) + entry.mTargetType = .BeefConsoleApplication; + else + entry.mTargetType = .BeefLib; + + var targetTypeName = scope String(); + sd.GetString("TargetType", targetTypeName); + + if (!targetTypeName.IsEmpty) + { + switch (targetTypeName) + { // Handle Legacy names first + case "BeefWindowsApplication": + entry.mTargetType = .BeefGUIApplication; + case "C_WindowsApplication": + entry.mTargetType = .C_GUIApplication; + case "BeefDynLib": + entry.mTargetType = .BeefLib; + default: + entry.mTargetType = sd.GetEnum("TargetType", entry.mTargetType); + } + } } } } diff --git a/IDE/src/BuildContext.bf b/IDE/src/BuildContext.bf index 02573971..20ed2542 100644 --- a/IDE/src/BuildContext.bf +++ b/IDE/src/BuildContext.bf @@ -627,15 +627,7 @@ namespace IDE return false; } - String compilerExePath = scope String(); -#if BF_PLATFORM_WINDOWS - String llvmDir = scope String(IDEApp.sApp.mInstallDir); - IDEUtils.FixFilePath(llvmDir); - llvmDir.Append("llvm/"); -#else - String llvmDir = ""; -#endif if (gApp.mSettings.mEmscriptenPath.IsEmpty) { gApp.OutputErrorLine("Emscripten path not configured. Check Wasm configuration in File\\Preferences\\Settings."); diff --git a/IDE/src/Commands.bf b/IDE/src/Commands.bf index f493b56e..f4c5ca86 100644 --- a/IDE/src/Commands.bf +++ b/IDE/src/Commands.bf @@ -90,10 +90,11 @@ namespace IDE { if (mParent == null) return; + int startIdx = strBuffer.Length; mParent.ToString(strBuffer); if (mBoundKeyState != null) { - if (!strBuffer.IsEmpty) + if (strBuffer.Length > startIdx) strBuffer.Append(", "); mBoundKeyState.ToString(strBuffer); } diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 214300ce..525318a7 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -156,7 +156,7 @@ namespace IDE.Compiler static extern int32 BfCompiler_GetEmitSourceVersion(void* bfCompiler, char8* fileName); [CallingConvention(.Stdcall), CLink] - static extern char8* BfCompiler_GetEmitLocation(void* bfCompiler, char8* typeName, int32 line, out int32 embedLine, out int32 embedLineChar); + static extern char8* BfCompiler_GetEmitLocation(void* bfCompiler, char8* typeName, int32 line, out int32 embedLine, out int32 embedLineChar, out uint64 hash); [CallingConvention(.Stdcall), CLink] static extern void BfCompiler_WriteEmitData(void* bfCompiler, char8* filePath, void* bfProject); @@ -362,11 +362,11 @@ namespace IDE.Compiler return BfCompiler_GetEmitSourceVersion(mNativeBfCompiler, fileName.ToScopeCStr!()); } - public void GetEmitLocation(StringView typeName, int line, String outFilePath, out int embedLine, out int embedLineChar) + public void GetEmitLocation(StringView typeName, int line, String outFilePath, out int embedLine, out int embedLineChar, out uint64 hash) { int32 embedLine32; int32 embedLineChar32; - outFilePath.Append(BfCompiler_GetEmitLocation(mNativeBfCompiler, typeName.ToScopeCStr!(), (.)line, out embedLine32, out embedLineChar32)); + outFilePath.Append(BfCompiler_GetEmitLocation(mNativeBfCompiler, typeName.ToScopeCStr!(), (.)line, out embedLine32, out embedLineChar32, out hash)); embedLine = embedLine32; embedLineChar = embedLineChar32; } @@ -603,6 +603,8 @@ namespace IDE.Compiler UpdateRebuildFileWatches(); mBfSystem.RemoveOldParsers(); mBfSystem.RemoveOldData(); + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) + QueueRefreshViewCommand(.Collapse); } if (command is ResolveAllCommand) diff --git a/IDE/src/Compiler/BfSystem.bf b/IDE/src/Compiler/BfSystem.bf index 9fb64746..60cbcd38 100644 --- a/IDE/src/Compiler/BfSystem.bf +++ b/IDE/src/Compiler/BfSystem.bf @@ -239,6 +239,16 @@ namespace IDE.Compiler } } + public BfParser GetParser(ProjectSource projectSource) + { + using (mMonitor.Enter()) + { + BfParser parser; + mParserMap.TryGetValue(projectSource, out parser); + return parser; + } + } + public BfParser CreateNewParserRevision(BfParser prevParser) { using (mMonitor.Enter()) diff --git a/IDE/src/FileRecovery.bf b/IDE/src/FileRecovery.bf index 1cbc6ce4..97cefb35 100644 --- a/IDE/src/FileRecovery.bf +++ b/IDE/src/FileRecovery.bf @@ -57,6 +57,14 @@ namespace IDE String mWorkspaceDir = new String() ~ delete _; bool mWantWorkspaceCleanup; public bool mDisabled; + Dictionary> mDB = new .() ~ DeleteDictionaryAndKeysAndValues!(_); + public bool mDBDirty; + public String mDBWorkspaceDir = new String() ~ delete _; + + public this() + { + + } public ~this() { @@ -84,6 +92,26 @@ namespace IDE bool wantWorkspaceCleanup = false; using (mMonitor.Enter()) { + if (mDBDirty) + { + String recoverPath = scope String(); + recoverPath.Append(mWorkspaceDir); + recoverPath.Append("/recovery/db.bin"); + + FileStream fs = scope .(); + if (fs.Create(recoverPath) case .Ok) + { + fs.Write((uint32)0xBEEF0701); + for (var kv in mDB) + { + fs.WriteStrSized32(kv.key).IgnoreError(); + fs.Write((int32)kv.value.Count); + fs.TryWrite(kv.value).IgnoreError(); + } + } + mDBDirty = false; + } + for (var entry in mFileSet) { if (entry.mRecoveryFileName == null) @@ -250,6 +278,104 @@ namespace IDE } } + public void CheckDB() + { + if (mDBWorkspaceDir == gApp.mWorkspace.mDir) + return; + + using (mMonitor.Enter()) + { + for (var kv in mDB) + { + delete kv.key; + delete kv.value; + } + mDB.Clear(); + + mDBWorkspaceDir.Set(gApp.mWorkspace.mDir); + if (mDBWorkspaceDir.IsEmpty) + return; + + String recoverPath = scope String(); + recoverPath.Append(mDBWorkspaceDir); + recoverPath.Append("/recovery/db.bin"); + + FileStream fs = scope .(); + if (fs.Open(recoverPath) case .Ok) + { + if (fs.Read() == 0xBEEF0701) + { + String filePath = scope .(); + while (true) + { + filePath.Clear(); + if (fs.ReadStrSized32(filePath) case .Err) + break; + if (filePath.IsEmpty) + break; + + int32 dataSize = fs.Read(); + List list = new List(); + mDB[new String(filePath)] = list; + + list.Resize(dataSize); + if (fs.TryRead(.(list.Ptr, dataSize)) case .Err) + break; + } + } + } + } + } + + public void SetDB(StringView key, Span data) + { + using (mMonitor.Enter()) + { + CheckDB(); + + if (mDB.TryAddAlt(key, var keyPtr, var valuePtr)) + { + *keyPtr = new .(key); + *valuePtr = new .(); + } + (*valuePtr).Clear(); + (*valuePtr).AddRange(data); + mDBDirty = true; + } + } + + public bool GetDB(StringView key, List data) + { + using (mMonitor.Enter()) + { + CheckDB(); + + if (mDB.TryGetAlt(key, var matchKey, var value)) + { + data.AddRange(value); + return true; + } + return false; + } + } + + public bool DeleteDB(StringView key) + { + using (mMonitor.Enter()) + { + CheckDB(); + + if (mDB.GetAndRemoveAlt(key) case .Ok((var mapKey, var value))) + { + mDBDirty = true; + delete mapKey; + delete value; + return true; + } + return false; + } + } + public void Update() { if (mProcessingEvent != null) @@ -261,7 +387,7 @@ namespace IDE using (mMonitor.Enter()) { - if ((!mDirty) && (!mWantWorkspaceCleanup)) + if ((!mDirty) && (!mDBDirty) && (!mWantWorkspaceCleanup)) return; } diff --git a/IDE/src/FileWatcher.bf b/IDE/src/FileWatcher.bf index 63401fce..39b2f34a 100644 --- a/IDE/src/FileWatcher.bf +++ b/IDE/src/FileWatcher.bf @@ -95,6 +95,16 @@ namespace IDE FileChanged(starPath, null, .Changed); } + if ((isDirectory) && (changeType == .Renamed)) + { + // On Windows, renaming a directory with only case changes will result in a remove before a rename + var dirName = scope String(); + Path.GetDirectoryPath(newPath.Substring(0, newPath.Length - 1), dirName); + dirName.Append(Path.DirectorySeparatorChar); + + FileChanged(dirName, newPath, .DirectoryCreated); + } + var newPath; if (isDirectory) { diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index b19656d1..7e70fd23 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -119,7 +119,7 @@ namespace IDE public class IDEApp : BFApp { public static String sRTVersionStr = "042"; - public const String cVersion = "0.43.3"; + public const String cVersion = "0.43.4"; #if BF_PLATFORM_WINDOWS public static readonly String sPlatform64Name = "Win64"; @@ -1475,6 +1475,14 @@ namespace IDE return true; } + public void SetEmbedCompiler(Settings.EditorSettings.CompilerKind emitCompiler) + { + gApp.mSettings.mEditorSettings.mEmitCompiler = emitCompiler; + mBfResolveCompiler?.QueueRefreshViewCommand(.Collapse); + if (emitCompiler == .Resolve) + mBfResolveCompiler?.QueueRefreshViewCommand(.FullRefresh); + } + public Result LoadTextFile(String fileName, String outBuffer, bool autoRetry = true, delegate void() onPreFilter = null) { if (mWorkspace.IsSingleFileWorkspace) @@ -1490,9 +1498,23 @@ namespace IDE if (fileName.StartsWith("$Emit$")) { - BfCompiler compiler = mBfResolveCompiler; + String useFileName = fileName; + + BfCompiler compiler = (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? mBfResolveCompiler : mBfBuildCompiler; + + if (useFileName.StartsWith("$Emit$Build$")) + { + useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Build$".Length)}"; + compiler = mBfBuildCompiler; + } + else if (useFileName.StartsWith("$Emit$Resolve$")) + { + useFileName = scope:: $"$Emit${useFileName.Substring("$Emit$Resolve$".Length)}"; + compiler = mBfResolveCompiler; + } + if (!compiler.IsPerformingBackgroundOperation()) - compiler.GetEmitSource(fileName, outBuffer); + compiler.GetEmitSource(useFileName, outBuffer); if (onPreFilter != null) onPreFilter(); @@ -2299,7 +2321,7 @@ namespace IDE AddNewProjectToWorkspace(project); project.FinishCreate(); - mProjectPanel.InitProject(project); + mProjectPanel.InitProject(project, mProjectPanel.GetSelectedWorkspaceFolder()); mProjectPanel.Sort(); mWorkspace.FixOptions(); mWorkspace.mHasChanged = true; @@ -2693,7 +2715,7 @@ namespace IDE AddProjectToWorkspace(project, false); if (addToUI) - mProjectPanel.InitProject(project); + mProjectPanel.InitProject(project, null); } } if (!hadLoad) @@ -2977,6 +2999,8 @@ namespace IDE { using (mBeefConfig.mRegistry.mMonitor.Enter()) { + BeefConfig.RegistryEntry matchedEntry = null; + for (int regEntryIdx = mBeefConfig.mRegistry.mEntries.Count - 1; regEntryIdx >= 0; regEntryIdx--) { var regEntry = mBeefConfig.mRegistry.mEntries[regEntryIdx]; @@ -2986,11 +3010,19 @@ namespace IDE if (regEntry.mProjName == projectName) { - useVerSpec = regEntry.mLocation; - verConfigDir = regEntry.mConfigFile.mConfigDir; - break FindLoop; + // Prioritize a lib file over a non-lib + if ((matchedEntry == null) || + ((!matchedEntry.mTargetType.IsLib) && (regEntry.mTargetType.IsLib))) + matchedEntry = regEntry; } } + + if (matchedEntry != null) + { + useVerSpec = matchedEntry.mLocation; + verConfigDir = matchedEntry.mConfigFile.mConfigDir; + break FindLoop; + } } mBeefConfig.mRegistry.WaitFor(); } @@ -5429,6 +5461,20 @@ namespace IDE sysMenu.Modify(null, null, null, true, checkVal ? 1 : 0); } + public Menu AddMenuItem(Menu menu, StringView label, StringView command = default) + { + var command; + if (command.IsEmpty) + command = label; + String labelStr = scope String(label); + if (mCommands.mCommandMap.TryGetAlt(command, var matchKey, var ideCommand)) + { + labelStr.Append("|"); + ideCommand.ToString(labelStr); + } + return menu.AddItem(labelStr); + } + public bool AreTestsRunning() { return (mTestManager != null); @@ -5683,6 +5729,17 @@ namespace IDE AddMenuItem(bookmarkMenu, "&Previous Bookmark", "Bookmark Prev"); AddMenuItem(bookmarkMenu, "&Clear Bookmarks", "Bookmark Clear"); + var comptimeMenu = subMenu.AddMenuItem("Comptime"); + var emitViewCompiler = comptimeMenu.AddMenuItem("Emit View Compiler"); + var subItem = emitViewCompiler.AddMenuItem("Resolve", null, + new (menu) => { SetEmbedCompiler(.Resolve); } , + new (menu) => { menu.SetCheckState((mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? 1 : 0); }, + null, true, (mSettings.mEditorSettings.mEmitCompiler == .Resolve) ? 1 : 0); + subItem = emitViewCompiler.AddMenuItem("Build", null, + new (menu) => { SetEmbedCompiler(.Build); } , + new (menu) => { menu.SetCheckState((mSettings.mEditorSettings.mEmitCompiler == .Build) ? 1 : 0); }, + null, true, (mSettings.mEditorSettings.mEmitCompiler == .Build) ? 1 : 0); + var advancedEditMenu = subMenu.AddMenuItem("Advanced"); AddMenuItem(advancedEditMenu, "Duplicate Line", "Duplicate Line"); AddMenuItem(advancedEditMenu, "Move Line Up", "Move Line Up"); @@ -6285,6 +6342,11 @@ namespace IDE let process = scope SpawnedProcess(); process.Start(procInfo).IgnoreError(); }); + item = menu.AddItem("Show in Workspace Panel"); + item.mOnMenuItemSelected.Add(new (menu) => + { + sourceViewPanel.SyncWithWorkspacePanel(); + }); item = menu.AddItem("Close"); item.mOnMenuItemSelected.Add(new (menu) => { @@ -7155,10 +7217,11 @@ namespace IDE public SourceViewPanel ShowSourceFileLocation(String filePath, int showHotIdx, int refHotIdx, int line, int column, LocatorType hilitePosition, bool showTemp = false) { + var useFilePath = filePath; + if (filePath.StartsWith("$Emit$")) { - var compiler = mBfResolveCompiler; - if (compiler.IsPerformingBackgroundOperation()) + if ((mBfBuildCompiler.IsPerformingBackgroundOperation()) || (mBfResolveCompiler.IsPerformingBackgroundOperation())) { DeleteAndNullify!(mDeferredShowSource); mDeferredShowSource = new DeferredShowSource() @@ -7174,18 +7237,76 @@ namespace IDE return null; } - var itr = filePath.Split('$'); - itr.GetNext(); - itr.GetNext(); - var typeName = itr.GetNext().Value; + String embedFilePath; + bool isViewValid = true; + StringView typeName; + int embedLine; + int embedLineChar; - //var compiler = (kindStr == "Emit") ? mBfBuildCompiler : mBfResolveCompiler; - - compiler.mBfSystem.Lock(0); - var embedFilePath = compiler.GetEmitLocation(typeName, line, .. scope .(), var embedLine, var embedLineChar); - compiler.mBfSystem.Unlock(); + if (filePath.StartsWith("$Emit$Resolve$")) + { + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) + { + var itr = filePath.Split('$'); + itr.GetNext(); + itr.GetNext(); + itr.GetNext(); + typeName = itr.GetNext().Value; + + mBfResolveCompiler.mBfSystem.Lock(0); + embedFilePath = mBfResolveCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash); + mBfResolveCompiler.mBfSystem.Unlock(); + + useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Resolve$".Length)}"; + } + else + isViewValid = false; + } + else if (filePath.StartsWith("$Emit$Build$")) + { + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) + { + var itr = filePath.Split('$'); + itr.GetNext(); + itr.GetNext(); + itr.GetNext(); + typeName = itr.GetNext().Value; + + mBfBuildCompiler.mBfSystem.Lock(0); + embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash); + mBfBuildCompiler.mBfSystem.Unlock(); + + useFilePath = scope:: $"$Emit${useFilePath.Substring("$Emit$Build$".Length)}"; + } + else + isViewValid = false; + } + else + { + var itr = filePath.Split('$'); + itr.GetNext(); + itr.GetNext(); + typeName = itr.GetNext().Value; - if (!embedFilePath.IsEmpty) + mBfBuildCompiler.mBfSystem.Lock(0); + embedFilePath = mBfBuildCompiler.GetEmitLocation(typeName, line, .. scope:: .(), out embedLine, out embedLineChar, var embedHash); + mBfBuildCompiler.mBfSystem.Unlock(); + + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) + { + mBfResolveCompiler.mBfSystem.Lock(0); + mBfResolveCompiler.GetEmitLocation(typeName, line, scope .(), var resolveLine, var resolveLineChar, var resolveHash); + mBfResolveCompiler.mBfSystem.Unlock(); + + if ((resolveLine != embedLine) || (resolveLineChar != embedLineChar) || (embedHash != resolveHash)) + { + isViewValid = false; + useFilePath = scope:: $"$Emit$Build${useFilePath.Substring("$Emit$".Length)}"; + } + } + } + + if ((isViewValid) && (!embedFilePath.IsEmpty)) { var sourceViewPanel = ShowSourceFile(scope .(embedFilePath), null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting).panel; if (sourceViewPanel == null) @@ -7201,11 +7322,7 @@ namespace IDE emitShowData.mColumn = (.)column; DeleteAndNullify!(sourceViewPanel.[Friend]mQueuedEmitShowData); sourceViewPanel.[Friend]mQueuedEmitShowData = emitShowData; - - //sourceViewPanel.ShowHotFileIdx(showHotIdx); sourceViewPanel.ShowFileLocation(refHotIdx, embedLine, embedLineChar, .None); - //sourceViewPanel.QueueFullRefresh(false); - //sourceViewPanel.mBackgroundDelay = 1; // Don't immediately perform the full classify if (typeName.Contains('<')) { @@ -7220,7 +7337,7 @@ namespace IDE } } - var (sourceViewPanel, tabButton) = ShowSourceFile(filePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting); + var (sourceViewPanel, tabButton) = ShowSourceFile(useFilePath, null, showTemp ? SourceShowType.Temp : SourceShowType.ShowExisting); if (sourceViewPanel == null) return null; if (((filePath.StartsWith("$")) && (var svTabButton = tabButton as SourceViewTabButton))) @@ -14259,7 +14376,8 @@ namespace IDE if (IDEApp.sApp.mSpellChecker != null) IDEApp.sApp.mSpellChecker.CheckThreadDone(); - if ((mDeferredShowSource != null) && (mBfResolveCompiler?.IsPerformingBackgroundOperation() == false)) + if ((mDeferredShowSource != null) && (!mBfBuildCompiler.IsPerformingBackgroundOperation()) && + (mBfResolveCompiler?.IsPerformingBackgroundOperation() != true)) { var deferredShowSource = mDeferredShowSource; mDeferredShowSource = null; diff --git a/IDE/src/IDEUtils.bf b/IDE/src/IDEUtils.bf index f39761fc..1b2c41e8 100644 --- a/IDE/src/IDEUtils.bf +++ b/IDE/src/IDEUtils.bf @@ -636,6 +636,38 @@ namespace IDE label.Append('\x02'); } } + + static String sHexUpperChars = "0123456789ABCDEF"; + public static void URLEncode(StringView inStr, String outStr) + { + for (var c in inStr) + { + if ((c.IsLetterOrDigit) || (c == '-') || (c == '_') || (c == '.') || (c == '~') || (c == '/')) + { + outStr.Append(c); + } + else + { + outStr.Append('%'); + outStr.Append(sHexUpperChars[(.)c>>4]); + outStr.Append(sHexUpperChars[(.)c&0xF]); + } + } + } + + public static void URLDecode(StringView inStr, String outStr) + { + for (int i < inStr.Length) + { + char8 c = inStr[i]; + if ((c == '%') && (i < inStr.Length-2)) + { + c = (.)int32.Parse(inStr.Substring(i+1, 2), .HexNumber).GetValueOrDefault(); + i += 2; + } + outStr.Append(c); + } + } } } diff --git a/IDE/src/Project.bf b/IDE/src/Project.bf index 9ef7c60f..f7a630c7 100644 --- a/IDE/src/Project.bf +++ b/IDE/src/Project.bf @@ -979,6 +979,20 @@ namespace IDE } } } + + public bool IsLib + { + get + { + switch (this) + { + case BeefLib: + return true; + default: + return false; + } + } + } } public class WindowsOptions diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index a15e00f3..5323cfb1 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -304,6 +304,7 @@ namespace IDE public Color mWorkspaceFailedText = 0xFFE04040; public Color mWorkspaceManualIncludeText = 0xFFE0E0FF; public Color mWorkspaceIgnoredText = 0xFF909090; + public Color mWorkspaceCutText = 0xFFC0B0B0; public Color mCode = 0xFFFFFFFF; public Color mKeyword = 0xFFE1AE9A; @@ -628,6 +629,12 @@ namespace IDE Spaces } + public enum CompilerKind + { + Resolve, + Build + } + public List mFonts = new .() ~ DeleteContainerAndItems!(_); public float mFontSize = 12; public AutoCompleteShowKind mAutoCompleteShowKind = .PanelIfVisible; @@ -641,6 +648,7 @@ namespace IDE public bool mHiliteCurrentLine = false; public bool mLockEditing; public LockWhileDebuggingKind mLockEditingWhenDebugging = .WhenNotHotSwappable;// Only applicable for + public CompilerKind mEmitCompiler; // non-Beef sources public bool mPerforceAutoCheckout = true; public bool mSpellCheckEnabled = true; @@ -674,6 +682,7 @@ namespace IDE sd.Add("HiliteCurrentLine", mHiliteCurrentLine); sd.Add("LockEditing", mLockEditing); sd.Add("LockEditingWhenDebugging", mLockEditingWhenDebugging); + sd.Add("EmitCompiler", mEmitCompiler); sd.Add("PerforceAutoCheckout", mPerforceAutoCheckout); sd.Add("SpellCheckEnabled", mSpellCheckEnabled); sd.Add("ShowLineNumbers", mShowLineNumbers); @@ -710,6 +719,7 @@ namespace IDE sd.Get("HiliteCurrentLine", ref mHiliteCurrentLine); sd.Get("LockEditing", ref mLockEditing); sd.Get("LockEditingWhenDebugging", ref mLockEditingWhenDebugging); + sd.Get("EmitCompiler", ref mEmitCompiler); sd.Get("PerforceAutoCheckout", ref mPerforceAutoCheckout); sd.Get("SpellCheckEnabled", ref mSpellCheckEnabled); sd.Get("ShowLineNumbers", ref mShowLineNumbers); @@ -944,7 +954,7 @@ namespace IDE curCmdMap = (*valuePtr) as CommandMap; if (curCmdMap == null) { - curCmdMap.FailValues.Add(ideCommand); + gApp.OutputLineSmart("ERROR: The same key is bound for '{0}' and as part of a key chord", entry.mCommand); break; } } diff --git a/IDE/src/ui/AutoComplete.bf b/IDE/src/ui/AutoComplete.bf index 1c4122fc..aa118a9f 100644 --- a/IDE/src/ui/AutoComplete.bf +++ b/IDE/src/ui/AutoComplete.bf @@ -1017,6 +1017,72 @@ namespace IDE.ui if (cursorSection >= textSections.Count - 1) cursorSection = textSections.Count - 2; + if ((cursorSection >= 0) && (cursorSection < mAutoComplete.mInvokeSrcPositions.Count)) + { + var argText = mAutoComplete.mTargetEditWidget.mEditWidgetContent.ExtractString(mAutoComplete.mInvokeSrcPositions[cursorSection - 1], + mAutoComplete.mInvokeSrcPositions[cursorSection] - mAutoComplete.mInvokeSrcPositions[cursorSection - 1], .. scope .()); + + int colonPos = argText.IndexOf(':'); + + if (colonPos != -1) + { + do + { + bool foundSep = false; + int nameStart = -1; + for (int i = colonPos - 1; i >= 0; i--) + { + char8 c = argText[i]; + if (nameStart == -1) + { + if ((c != '_') && (!c.IsLetterOrDigit)) + nameStart = i + 1; + } + else + { + if (!c.IsWhiteSpace) + { + if ((!foundSep) && + ((c == ',') || (c == '('))) + foundSep = true; + else + break; + } + } + } + + if (nameStart == -1) + break; + + var argParamName = argText.Substring(nameStart, colonPos - nameStart); + for (int checkSectionIdx = 1; checkSectionIdx < textSections.Count; checkSectionIdx++) + { + var sectionStr = textSections[checkSectionIdx]; + + var checkParamName = sectionStr; + if (checkParamName.EndsWith(',')) + checkParamName.RemoveFromEnd(1); + + for (int checkIdx = checkParamName.Length - 1; checkIdx >= 0; checkIdx--) + { + char8 c = checkParamName[checkIdx]; + if (c.IsWhiteSpace) + { + checkParamName.RemoveFromStart(checkIdx + 1); + break; + } + } + + if (checkParamName == argParamName) + { + cursorSection = checkSectionIdx; + break; + } + } + } + } + } + float paramX = 0; for (int sectionIdx = 0; sectionIdx < textSections.Count; sectionIdx++) { diff --git a/IDE/src/ui/FindResultsPanel.bf b/IDE/src/ui/FindResultsPanel.bf index 02eedf32..ea710597 100644 --- a/IDE/src/ui/FindResultsPanel.bf +++ b/IDE/src/ui/FindResultsPanel.bf @@ -552,7 +552,7 @@ namespace IDE.ui return base.Deserialize(data); } - public void QueueLine(String text) + public void AddPendingLine(String text) { mCurLineNum++; using (mMonitor.Enter()) @@ -591,7 +591,17 @@ namespace IDE.ui String outStr = scope String(); outStr.AppendF("{0}({1}):{2}", fileEditData.mFilePath, line + 1, lineStr); - gApp.mFindResultsPanel.QueueLine(outStr); + gApp.mFindResultsPanel.AddPendingLine(outStr); + } + + public void QueueLine(String text) + { + using (mMonitor.Enter()) + { + QueuedEntry entry = new .(); + entry.mText = new .(text); + mQueuedEntries.Add(entry); + } } public void QueueLine(String fileName, int32 line, int32 column, String text) @@ -641,7 +651,10 @@ namespace IDE.ui while (!mQueuedEntries.IsEmpty) { var entry = mQueuedEntries.PopFront(); - QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText); + if (entry.mFileName == null) + AddPendingLine(entry.mText); + else + QueueLine(gApp.GetEditData(entry.mFileName, true, false), entry.mLine, entry.mColumn, entry.mText); delete entry; } diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf index 07762cad..1b51eeb7 100644 --- a/IDE/src/ui/HoverWatch.bf +++ b/IDE/src/ui/HoverWatch.bf @@ -406,14 +406,12 @@ namespace IDE.ui void HandleMouseWheel(MouseEvent evt) { - if (mChildWidgets.Count == 0) - return; - - var lastListView = mChildWidgets[mChildWidgets.Count - 1] as HoverListView; - if ((lastListView != null) && (lastListView.mVertScrollbar != null)) - return; - if (mListViews.Count > 1) + { + return; + } + + if (evt.mSender != mWidgetWindow) { var widgetWindow = evt.mSender as BFWindow; while (widgetWindow != null) @@ -423,6 +421,7 @@ namespace IDE.ui widgetWindow = widgetWindow.mParent; } } + EditWidget editWidget = mEditWidget; if (var sourceViewPanel = mTextPanel as SourceViewPanel) editWidget = sourceViewPanel.mEditWidget; diff --git a/IDE/src/ui/InstalledProjectDialog.bf b/IDE/src/ui/InstalledProjectDialog.bf index 88dbf864..832e6627 100644 --- a/IDE/src/ui/InstalledProjectDialog.bf +++ b/IDE/src/ui/InstalledProjectDialog.bf @@ -16,9 +16,11 @@ namespace IDE.ui public String mName ~ delete _; public String mPath ~ delete _; public VerSpecRecord mVersion; + public Project.TargetType mTargetType; } protected IDEListView mProjectList; + DarkComboBox mKindCombo; EditWidget mEditWidget; bool mFilterChanged; List mInstalledProjectList = new .() ~ DeleteContainerAndItems!(_); @@ -58,6 +60,21 @@ namespace IDE.ui mEditWidget.mOnKeyDown.Add(new => EditKeyDownHandler); mEditWidget.mOnContentChanged.Add(new (evt) => { mFilterChanged = true; }); + mKindCombo = new DarkComboBox(); + mKindCombo.Label = "Libraries"; + mKindCombo.mPopulateMenuAction.Add(new (menu) => + { + for (var kind in String[?]("All", "Libraries")) + { + menu.AddItem(kind).mOnMenuItemSelected.Add(new (menu) => + { + mFilterChanged = true; + mKindCombo.Label = kind; + }); + } + }); + AddWidget(mKindCombo); + FindProjects(); } @@ -78,6 +95,7 @@ namespace IDE.ui installedProject.mPath.Append("BeefProj.toml"); default: } + installedProject.mTargetType = registryEntry.mTargetType; mInstalledProjectList.Add(installedProject); } } @@ -128,9 +146,14 @@ namespace IDE.ui mEditWidget.GetText(filterString); filterString.Trim(); + bool onlyLibs = mKindCombo.Label == "Libraries"; + mFilteredList.Clear(); for (var installedProject in mInstalledProjectList) { + if ((onlyLibs) && (!installedProject.mTargetType.IsLib)) + continue; + if ((!filterString.IsEmpty) && (installedProject.mName.IndexOf(filterString, true) == -1)) continue; @@ -138,7 +161,7 @@ namespace IDE.ui listViewItem.Label = installedProject.mName; var subListViewItem = listViewItem.CreateSubItem(1); - subListViewItem.Label = installedProject.mPath; + subListViewItem.Label = Path.GetDirectoryPath(installedProject.mPath, .. scope .()); mFilteredList.Add(installedProject); } @@ -180,7 +203,7 @@ namespace IDE.ui VerSpec verSpec = .SemVer(new .("*")); defer verSpec.Dispose(); - let project = gApp.mProjectPanel.ImportProject(entry.mPath, verSpec); + let project = gApp.mProjectPanel.ImportProject(entry.mPath, null, verSpec); if (project == null) { return; @@ -223,6 +246,7 @@ namespace IDE.ui float insetSize = GS!(6); mProjectList.Resize(insetSize, insetSize, mWidth - insetSize - insetSize, mHeight - GS!(66)); mEditWidget.Resize(insetSize, mProjectList.mY + mProjectList.mHeight + insetSize, mWidth - insetSize - insetSize, GS!(22)); + mKindCombo.Resize(insetSize, mHeight - GS!(26), Math.Min(GS!(160), mDefaultButton.mX - GS!(6)), GS!(26)); } public override void CalcSize() diff --git a/IDE/src/ui/ProjectPanel.bf b/IDE/src/ui/ProjectPanel.bf index 500fc926..1ce74655 100644 --- a/IDE/src/ui/ProjectPanel.bf +++ b/IDE/src/ui/ProjectPanel.bf @@ -61,6 +61,17 @@ namespace IDE.ui else if (projectItem.mIncludeKind == .Ignore) color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceIgnoredText); + if (let projectFileItem = projectItem as ProjectFileItem) + { + if (projectPanel.mClipboardCutQueued != null) + { + var path = projectFileItem.mProject.GetProjectFullPath(projectFileItem.mPath, .. scope .()); + IDEUtils.MakeComparableFilePath(path); + if (projectPanel.mClipboardCutQueued.Contains(path)) + color = Color.Mult(color, gApp.mSettings.mUISettings.mColors.mWorkspaceCutText); + } + } + if (let projectSource = projectItem as ProjectSource) { if (projectSource.mLoadFailed) @@ -146,6 +157,7 @@ namespace IDE.ui public bool mShowIgnored = true; public bool mSortDirty; public bool mWantsRehup; + public HashSet mClipboardCutQueued ~ DeleteContainerAndItems!(_); public this() { @@ -518,10 +530,22 @@ namespace IDE.ui } } - public void InitProject(Project project) - { + public void InitProject(Project project, WorkspaceFolder workspaceFolder) + { var projectListViewItem = InitProjectItem(project.mRootFolder); projectListViewItem.mRefObject = project; + if (workspaceFolder != null) + { + let root = mListView.GetRoot(); + root.RemoveChildItem(projectListViewItem, false); + workspaceFolder.mListView.MakeParent(); + workspaceFolder.mListView.AddChild(projectListViewItem); + workspaceFolder.mListView.Open(true); + mProjectToWorkspaceFolderMap[project.mRootFolder] = workspaceFolder; + + workspaceFolder.mProjects.Add(project); + QueueSortItem(workspaceFolder.mListView); + } } public void RebuildUI() @@ -564,7 +588,7 @@ namespace IDE.ui mProjectToWorkspaceFolderMap.Clear(); for (var project in IDEApp.sApp.mWorkspace.mProjects) - InitProject(project); + InitProject(project, null); let root = mListView.GetRoot(); @@ -1489,6 +1513,14 @@ namespace IDE.ui #endif } + public WorkspaceFolder GetSelectedWorkspaceFolder() + { + ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem(); + if (mListViewToWorkspaceFolderMap.TryGetValue(selectedItem, let folder)) + return folder; + return null; + } + ListViewItem GetSelectedParentItem() { ListViewItem selectedItem = mListView.GetRoot().FindFirstSelectedItem(); @@ -1764,33 +1796,59 @@ namespace IDE.ui let root = mListView.GetRoot(); List itemsToMove = scope .(); List foldersToDelete = scope .(); + root.WithSelectedItems(scope [&] (selectedItem) => { if (mListViewToWorkspaceFolderMap.GetValue(selectedItem) case .Ok(let folder)) { foldersToDelete.Add(folder); + mListViewToWorkspaceFolderMap.Remove(folder.mListView); selectedItem.WithItems(scope [&] (item) => { if (mListViewToProjectMap.GetValue(item) case .Ok(let project)) { if (project.mParentFolder == null) itemsToMove.Add(item); } + else if (mListViewToWorkspaceFolderMap.GetValue(item) case .Ok(let itemFolder)) + { + foldersToDelete.Add(itemFolder); + mListViewToWorkspaceFolderMap.Remove(itemFolder.mListView); + } }); } }); - - for (let projectListViewItem in itemsToMove) + + for (let listViewItem in itemsToMove) { - projectListViewItem.mParentItem.RemoveChildItem(projectListViewItem, false); - root.AddChildAtIndex(1, projectListViewItem); - if (mListViewToProjectMap.TryGetValue(projectListViewItem, let projectItem)) + listViewItem.mParentItem.RemoveChildItem(listViewItem, false); + root.AddChildAtIndex(1, listViewItem); + if (mListViewToProjectMap.TryGetValue(listViewItem, let projectItem)) mProjectToWorkspaceFolderMap.Remove(projectItem); } - for (let folder in foldersToDelete) + + bool HasDeletedParent(WorkspaceFolder folder) + { + WorkspaceFolder parent = folder; + repeat + { + parent = parent.mParent; + + if (foldersToDelete.Contains(parent)) + return true; + } + while (parent != null); + + return false; + } + + for (let folder in foldersToDelete) { - let folderItem = folder.mListView; - mListViewToWorkspaceFolderMap.Remove(folderItem); - folderItem.mParentItem.RemoveChildItem(folderItem); - gApp.mWorkspace.mWorkspaceFolders.Remove(folder); + if (!HasDeletedParent(folder)) + { + let folderItem = folder.mListView; + folderItem.mParentItem.RemoveChildItem(folderItem); + } + + gApp.mWorkspace.mWorkspaceFolders.Remove(folder); delete folder; } @@ -2004,6 +2062,307 @@ namespace IDE.ui } } + void CopyToClipboard() + { + String clipData = scope .(); + mListView.GetRoot().WithSelectedItems(scope (selectedItem) => + { + if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem)) + { + String path = scope .(); + if (var projectFileItem = sourceProjectItem as ProjectFileItem) + { + sourceProjectItem.mProject.GetProjectFullPath(projectFileItem.mPath, path); + path.Replace('\\', '/'); + + if (!clipData.IsEmpty) + clipData.Append("\n"); + clipData.Append("file:///"); + IDEUtils.URLEncode(path, clipData); + } + } + }); + if (!clipData.IsEmpty) + gApp.SetClipboardData("code/file-list", clipData.Ptr, (.)clipData.Length, true); + } + + void CutToClipboard() + { + DeleteContainerAndItems!(mClipboardCutQueued); + mClipboardCutQueued = null; + + CopyToClipboard(); + mClipboardCutQueued = new .(); + ValidateCutClipboard(); + } + + void ValidateCutClipboard() + { + if (mClipboardCutQueued == null) + return; + + void* data = gApp.GetClipboardData("code/file-list", var size, 0); + if (size == -1) + return; + + ClearAndDeleteItems!(mClipboardCutQueued); + + if (data != null) + { + StringView sv = .((.)data, size); + for (var line in sv.Split('\n')) + { + var uri = IDEUtils.URLDecode(line, .. scope .()); + if (uri.StartsWith("file:///")) + { + var srcPath = scope String()..Append(uri.Substring("file:///".Length)); + IDEUtils.MakeComparableFilePath(srcPath); + if (mClipboardCutQueued.TryAddAlt(srcPath, var entryPtr)) + *entryPtr = new String(srcPath); + } + } + } + + if (mClipboardCutQueued.IsEmpty) + DeleteAndNullify!(mClipboardCutQueued); + } + + void PasteFromClipboard() + { + ValidateCutClipboard(); + + var projectItem = GetSelectedProjectItem(); + var projectFolder = projectItem as ProjectFolder; + if (projectFolder == null) + projectFolder = projectItem.mParentFolder; + if (projectFolder == null) + return; + + var folderPath = projectFolder.GetFullImportPath(.. scope .()); + + void* data = gApp.GetClipboardData("code/file-list", var size); + if (data == null) + return; + + bool isCut = mClipboardCutQueued != null; + Dictionary sourceViewPanelMap = null; + List<(SourceViewPanel sourceViewPanel, String fromPath, String toPath)> moveList = null; + + HashSet foundDirs = scope .(); + + if (isCut) + { + sourceViewPanelMap = scope:: .(); + gApp.WithSourceViewPanels(scope (sourceViewPanel) => + { + if (sourceViewPanel.mFilePath === null) + return; + if (sourceViewPanel.mProjectSource == null) + return; + + var path = scope String()..Append(sourceViewPanel.mFilePath); + IDEUtils.MakeComparableFilePath(path); + if (sourceViewPanelMap.TryAdd(path, var keyPtr, var valuePtr)) + { + *keyPtr = new String(path); + *valuePtr = sourceViewPanel; + } + }); + + moveList = scope:: .(); + } + + defer + { + DeleteContainerAndItems!(mClipboardCutQueued); + mClipboardCutQueued = null; + + if (sourceViewPanelMap != null) + { + for (var key in sourceViewPanelMap.Keys) + delete key; + } + + if (moveList != null) + { + for (var val in moveList) + { + delete val.fromPath; + delete val.toPath; + } + } + + ClearAndDeleteItems!(foundDirs); + } + + void QueueDirectoryMove(StringView fromDir, StringView toDir) + { + var searchStr = scope String(); + searchStr.Append(fromDir); + searchStr.Append("/*"); + for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files)) + { + var fromChildPath = dirEntry.GetFilePath(.. scope .()); + + String toChildPath = scope String()..Append(toDir); + toChildPath.Append(Path.DirectorySeparatorChar); + dirEntry.GetFileName(toChildPath); + + if (dirEntry.IsDirectory) + { + QueueDirectoryMove(fromChildPath, toChildPath); + continue; + } + + var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(fromChildPath)); + if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel)) + { + moveList.Add((sourceViewPanel, new String(fromChildPath), new String(toChildPath))); + } + } + } + + Result CopyDirectory(StringView fromDir, StringView toDir) + { + if (Directory.CreateDirectory(toDir) case .Err) + { + gApp.Fail(scope $"Failed to create directory '{toDir}'"); + return .Err; + } + + var searchStr = scope String(); + searchStr.Append(fromDir); + searchStr.Append("/*"); + for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files)) + { + var fromChildPath = dirEntry.GetFilePath(.. scope .()); + + String toChildPath = scope String()..Append(toDir); + toChildPath.Append("/"); + dirEntry.GetFileName(toChildPath); + + if (dirEntry.IsDirectory) + { + CopyDirectory(fromChildPath, toChildPath); + continue; + } + + if (File.Copy(fromChildPath, toChildPath) case .Err) + { + gApp.Fail(scope $"Failed to copy '{fromChildPath}' to '{toChildPath}'"); + return .Err; + } + } + + return .Ok; + } + + StringView sv = .((.)data, size); + SrcLoop: for (var line in sv.Split('\n')) + { + var uri = IDEUtils.URLDecode(line, .. scope .()); + if (uri.StartsWith("file:///")) + { + var srcPath = scope String()..Append(uri.Substring("file:///".Length)); + + for (int i < 100) + { + var fileName = Path.GetFileNameWithoutExtension(srcPath, .. scope .()); + var destPath = scope String(); + destPath.Append(folderPath); + destPath.Append("/"); + destPath.Append(fileName); + if ((i > 0) && (!fileName.Contains(" - Copy"))) + destPath.Append(" - Copy"); + if (i > 1) + destPath.AppendF($" ({i})"); + Path.GetExtension(srcPath, destPath); + + IDEUtils.FixFilePath(srcPath); + IDEUtils.FixFilePath(destPath); + + if ((isCut) && (Path.Equals(srcPath, destPath))) + break; + + if (File.Exists(destPath)) + continue; + if (Directory.Exists(destPath)) + continue; + + if (Directory.Exists(srcPath)) + { + if (foundDirs.TryAdd(srcPath, var entryPtr)) + *entryPtr = new String(srcPath); + + if (isCut) + { + QueueDirectoryMove(srcPath, destPath); + + if (Directory.Move(srcPath, destPath) case .Err) + { + gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'"); + return; + } + + for (var val in moveList) + { + gApp.FileRenamed(val.sourceViewPanel.mProjectSource, val.fromPath, val.toPath); + } + } + else + { + if (CopyDirectory(srcPath, destPath) case .Err) + { + return; + } + } + } + else + { + var checkPath = scope String()..Append(srcPath); + while (true) + { + String checkDir = scope .(); + if (Path.GetDirectoryPath(checkPath, checkDir) case .Err) + break; + if (foundDirs.Contains(checkDir)) + { + // Already handled + continue SrcLoop; + } + checkPath.Set(checkDir); + } + + if (isCut) + { + if (File.Move(srcPath, destPath) case .Err) + { + gApp.Fail(scope $"Failed to move '{srcPath}' to '{destPath}'"); + return; + } + + var cmpPath = IDEUtils.MakeComparableFilePath(.. scope String()..Append(srcPath)); + if (sourceViewPanelMap.TryGet(cmpPath, var matchKey, var sourceViewPanel)) + { + gApp.FileRenamed(sourceViewPanel.mProjectSource, srcPath, destPath); + } + } + else + { + if (File.Copy(srcPath, destPath) case .Err) + { + gApp.Fail(scope $"Failed to copy '{srcPath}' to '{destPath}'"); + return; + } + } + } + + break; + } + } + } + } + public override void KeyDown(KeyCode keyCode, bool isRepeat) { mListView.KeyDown(keyCode, isRepeat); @@ -2015,8 +2374,25 @@ namespace IDE.ui } base.KeyDown(keyCode, isRepeat); - if (keyCode == KeyCode.Delete) - RemoveSelectedItems(); + + if (mWidgetWindow.GetKeyFlags() == .Ctrl) + { + switch (keyCode) + { + case (.)'C': + CopyToClipboard(); + case (.)'X': + CutToClipboard(); + case (.)'V': + PasteFromClipboard(); + default: + } + } + else if (mWidgetWindow.GetKeyFlags() == .None) + { + if (keyCode == KeyCode.Delete) + RemoveSelectedItems(); + } } void ItemClicked(MouseEvent theEvent) @@ -2374,7 +2750,7 @@ namespace IDE.ui return true; } - public void AddWorkspaceFolder(ProjectListViewItem parentListViewItem) + public WorkspaceFolder AddWorkspaceFolder(ProjectListViewItem parentListViewItem) { ProjectListViewItem listViewItem; listViewItem = (ProjectListViewItem)parentListViewItem.CreateChildItem(); @@ -2406,10 +2782,11 @@ namespace IDE.ui mListView.GetRoot().SelectItemExclusively(listViewItem); EditListViewItem(listViewItem); gApp.mWorkspace.SetChanged(); + return folder; } - public Project ImportProject(String filePath, VerSpec verSpec = .None) + public Project ImportProject(String filePath, WorkspaceFolder workspaceFolder, VerSpec verSpec = .None) { if (gApp.IsCompiling) return null; @@ -2456,7 +2833,7 @@ namespace IDE.ui gApp.AddNewProjectToWorkspace(proj, verSpec); gApp.mWorkspace.FixOptions(); gApp.[Friend]FlushDeferredLoadProjects(true); - InitProject(proj); + InitProject(proj, workspaceFolder); if (failed) { gApp.Fail(StackStringFormat!("Failed to load project: {0}", filePath)); @@ -2502,6 +2879,8 @@ namespace IDE.ui initialDir.Concat(Path.DirectorySeparatorChar, "Samples"); } + var workspaceFolder = GetSelectedWorkspaceFolder(); + fileDialog.InitialDirectory = initialDir; fileDialog.ValidateNames = true; fileDialog.DefaultExt = ".toml"; @@ -2511,7 +2890,7 @@ namespace IDE.ui { for (String origProjFilePath in fileDialog.FileNames) { - ImportProject(origProjFilePath); + ImportProject(origProjFilePath, workspaceFolder); } } #endif @@ -2616,6 +2995,43 @@ namespace IDE.ui { Menu anItem; + void AddWorkspaceMenuItems() + { + anItem = menu.AddItem("Add New Project..."); + anItem.mOnMenuItemSelected.Add(new (item) => { + AddNewProject(); + }); + if (gApp.IsCompiling) + anItem.SetDisabled(true); + + anItem = menu.AddItem("Add Existing Project..."); + anItem.mOnMenuItemSelected.Add(new (item) => { + mImportProjectDeferred = true; + }); + if (gApp.IsCompiling) + anItem.SetDisabled(true); + + anItem = menu.AddItem("Add From Installed..."); + anItem.mOnMenuItemSelected.Add(new (item) => { + mImportInstalledDeferred = true; + }); + if (gApp.IsCompiling) + anItem.SetDisabled(true); + anItem = menu.AddItem("New Folder"); + anItem.mOnMenuItemSelected.Add(new (item) => { + var workspaceFolder = GetSelectedWorkspaceFolder(); + if (workspaceFolder != null) + { + let newFolder = AddWorkspaceFolder(workspaceFolder.mListView); + newFolder.mParent = workspaceFolder; + } + else + { + AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot()); + } + }); + } + if (mListViewToWorkspaceFolderMap.TryGetValue(focusedItem, let folder)) { anItem = menu.AddItem("Remove"); @@ -2623,8 +3039,9 @@ namespace IDE.ui anItem = menu.AddItem("Rename"); anItem.mOnMenuItemSelected.Add(new (item) => { EditListViewItem(focusedItem); }); menu.AddItem(); - anItem = menu.AddItem("New Folder"); - anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder(folder.mListView); }); + + AddWorkspaceMenuItems(); + handled = true; } else if (gApp.mWorkspace.IsInitialized) @@ -2632,23 +3049,7 @@ namespace IDE.ui AddOpenContainingFolder(); menu.AddItem(); - anItem = menu.AddItem("Add New Project..."); - anItem.mOnMenuItemSelected.Add(new (item) => { AddNewProject(); }); - if (gApp.IsCompiling) - anItem.SetDisabled(true); - - anItem = menu.AddItem("Add Existing Project..."); - anItem.mOnMenuItemSelected.Add(new (item) => { mImportProjectDeferred = true; }); - if (gApp.IsCompiling) - anItem.SetDisabled(true); - - anItem = menu.AddItem("Add From Installed..."); - anItem.mOnMenuItemSelected.Add(new (item) => { mImportInstalledDeferred = true; }); - if (gApp.IsCompiling) - anItem.SetDisabled(true); - - anItem = menu.AddItem("New Folder"); - anItem.mOnMenuItemSelected.Add(new (item) => { AddWorkspaceFolder((ProjectListViewItem)mListView.GetRoot()); }); + AddWorkspaceMenuItems(); menu.AddItem(); anItem = menu.AddItem("Properties..."); anItem.mOnMenuItemSelected.Add(new (item) => { ShowWorkspaceProperties(); }); @@ -2717,7 +3118,7 @@ namespace IDE.ui }); } - item = menu.AddItem("Remove..."); + item = menu.AddItem("Remove...|Del"); if (gApp.IsCompiling) item.SetDisabled(true); item.mOnMenuItemSelected.Add(new (item) => @@ -2725,7 +3126,7 @@ namespace IDE.ui RemoveSelectedItems(); }); - item = menu.AddItem("Rename"); + item = gApp.AddMenuItem(menu, "Rename", "Rename Item"); if (gApp.IsCompiling) item.SetDisabled(true); item.mOnMenuItemSelected.Add(new (item) => @@ -2769,13 +3170,13 @@ namespace IDE.ui if ((projectItem != null) && (!isProject)) { - item = menu.AddItem("Remove ..."); + item = menu.AddItem("Remove ...|Del"); item.mOnMenuItemSelected.Add(new (item) => { RemoveSelectedItems(); }); - item = menu.AddItem("Rename"); + item = gApp.AddMenuItem(menu, "Rename", "Rename Item"); item.mOnMenuItemSelected.Add(new (item) => { var projectItem = GetSelectedProjectItem(); @@ -2926,6 +3327,14 @@ namespace IDE.ui if (!isFailedLoad) { + item = menu.AddItem("Copy|Ctrl+C"); + item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard()); + item = menu.AddItem("Cut|Ctrl+X"); + item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard()); + item = menu.AddItem("Paste|Ctrl+V"); + item.mOnMenuItemSelected.Add(new (item) => CopyToClipboard()); + menu.AddItem(); + item = menu.AddItem("New Folder"); item.mOnMenuItemSelected.Add(new (item) => { @@ -3098,6 +3507,8 @@ namespace IDE.ui mImportInstalledDeferred = false; ImportInstalledProject(); } + + ValidateCutClipboard(); } public override void Resize(float x, float y, float width, float height) @@ -3114,3 +3525,5 @@ namespace IDE.ui } } + +/////////////////////// \ No newline at end of file diff --git a/IDE/src/ui/RenameSymbolDialog.bf b/IDE/src/ui/RenameSymbolDialog.bf index 3ff90b37..ab19e118 100644 --- a/IDE/src/ui/RenameSymbolDialog.bf +++ b/IDE/src/ui/RenameSymbolDialog.bf @@ -244,7 +244,12 @@ namespace IDE.ui if (mKind == .GoToDefinition) { mSourceViewPanel.RecordHistoryLocation(); - var sourceViewPanel = gApp.ShowSourceFileLocation(scope .(filePath), -1, -1, line, lineChar, LocatorType.Smart, true); + + var usePath = scope String(filePath); + if (usePath.StartsWith("$Emit$")) + usePath.Insert("$Emit$".Length, "Resolve$"); + + var sourceViewPanel = gApp.ShowSourceFileLocation(usePath, -1, -1, line, lineChar, LocatorType.Smart, true); sourceViewPanel.RecordHistoryLocation(true); Close(); return; diff --git a/IDE/src/ui/SettingsDialog.bf b/IDE/src/ui/SettingsDialog.bf index 8c4e9c93..e7e1da9a 100644 --- a/IDE/src/ui/SettingsDialog.bf +++ b/IDE/src/ui/SettingsDialog.bf @@ -221,6 +221,30 @@ namespace IDE.ui } } + // Do chord prefix search + for (var propEntries in mPropPage.mPropEntries.Values) + { + var propEntry = propEntries[0]; + let keyEntry = (KeyEntry)propEntry.mTarget; + let origKeys = propEntry.mCurValue.Get>(); + var keys = scope List(origKeys.GetEnumerator()); + while (keys.Count > 1) + { + keys.PopBack(); + let keyEntryStr = scope String(); + KeyState.ToString(keys, keyEntryStr); + keyEntryStr.Append(" "); + CommandContextToString(keyEntry.mContextFlags, keyEntryStr); + + if (mappedEntries.TryGet(keyEntryStr, var keyPtr, var valuePtr)) + { + let other = valuePtr; + other.mHasConflict = true; + keyEntry.mHasConflict = true; + } + } + } + for (let keyEntryStr in mappedEntries.Keys) delete keyEntryStr; diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index f51d83ff..b977d064 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -14,6 +14,8 @@ using IDE.Debugger; using IDE.Compiler; using Beefy.geom; using Beefy.events; +using System.Security.Cryptography; +using System.IO; namespace IDE.ui { @@ -224,7 +226,7 @@ namespace IDE.ui { mTypeName = new .(emitEmbed.mTypeName); mEmitEmbed = emitEmbed; - mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Method) ? .Method : .Type); + mSourceViewPanel = new SourceViewPanel((emitEmbed.mEmitKind == .Emit_Method) ? .Method : .Type); mSourceViewPanel.mEmbedParent = mEmitEmbed.mEditWidgetContent.mSourceViewPanel; var emitPath = scope $"$Emit${emitEmbed.mTypeName}"; @@ -382,7 +384,7 @@ namespace IDE.ui } mAwaitingLoad = false; - if (!mEmitRemoved) + if ((!mEmitRemoved) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)) { for (var explicitTypeName in mEmitEmbed.mEditWidgetContent.mSourceViewPanel.[Friend]mExplicitEmitTypes) { @@ -397,6 +399,9 @@ namespace IDE.ui if ((mAwaitingLoad) && (gApp.mUpdateCnt % 4 == 0)) MarkDirty(); + + if (mSourceViewPanel.HasFocus()) + mEmitEmbed.mEditWidgetContent.mEmbedSelected = mEmitEmbed; } public void GetGenericTypes() @@ -516,6 +521,10 @@ namespace IDE.ui public int32 mEndLine; public View mView; + public this() + { + } + public ~this() { if (mView != null) @@ -525,17 +534,29 @@ namespace IDE.ui } } + public bool IsSelected => mEditWidgetContent.mEmbedSelected == this; + public float LabelWidth = GS!(42); + public override float GetWidth(bool hideLine) { - return GS!(42); + return IsSelected ? GS!(60) : LabelWidth; } public override void Draw(Graphics g, Rect rect, bool hideLine) { + var rect; + rect.mWidth = LabelWidth; + if (rect.mHeight >= DarkTheme.sDarkTheme.mSmallBoldFont.GetLineSpacing()) g.SetFont(DarkTheme.sDarkTheme.mSmallBoldFont); - using (g.PushColor(0x80707070)) + uint32 fillColor = 0x80707070; + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) + { + fillColor = 0x805050E0; + } + + using (g.PushColor(fillColor)) { g.FillRect(rect.mX + 1, rect.mY + 1, rect.mWidth - 2, rect.mHeight - 2); } @@ -558,6 +579,40 @@ namespace IDE.ui var summaryString = "Emit"; g.DrawString(summaryString, rect.mX, rect.mY + (int)((rect.mHeight - g.mFont.GetLineSpacing()) * 0.5f), .Centered, rect.mWidth); + + if (IsSelected) + { + g.Draw(DarkTheme.sDarkTheme.GetImage(.DropMenuButton), rect.Right, rect.Top); + } + } + + public override void MouseDown(Rect rect, float x, float y, int btn, int btnCount) + { + base.MouseDown(rect, x, y, btn, btnCount); + if (x >= rect.mX + LabelWidth) + ShowMenu(x, y); + } + + public void ShowMenu(float x, float y) + { + Menu menuItem; + + Menu menu = new Menu(); + menuItem = menu.AddItem("Compiler"); + + var subItem = menuItem.AddItem("Resolve"); + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) + subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check); + subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Resolve); }); + + subItem = menuItem.AddItem("Build"); + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) + subItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check); + subItem.mOnMenuItemSelected.Add(new (menu) => { gApp.SetEmbedCompiler(.Build); }); + + MenuWidget menuWidget = DarkTheme.sDarkTheme.CreateMenuWidget(menu); + + menuWidget.Init(mEditWidgetContent, x, y); } } @@ -575,10 +630,11 @@ namespace IDE.ui case UsingNamespaces = 'U'; case Unknown = '?'; case HasUncertainEmits = '~'; - case Emit = 'e'; + case Emit_Type = 't'; + case Emit_Method = 'm'; case EmitAddType = '+'; - public bool IsEmit => (this == .Emit); + public bool IsEmit => (this == .Emit_Type) || (this == .Emit_Method); } public Kind mKind; @@ -602,6 +658,8 @@ namespace IDE.ui public int32 mParseRevision; public int32 mTextRevision; public bool mDeleted; + + public bool DefaultOpen => mKind != .Region; } public struct EmitData @@ -614,6 +672,7 @@ namespace IDE.ui public bool mOnlyInResolveAll; public bool mIncludedInClassify; public bool mIncludedInResolveAll; + public bool mIncludedInBuild; public int32 mAnchorId; } @@ -757,6 +816,8 @@ namespace IDE.ui public int32 mCollapseTextVersionId; public bool mCollapseNeedsUpdate; public bool mCollapseNoCheckOpen; + public bool mCollapseDBDirty; + public bool mCollapseAwaitingDB = true; public List PersistentTextPositions { @@ -1784,7 +1845,19 @@ namespace IDE.ui int line; int lineChar; GetCursorLineChar(out line, out lineChar); - return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, mSourceViewPanel.mFilePath, line, lineChar, ignoreIfClose); + + String useFilePath = mSourceViewPanel.mFilePath; + if ((mSourceViewPanel.mFilePath.StartsWith("$Emit$")) && + (!mSourceViewPanel.mFilePath.StartsWith("$Emit$Build$")) && + (!mSourceViewPanel.mFilePath.StartsWith("$Emit$Resolve$"))) + { + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve) + useFilePath = scope:: String("$Emit$Resolve$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length)); + else + useFilePath = scope:: String("$Emit$Build$")..Append(mSourceViewPanel.mFilePath.Substring("$Emit$".Length)); + } + + return IDEApp.sApp.mHistoryManager.CreateHistory(mSourceViewPanel, useFilePath, line, lineChar, ignoreIfClose); } return null; } @@ -3901,7 +3974,7 @@ namespace IDE.ui prevChar = mData.mText[cursorTextPos - 1].mChar; } - if (((keyChar == '\n') || (keyChar == '\r')) && (mIsMultiline) && (!CheckReadOnly())) + if (((keyChar == '\n') || (keyChar == '\r')) && (!HasSelection()) && (mIsMultiline) && (!CheckReadOnly())) { UndoBatchStart undoBatchStart = new UndoBatchStart("newline"); mData.mUndoManager.Add(undoBatchStart); @@ -4408,6 +4481,7 @@ namespace IDE.ui public override void KeyDown(KeyCode keyCode, bool isRepeat) { mIgnoreKeyChar = false; + mEmbedSelected = null; bool autoCompleteRequireControl = (gApp.mSettings.mEditorSettings.mAutoCompleteRequireControl) && (mIsMultiline); @@ -4463,7 +4537,6 @@ namespace IDE.ui { return; } - if ((keyCode == KeyCode.Escape) && (mSelection != null) && (mSelection.Value.HasSelection)) { @@ -4696,6 +4769,23 @@ namespace IDE.ui { base.MouseClicked(x, y, origX, origY, btn); + if (btn == 1) + { + int line = GetLineAt(y); + if (mEmbeds.GetValue((.)line) case .Ok(let embed)) + { + Rect embedRect = GetEmbedRect(line, embed); + if (embedRect.Contains(x, y)) + { + if (var emitEmbed = embed as EmitEmbed) + { + emitEmbed.ShowMenu(x, y); + } + return; + } + } + } + var useX = x; var useY = y; @@ -4735,15 +4825,15 @@ namespace IDE.ui { Menu menuItem; - menuItem = menu.AddItem("Go to Definition"); + menuItem = gApp.AddMenuItem(menu, "Go to Definition", "Goto Definition"); menuItem.SetDisabled(!hasText); menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.GoToDefinition(true)); - menuItem = menu.AddItem("Find All References"); + menuItem = gApp.AddMenuItem(menu, "Find All References"); menuItem.SetDisabled(!hasText); menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_FindAllReferences()); - menuItem = menu.AddItem("Rename Symbol"); + menuItem = gApp.AddMenuItem(menu, "Rename Symbol"); menuItem.SetDisabled(!hasText); menuItem.mOnMenuItemSelected.Add(new (evt) => gApp.Cmd_RenameSymbol()); @@ -4823,7 +4913,12 @@ namespace IDE.ui var autoComplete = new AutoComplete(mEditWidget); autoComplete.SetInfo(infoCopy); autoComplete.mAutoCompleteListWidget.mSelectIdx = fixitIdx; + + UndoBatchStart undoBatchStart = new UndoBatchStart("autocomplete"); + mData.mUndoManager.Add(undoBatchStart); autoComplete.InsertSelection(0); + mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + autoComplete.Close(); } ~ @@ -4866,10 +4961,14 @@ namespace IDE.ui menu.AddItem(); var debugger = IDEApp.sApp.mDebugger; bool isPaused = debugger.IsPaused(); - menuItem = menu.AddItem("Show Disassembly"); + menuItem = gApp.AddMenuItem(menu, "Show Disassembly"); menuItem.SetDisabled(!isPaused); menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.ShowDisassemblyAtCursor()); + menuItem = gApp.AddMenuItem(menu, "Set Next Statement"); + menuItem.SetDisabled(!isPaused); + menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.[Friend]SetNextStatement()); + var stepIntoSpecificMenu = menu.AddItem("Step into Specific"); stepIntoSpecificMenu.SetDisabled(!isPaused); stepIntoSpecificMenu.IsParent = true; @@ -5019,20 +5118,26 @@ namespace IDE.ui Rect embedRect = GetEmbedRect(line, embed); if (embedRect.Contains(x, y)) { - if ((btn == 0) && (btnCount % 2 == 0)) + mEmbedSelected = embed; + embed.MouseDown(GetEmbedRect(line, embed), x, y, btn, btnCount); + if (btn == 0) { - if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary) - SetCollapseOpen(collapseSummary.mCollapseIndex, true); - else if (var emitEmbed = embed as EmitEmbed) + if (btnCount % 2 == 0) { - emitEmbed.mIsOpen = !emitEmbed.mIsOpen; - mCollapseNeedsUpdate = true; + if (var collapseSummary = embed as SourceEditWidgetContent.CollapseSummary) + SetCollapseOpen(collapseSummary.mCollapseIndex, true); + else if (var emitEmbed = embed as EmitEmbed) + { + emitEmbed.mIsOpen = !emitEmbed.mIsOpen; + mCollapseNeedsUpdate = true; + } } } return; } } + mEmbedSelected = null; base.MouseDown(x, y, btn, btnCount); } @@ -5727,6 +5832,13 @@ namespace IDE.ui } } + void DeleteEmbed(Embed embed) + { + if (mEmbedSelected == embed) + mEmbedSelected = null; + delete embed; + } + public override void GetTextData() { var data = Data; @@ -5755,8 +5867,14 @@ namespace IDE.ui } } + IdSpan.LookupContext lookupCtx = null; + for (var emitData in ref data.mEmitData) { + if (lookupCtx == null) + lookupCtx = scope:: .(mData.mTextIdData); + emitData.mAnchorIdx = (.)lookupCtx.GetIndexFromId(emitData.mAnchorId); + GetLineCharAtIdx(emitData.mAnchorIdx, var line, var lineChar); SourceEditWidgetContent.EmitEmbed emitEmbed = null; @@ -5776,7 +5894,7 @@ namespace IDE.ui else { //Debug.WriteLine($" Occupied- deleting {emitEmbed}"); - delete emitEmbed; + DeleteEmbed(emitEmbed); emitEmbed = null; } } @@ -5837,13 +5955,14 @@ namespace IDE.ui { mCollapseNeedsUpdate = true; mEmbeds.Remove(emitEmbed.mLine); - delete emitEmbed; + DeleteEmbed(emitEmbed); } } for (var collapseData in ref data.mCollapseData) { - if (mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry)) + bool isNew = mCollapseMap.TryAdd(collapseData.mAnchorId, ?, var entry); + if (isNew) { *entry = .(); } @@ -5852,6 +5971,12 @@ namespace IDE.ui entry.mPrevAnchorLine = prevAnchorLine; entry.mParseRevision = mCollapseParseRevision; entry.mDeleted = false; + + if ((isNew) && (!entry.DefaultOpen) && (!mCollapseAwaitingDB)) + { + // Likely a '#region' that we need to serialize as being open + mCollapseDBDirty = true; + } } for (var entry in ref mCollapseMap.Values) @@ -5863,7 +5988,7 @@ namespace IDE.ui if (!(value is EmitEmbed)) { mEmbeds.Remove(entry.mAnchorLine); - delete value; + DeleteEmbed(value); } } @entry.Remove(); @@ -5888,7 +6013,7 @@ namespace IDE.ui { //Debug.WriteLine($" Removing {val.value}"); if (val.value is CollapseSummary) - delete val.value; + DeleteEmbed(val.value); } continue; } @@ -5914,11 +6039,68 @@ namespace IDE.ui else { //Debug.WriteLine($" Deleting(3) {val}"); - delete val; + DeleteEmbed(val); } } } +#if !CLI + if ((mCollapseAwaitingDB) && (mSourceViewPanel != null)) + { + String filePath = scope .(mSourceViewPanel.mFilePath); + IDEUtils.MakeComparableFilePath(filePath); + + HashSet toggledIndices = scope .(); + + List dbData = scope .(); + if (gApp.mFileRecovery.GetDB(filePath, dbData)) + { + MemoryStream memStream = scope .(dbData, false); + var dbHash = memStream.Read().GetValueOrDefault(); + + String text = scope .(); + mEditWidget.GetText(text); + var curHash = MD5.Hash(.((uint8*)text.Ptr, text.Length)); + if (curHash == dbHash) + { + while (true) + { + if (memStream.Read() case .Ok(let idx)) + { + // We recorded indices, which (upon load) will generate an id of idx+1 + toggledIndices.Add(idx + 1); + } + else + break; + } + } + } + + bool wasCursorVisible = IsCursorVisible(); + bool hadCloses = false; + for (var collapseEntry in mOrderedCollapseEntries) + { + bool wantOpen = collapseEntry.DefaultOpen; + if (toggledIndices.Contains(collapseEntry.mAnchorId)) + wantOpen = !wantOpen; + + if (collapseEntry.mIsOpen != wantOpen) + { + if (!wantOpen) + hadCloses = true; + SetCollapseOpen(@collapseEntry.Index, wantOpen, true, true); + } + } + if ((wasCursorVisible) && (hadCloses)) + { + UpdateCollapse(0.0f); + EnsureCursorVisible(); + } + + mCollapseAwaitingDB = false; + } +#endif + //Debug.WriteLine($"ParseCollapseRegions Count:{mOrderedCollapseEntries.Count} Time:{sw.ElapsedMilliseconds}ms"); } @@ -6221,17 +6403,26 @@ namespace IDE.ui } - public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false) + public void SetCollapseOpen(int collapseIdx, bool wantOpen, bool immediate = false, bool keepCursorVisible = false) { var entry = mOrderedCollapseEntries[collapseIdx]; + var cursorLineAndColumn = CursorLineAndColumn; + + if ((!wantOpen) && (keepCursorVisible) && (cursorLineAndColumn.mLine >= entry.mStartLine) && (cursorLineAndColumn.mLine <= entry.mEndLine)) + { + if (CursorTextPos < entry.mEndIdx) + { + // Ignore close + return; + } + } + entry.mIsOpen = wantOpen; if (immediate) entry.mOpenPct = entry.mIsOpen ? 1.0f : 0.0f; - else - mCollapseNeedsUpdate = true; - - var cursorLineAndColumn = CursorLineAndColumn; + mCollapseNeedsUpdate = true; + mCollapseDBDirty = true; if (wantOpen) { @@ -6241,7 +6432,7 @@ namespace IDE.ui { if ((embed.mKind == .HideLine) || (embed.mKind == .LineEnd)) { - delete embed; + DeleteEmbed(embed); mEmbeds.Remove(entry.mAnchorLine); } } @@ -6283,7 +6474,7 @@ namespace IDE.ui if (!(value is EmitEmbed)) { mEmbeds.Remove(prevAnchorLine); - delete value; + DeleteEmbed(value); } } @@ -6304,7 +6495,7 @@ namespace IDE.ui else { //Debug.WriteLine($" Occupied- deleting {val}"); - delete val.value; + DeleteEmbed(val.value); } } } @@ -6360,7 +6551,7 @@ namespace IDE.ui if (entry.mDeleted) { if (mEmbeds.GetAndRemove(entry.mAnchorIdx) case .Ok(let val)) - delete val.value; + DeleteEmbed(val.value); continue; } @@ -6388,7 +6579,7 @@ namespace IDE.ui *valuePtr = val.value; } else - delete val.value; + DeleteEmbed(val.value); } } } @@ -6401,7 +6592,7 @@ namespace IDE.ui RehupLineCoords(); } - public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType resolveType) + public void ParseCollapseRegions(String collapseText, int32 textVersion, ref IdSpan idSpan, ResolveType? resolveType) { /*if (resolveType == .None) return;*/ @@ -6410,11 +6601,13 @@ namespace IDE.ui var data = PreparedData; - if (resolveType != .None) + if ((resolveType != null) && (resolveType != .None)) { data.ClearCollapse(); } + bool wantsBuildEmits = gApp.mSettings.mEditorSettings.mEmitCompiler == .Build; + //Debug.WriteLine($"ParseCollapseRegions {resolveType} CollapseRevision:{data.mCollapseParseRevision+1} TextVersion:{textVersion} IdSpan:{idSpan:D}"); List typeNameIdxMap = scope .(); @@ -6429,7 +6622,7 @@ namespace IDE.ui if (emitInitialized) return; emitInitialized = true; - if ((hasUncertainEmits) || (resolveType == .None)) + if ((hasUncertainEmits) || (wantsBuildEmits) || (resolveType == .None)) { // Leave emits alone for (var typeName in data.mTypeNames) @@ -6437,7 +6630,11 @@ namespace IDE.ui for (var emitData in ref data.mEmitData) { emitAnchorIds[emitData.mAnchorId] = (.)@emitData.Index; - if (resolveType == .None) + if (resolveType == null) + { + // Do nothing + } + else if (resolveType == .None) emitData.mIncludedInResolveAll = false; else emitData.mIncludedInClassify = false; @@ -6491,6 +6688,7 @@ namespace IDE.ui emitData.mOnlyInResolveAll = resolveType == .None; emitData.mIncludedInClassify = resolveType != .None; emitData.mIncludedInResolveAll = resolveType == .None; + emitData.mIncludedInBuild = resolveType == null; if (emitData.mAnchorIdx == -1) { @@ -6508,8 +6706,14 @@ namespace IDE.ui { curEmitData.mIncludedInResolveAll = true; } + else if ((wantsBuildEmits) && (resolveType != null)) + { + curEmitData.mIncludedInBuild |= emitData.mIncludedInBuild; + curEmitData.mIncludedInClassify |= emitData.mIncludedInClassify; + } else { + emitData.mIncludedInBuild |= curEmitData.mIncludedInBuild; emitData.mIncludedInClassify |= curEmitData.mIncludedInClassify; curEmitData = emitData; } @@ -6517,12 +6721,19 @@ namespace IDE.ui continue; } + if ((wantsBuildEmits) && (resolveType != null)) + { + // Not included in the build emit data - just show as a marker + emitData.mStartLine = 0; + emitData.mEndLine = 0; + } + //Debug.WriteLine($" New emit AnchorIdx:{emitData.mAnchorIdx} AnchorId:{emitData.mAnchorId} CurTextVersion:{textVersion} FoundTextVersion:{foundTextVersion}"); data.mEmitData.Add(emitData); continue; } - if (resolveType == .None) + if ((resolveType == null) || (resolveType == .None)) continue; CollapseData collapseData; @@ -6554,7 +6765,11 @@ namespace IDE.ui for (var emitData in ref data.mEmitData) { - if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) || + if ((emitData.mIncludedInBuild) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build)) + { + // Allow build-only markers to survive + } + else if (((emitData.mOnlyInResolveAll) && (!emitData.mIncludedInResolveAll)) || ((!emitData.mOnlyInResolveAll) && (!emitData.mIncludedInClassify))) { @emitData.RemoveFast(); diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index 2a7316d6..1112ce42 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -367,6 +367,7 @@ namespace IDE.ui class QueuedCollapseData { public String mData = new .() ~ delete _; + public String mBuildData ~ delete _; public int32 mTextVersion; public IdSpan mCharIdSpan ~ _.Dispose(); public ResolveType mResolveType; @@ -446,6 +447,7 @@ namespace IDE.ui int32 mTicksSinceTextChanged; int32 mErrorLookupTextIdx = -1; LinePointerDrawData mLinePointerDrawData; + bool mIsDraggingLinePointer; Point? mMousePos; #if IDE_C_SUPPORT public String mClangHoverErrorData ~ delete mClangHoverErrorData; @@ -1262,6 +1264,9 @@ namespace IDE.ui void FindEmbeds(ResolveParams resolveParams) { + if (gApp.mSettings.mEditorSettings.mEmitCompiler != .Resolve) + return; + HashSet foundEditData = scope .(); Dictionary remappedTypeNames = scope .(); @@ -1478,11 +1483,31 @@ namespace IDE.ui var collapseData = bfCompiler.GetCollapseRegions(parser, resolvePassData, explicitEmitTypeNames, .. scope .()); + String buildCollapseData = null; + if ((gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) && (!gApp.mBfBuildCompiler.IsPerformingBackgroundOperation())) + { + gApp.mBfBuildSystem.Lock(0); + var buildParser = gApp.mBfBuildSystem.GetParser(mProjectSource); + if (buildParser != null) + { + var buildResolvePassData = buildParser.CreateResolvePassData(.None); + defer delete buildResolvePassData; + buildCollapseData = gApp.mBfBuildCompiler.GetCollapseRegions(buildParser, buildResolvePassData, explicitEmitTypeNames, .. scope:: .()); + } + else + { + buildCollapseData = ""; + } + gApp.mBfBuildSystem.Unlock(); + } + using (mMonitor.Enter()) { DeleteAndNullify!(mQueuedCollapseData); mQueuedCollapseData = new .(); mQueuedCollapseData.mData.Set(collapseData); + if (buildCollapseData != null) + mQueuedCollapseData.mBuildData = new String(buildCollapseData); mQueuedCollapseData.mTextVersion = textVersion; mQueuedCollapseData.mCharIdSpan = charIdSpan.Duplicate(); @@ -1524,13 +1549,13 @@ namespace IDE.ui return; //var compiler = ResolveCompiler; - var char8Data = mEditWidget.Content.mData.mText; - int char8Len = Math.Min(char8Data.Count, mEditWidget.Content.mData.mTextLength); + var charData = mEditWidget.Content.mData.mText; + int charLen = Math.Min(charData.Count, mEditWidget.Content.mData.mTextLength); - char8[] chars = new char8[char8Len]; + char8[] chars = new char8[charLen]; defer delete chars; - for (int32 i = 0; i < char8Len; i++) - chars[i] = (char8)char8Data[i].mChar; + for (int32 i = 0; i < charLen; i++) + chars[i] = (char8)charData[i].mChar; String text = scope String(); text.Append(chars, 0, chars.Count); @@ -1554,7 +1579,7 @@ namespace IDE.ui parser.SetEmbedKind(mEmbedKind); parser.Reduce(passInstance); } - parser.ClassifySource(char8Data, !mIsBeefSource); + parser.ClassifySource(charData, !mIsBeefSource); mWantsParserCleanup = true; } @@ -2208,7 +2233,7 @@ namespace IDE.ui { parser.CreateClassifier(passInstance, resolvePassData, charData); - if (resolveParams != null) + if ((resolveParams != null) && (gApp.mSettings.mEditorSettings.mEmitCompiler == .Resolve)) { for (var emitEmbedData in resolveParams.mEmitEmbeds) { @@ -2484,7 +2509,10 @@ namespace IDE.ui int32 prevLine = mEditWidget.Content.CursorLineAndColumn.mLine; mEditWidget.Content.mSelection = null; - mEditWidget.Content.CursorTextPos = cursorIdx; + + int wantCursorPos = Math.Min(mEditWidget.Content.mData.mTextLength - 1, cursorIdx); + if (wantCursorPos >= 0) + mEditWidget.Content.CursorTextPos = wantCursorPos; mEditWidget.Content.CursorMoved(); mEditWidget.Content.EnsureCursorVisible(true, true); mEditWidget.Content.mCursorImplicitlyMoved = true; @@ -4476,6 +4504,8 @@ namespace IDE.ui BreakpointCountMask = 0x7F, Boomkmark = 0x80 } + + static float sDrawLeftAdjust = GS!(12); public override void Draw(Graphics g) { @@ -4505,7 +4535,6 @@ namespace IDE.ui using (g.PushTranslate(0, mEditWidget.mY + mEditWidget.Content.Y + GS!(2))) { float editX = GetEditX(); - float leftAdjust = GS!(12); float lineSpacing = ewc.mFont.GetLineSpacing(); int cursorLineNumber = mEditWidget.mEditWidgetContent.CursorLineAndColumn.mLine; @@ -4623,7 +4652,7 @@ namespace IDE.ui int breakpointCount = (.)(curLineFlags & .BreakpointCountMask); curLineFlags++; - float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - leftAdjust) + breakpointCount*-GS!(2); + float iconX = Math.Max(GS!(-2), mEditWidget.mX - GS!(24) - sDrawLeftAdjust) + breakpointCount*-GS!(2); float iconY = 0 + ewc.mLineCoords[drawLineNum] + (lineSpacing - DarkTheme.sUnitSize + GS!(5)) / 2; // Just leave last digit visible @@ -4648,7 +4677,7 @@ namespace IDE.ui continue; //hadLineIcon[drawLineNum - lineStart] = true; Image image = DarkTheme.sDarkTheme.GetImage(bookmark.mIsDisabled ? .IconBookmarkDisabled : .IconBookmark); - g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - leftAdjust), + g.Draw(image, Math.Max(GS!(-5), mEditWidget.mX - GS!(30) - sDrawLeftAdjust), 0 + bookmark.mLineNum * lineSpacing); var curLineFlags = ref lineFlags[drawLineNum - lineStart]; @@ -4812,9 +4841,20 @@ namespace IDE.ui { mLinePointerDrawData.mUpdateCnt = gApp.mUpdateCnt; mLinePointerDrawData.mDebuggerContinueIdx = gApp.mDebuggerContinueIdx; - g.Draw(img, mEditWidget.mX - GS!(20) - leftAdjust, + g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust, 0 + ewc.GetLineY(lineNum, 0)); } + + if (mMousePos != null && mIsDraggingLinePointer) + { + int dragLineNum = GetLineAt(0, mMousePos.Value.y); + if (dragLineNum >= 0 && dragLineNum != lineNum) + { + using (g.PushColor(0x7FFFFFFF)) + g.Draw(img, mEditWidget.mX - GS!(20) - sDrawLeftAdjust, + 0 + ewc.GetLineY(dragLineNum, 0)); + } + } } } } @@ -6275,15 +6315,15 @@ namespace IDE.ui emitEmbedView.mGenericMethodCombo?.mEditWidget.SetFocus(); } - var sourceViewPanel = emitEmbedView.mSourceViewPanel; + var firstSourceViewPanel = emitEmbedView.mSourceViewPanel; - var embedEWC = sourceViewPanel.mEditWidget.mEditWidgetContent; + var firstEmbedEWC = firstSourceViewPanel.mEditWidget.mEditWidgetContent; - var prevCursorLineAndColumn = embedEWC.CursorLineAndColumn; + var prevCursorLineAndColumn = firstEmbedEWC.CursorLineAndColumn; - var editData = sourceViewPanel.mEditWidget.mEditWidgetContent.mData; + var editData = firstSourceViewPanel.mEditWidget.mEditWidgetContent.mData; if (editData.mTextLength == 0) - DeleteAndNullify!(sourceViewPanel.mTrackedTextElementViewList); + DeleteAndNullify!(firstSourceViewPanel.mTrackedTextElementViewList); delete editData.mText; editData.mText = embed.mCharData; @@ -6294,15 +6334,23 @@ namespace IDE.ui editData.mNextCharId = 0; editData.mTextIdData.Insert(0, editData.mTextLength, ref editData.mNextCharId); - sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged(); - // We have a full classify now, FastClassify will just mess it up - sourceViewPanel.mSkipFastClassify = true; + firstSourceViewPanel.mEmitRevision = embed.mRevision; + firstSourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true); - if (prevCursorLineAndColumn.mLine >= embedEWC.GetLineCount()) - embedEWC.CursorLineAndColumn = .(embedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn); - - sourceViewPanel.mEmitRevision = embed.mRevision; - sourceViewPanel.InjectErrors(resolveResult.mPassInstance, editData.mText, editData.mTextIdData, false, true); + for (var user in editData.mUsers) + { + if (var embedEWC = user as SourceEditWidgetContent) + { + var sourceViewPanel = embedEWC.mSourceViewPanel; + + sourceViewPanel.mEditWidget.mEditWidgetContent.ContentChanged(); + // We have a full classify now, FastClassify will just mess it up + sourceViewPanel.mSkipFastClassify = true; + + if (prevCursorLineAndColumn.mLine >= firstEmbedEWC.GetLineCount()) + embedEWC.CursorLineAndColumn = .(firstEmbedEWC.GetLineCount() - 1, prevCursorLineAndColumn.mColumn); + } + } } } } @@ -6595,7 +6643,7 @@ namespace IDE.ui } if ((mTicksSinceTextChanged >= 60) && (mWantsSpellCheck)) { - if (IsControllingEditData()) + if ((IsControllingEditData()) && (mEmbedKind == .None)) StartSpellCheck(); mWantsSpellCheck = false; } @@ -6850,7 +6898,59 @@ namespace IDE.ui using (mMonitor.Enter()) { if (mQueuedCollapseData != null) + { + if (gApp.mSettings.mEditorSettings.mEmitCompiler == .Build) + { + if (mQueuedCollapseData.mBuildData != null) + { + bool foundData = false; + + using (gApp.mMonitor.Enter()) + { + var projectSourceCompileInstance = gApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, gApp.mWorkspace.HotCompileIdx); + if (projectSourceCompileInstance != null) + { + foundData = true; + ewc.ParseCollapseRegions(mQueuedCollapseData.mBuildData, mQueuedCollapseData.mTextVersion, ref projectSourceCompileInstance.mSourceCharIdData, null); + + HashSet dataLoaded = scope .(); + + for (var embed in ewc.mEmbeds.Values) + { + if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed) + { + if (emitEmbed.mView != null) + { + if (dataLoaded.Add(emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.mData)) + { + emitEmbed.mView.mSourceViewPanel.mSkipFastClassify = false; + emitEmbed.mView.mSourceViewPanel.Reload(); + emitEmbed.mView.mSourceViewPanel.mWantsFastClassify = true; + } + } + } + } + } + } + + if (!foundData) + { + for (var embed in ewc.mEmbeds.Values) + { + if (var emitEmbed = embed as SourceEditWidgetContent.EmitEmbed) + { + if (emitEmbed.mView != null) + { + emitEmbed.mView.mSourceViewPanel.mEditWidget.mEditWidgetContent.ClearText(); + } + } + } + } + } + } + ewc.ParseCollapseRegions(mQueuedCollapseData.mData, mQueuedCollapseData.mTextVersion, ref mQueuedCollapseData.mCharIdSpan, mQueuedCollapseData.mResolveType); + } DeleteAndNullify!(mQueuedCollapseData); } @@ -6858,6 +6958,38 @@ namespace IDE.ui // Process after mQueuedCollapseData so mCharIdSpan is still valid ProcessDeferredResolveResults(0); + +#if !CLI + if (ewc.mCollapseDBDirty) + { + MemoryStream memStream = scope .(); + + String text = scope .(); + mEditWidget.GetText(text); + var hash = MD5.Hash(.((uint8*)text.Ptr, text.Length)); + memStream.Write(hash); + + bool hadData = false; + + for (var kv in ewc.mOrderedCollapseEntries) + { + if (kv.mIsOpen != kv.DefaultOpen) + { + hadData = true; + memStream.Write(kv.mAnchorIdx); + } + } + + String filePath = scope .(mFilePath); + IDEUtils.MakeComparableFilePath(filePath); + + if (!hadData) + gApp.mFileRecovery.DeleteDB(filePath); + else + gApp.mFileRecovery.SetDB(filePath, memStream.Memory); + ewc.mCollapseDBDirty = false; + } +#endif } public override void UpdateF(float updatePct) @@ -7070,7 +7202,7 @@ namespace IDE.ui float GetEditX() { - if (!gApp.mSettings.mEditorSettings.mShowLineNumbers && (mEmbedKind == .None)) + if ((!gApp.mSettings.mEditorSettings.mShowLineNumbers) || (mEmbedKind != .None)) return GS!(24); var font = IDEApp.sApp.mTinyCodeFont; @@ -7268,6 +7400,29 @@ namespace IDE.ui } } + public override void MouseUp(float x, float y, int32 btn) + { + base.MouseUp(x, y, btn); + + if (mIsDraggingLinePointer) + { + mIsDraggingLinePointer = false; + + float origX; + float origY; + RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY); + + int newLine = GetLineAt(0, y); + if (newLine >= 0 && newLine != GetLineAt(origX, origY)) + { + gApp.mDebugger.SetNextStatement(false, mFilePath, (int)newLine, 0); + + gApp.[Friend]PCChanged(); + gApp.[Friend]DebuggerUnpaused(); + } + } + } + public int GetLineAt(float x, float y) { if (x > mEditWidget.mX - GS!(4)) @@ -7321,8 +7476,9 @@ namespace IDE.ui { if ((x >= GS!(3)) && (x < mEditWidget.mX - GS!(14))) { + int lineMouseDown = GetLineAt(origX, origY); int lineClick = GetLineAt(x, y); - if (lineClick >= 0) + if (lineClick >= 0 && lineMouseDown == lineClick) { ToggleBreakpointAt(lineClick, 0); } @@ -7351,6 +7507,37 @@ namespace IDE.ui { base.MouseMove(x, y); mMousePos = .(x, y); + + if (!mIsDraggingLinePointer && IDEApp.sApp.mExecutionPaused && gApp.mDebugger.mActiveCallStackIdx == 0 && mMouseFlags.HasFlag(.Left)) + { + SourceEditWidgetContent ewc = (.)mEditWidget.Content; + Rect linePointerRect = .( + mEditWidget.mX - GS!(20) - sDrawLeftAdjust, + 0 + ewc.GetLineY(mLinePointerDrawData.mLine, 0), + GS!(15), + GS!(15) + ); + + float origX; + float origY; + RootToSelfTranslate(mWidgetWindow.mMouseDownX, mWidgetWindow.mMouseDownY, out origX, out origY); + + if (linePointerRect.Contains(origX, origY - mEditWidget.mY - mEditWidget.Content.Y - GS!(3))) + { + mIsDraggingLinePointer = true; + } + } + else if (mIsDraggingLinePointer) + { + SourceEditWidgetContent ewc = (.)mEditWidget.Content; + float linePos = ewc.GetLineY(GetLineAt(0, mMousePos.Value.y), 0); + Rect visibleRange = mEditWidget.GetVisibleContentRange(); + + if (visibleRange.Top > linePos) + mEditWidget.mVertScrollbar.ScrollTo(linePos); + else if (visibleRange.Bottom - mEditWidget.mHorzScrollbar.mHeight < linePos) + mEditWidget.mVertScrollbar.ScrollTo(linePos - visibleRange.mHeight + ewc.GetLineHeight(0)); + } } public override void DrawAll(Graphics g) diff --git a/IDE/src/ui/TargetedPropertiesDialog.bf b/IDE/src/ui/TargetedPropertiesDialog.bf index 534b86b5..c590a50c 100644 --- a/IDE/src/ui/TargetedPropertiesDialog.bf +++ b/IDE/src/ui/TargetedPropertiesDialog.bf @@ -384,6 +384,8 @@ namespace IDE.ui protected void ConfigDeleted(String configName) { + int32 category = mPropPage.mCategoryType; + bool currentChanged = false; int idx = mConfigNames.IndexOf(configName); if (idx != -1) @@ -422,7 +424,17 @@ namespace IDE.ui } if (currentChanged) - SelectConfig(mConfigNames); + { + mPropPage = null; + SelectConfig(mConfigNames, category); + } + + if ((mActiveConfigName == configName) && (!mConfigNames.IsEmpty)) + { + var newConfigName = mConfigNames[0]; + gApp.mMainFrame.mStatusBar.SelectConfig(newConfigName); + mActiveConfigName.Set(newConfigName); + } } protected void ConfigRenamed(String from, String to) @@ -761,7 +773,7 @@ namespace IDE.ui ShowPropPage(categoryType); } - protected void SelectConfig(List configNames) + protected void SelectConfig(List configNames, int32 category = -1) { if (configNames != mConfigNames) { @@ -770,7 +782,7 @@ namespace IDE.ui mConfigNames.Add(configName); } if (mConfigNames.Count == 1) - SelectConfig(mConfigNames[0]); + SelectConfig(mConfigNames[0], category); else { mConfigComboBox.Label = ""; @@ -795,13 +807,16 @@ namespace IDE.ui } } - protected void SelectConfig(String configName) + protected void SelectConfig(String configName, int32 category = -1) { + var category; + if (category == -1) + category = mPropPage.mCategoryType; var newConfigName = new String(configName); ClearAndDeleteItems(mConfigNames); mConfigNames.Add(newConfigName); mConfigComboBox.Label = newConfigName; - ShowPropPage(mPropPage.mCategoryType); + ShowPropPage(category); } protected void SelectPlatform(String platformName, int32 category = -1) diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index cd03670d..f4de9e67 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -2752,20 +2752,29 @@ namespace IDE.ui } else if (memberVals0 == ":addrs") { - WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); - String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]); - memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1; + if (memberCount > 0) + { + WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); + String.NewOrSet!(memberItem.mWatchSeriesInfo.mAddrs, memberVals[1]); + memberItem.mWatchSeriesInfo.mAddrsEntrySize = 1; + } } else if (memberVals0 == ":addrsEntrySize") { - int32 addrsEntrySize = int32.Parse(scope String(memberVals[1])); - WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); - memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize; + if (memberCount > 0) + { + int32 addrsEntrySize = int32.Parse(scope String(memberVals[1])); + WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); + memberItem.mWatchSeriesInfo.mAddrsEntrySize = addrsEntrySize; + } } else if (memberVals0 == ":continuation") { - WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); - String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]); + if (memberCount > 0) + { + WatchListViewItem memberItem = (WatchListViewItem)listViewItem.GetChildAtIndex(memberCount - 1); + String.NewOrSet!(memberItem.mWatchSeriesInfo.mContinuationData, memberVals[1]); + } } else if (memberVals0 == ":action") { diff --git a/IDEHelper/Backend/BeCOFFObject.cpp b/IDEHelper/Backend/BeCOFFObject.cpp index e01f4a0b..6a7a8354 100644 --- a/IDEHelper/Backend/BeCOFFObject.cpp +++ b/IDEHelper/Backend/BeCOFFObject.cpp @@ -74,15 +74,15 @@ void BeInlineLineBuilder::Update(BeDbgCodeEmission* codeEmission) } void BeInlineLineBuilder::Start(BeDbgCodeEmission* codeEmission) -{ +{ //mCurLine = codeEmission->mDbgLoc->mDbgInlinedAt->mLine; int lineOfs = codeEmission->mDbgLoc->mLine - mCurLine; int codeOfs = codeEmission->mPos - mCurCodePos; - + auto usingFile = codeEmission->mDbgLoc->mDbgInlinedAt->GetDbgFile(); auto wantFile = codeEmission->mDbgLoc->GetDbgFile(); - + mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset); WriteSigned(lineOfs); @@ -93,10 +93,10 @@ void BeInlineLineBuilder::Start(BeDbgCodeEmission* codeEmission) }*/ mData.push_back(CodeViewInfo::BA_OP_ChangeCodeOffset); - Compress(codeOfs); + Compress(codeOfs); mCurLine = codeEmission->mDbgLoc->mLine; - mCurCodePos = codeEmission->mPos; + mCurCodePos = codeEmission->mPos; /*mData.push_back(CodeViewInfo::BA_OP_ChangeLineOffset); WriteSigned(-mStartDbgLoc->mDbgInlinedAt->mLine - 1); @@ -122,14 +122,14 @@ void BeInlineLineBuilder::End(BeDbgCodeEmission* codeEmission) BeCOFFObject::BeCOFFObject() { mWriteToLib = false; - mBSSPos = 0; + mBSSPos = 0; mCurTagId = 0x1000; mCurStringId = 0; mCurJumpTableIdx = 0; mBeModule = NULL; mTTagStartPos = -1; mSTagStartPos = -1; - mSectionStartPos = -1; + mSectionStartPos = -1; mTypesLocked = false; mTimestamp = 0; mPerfManager = NULL; @@ -178,11 +178,11 @@ void BeCOFFObject::ToString(BeMDNode* mdNode, String& str) else { BF_FATAL("err"); - } + } } int BeCOFFObject::GetCVRegNum(X64CPURegister reg, int bits) -{ +{ if (bits == 8) { switch (reg) @@ -361,7 +361,7 @@ int BeCOFFObject::GetCVRegNum(X64CPURegister reg, int bits) case X64Reg_XMM72: return CV_AMD64_XMM7_2; case X64Reg_XMM73: return CV_AMD64_XMM7_3; } - + return 0; } @@ -400,7 +400,7 @@ void BeCOFFObject::DbgEncodeString(DynMemStream& memStream, const StringImpl& st } void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc) -{ +{ if (dbgFunc->mCvTypeId != -1) return; @@ -435,12 +435,12 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc) for (auto paramType : dbgFunc->mType->mParams) DbgGetTypeId(paramType); - bool hasThis = dbgFunc->HasThis(); + bool hasThis = dbgFunc->HasThis(); /*auto argListResultPair = mArgListSet.insert(dbgFunc); if (!argListResultPair.second) - { - dbgFunc->mCvArgListId = (*argListResultPair.first)->mCvArgListId; + { + dbgFunc->mCvArgListId = (*argListResultPair.first)->mCvArgListId; } else*/ @@ -457,12 +457,12 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc) outT.Write((int32)(dbgFunc->mType->mParams.size() - (hasThis ? 1 : 0))); for (int paramIdx = hasThis ? 1 : 0; paramIdx < (int)dbgFunc->mType->mParams.size(); paramIdx++) { - BeDbgType* dbgType = dbgFunc->mType->mParams[paramIdx]; + BeDbgType* dbgType = dbgFunc->mType->mParams[paramIdx]; outT.Write(DbgGetTypeId(dbgType)); } DbgTEndTag(); } - + dbgFunc->mCvTypeId = mCurTagId++; DbgTStartTag(); @@ -504,7 +504,7 @@ void BeCOFFObject::DbgMakeFuncType(BeDbgFunction* dbgFunc) void BeCOFFObject::DbgMakeFunc(BeDbgFunction* dbgFunc) { auto& outT = mDebugTSect.mData; - BF_ASSERT(dbgFunc->mCvTypeId == -1); + BF_ASSERT(dbgFunc->mCvTypeId == -1); DbgMakeFuncType(dbgFunc); @@ -534,7 +534,7 @@ void BeCOFFObject::DbgMakeFunc(BeDbgFunction* dbgFunc) void BeCOFFObject::DbgTAlign() { int curPos = mDebugTSect.mData.GetPos(); - // Perform alignment + // Perform alignment int addPadding = (4 - (curPos & 3)) % 4; while (addPadding > 0) { @@ -544,17 +544,17 @@ void BeCOFFObject::DbgTAlign() } void BeCOFFObject::DbgTStartTag() -{ +{ BF_ASSERT(mTTagStartPos == -1); mTTagStartPos = mDebugTSect.mData.GetPos(); mDebugTSect.mData.Write((int16)0); } void BeCOFFObject::DbgTEndTag() -{ +{ BF_ASSERT(mTTagStartPos != -1); DbgTAlign(); - int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos; + int tagSize = mDebugTSect.mData.GetPos() - mTTagStartPos; BF_ASSERT(tagSize <= 0xFFFF); *((int16*)&mDebugTSect.mData.mData[mTTagStartPos]) = (int16)(tagSize - 2); mTTagStartPos = -1; @@ -576,20 +576,20 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) auto& outT = mDebugTSect.mData; auto structType = BeValueDynCast(dbgType); - + if (structType != NULL) { - //lfClass classInfo; + //lfClass classInfo; //BF_CLEAR_VALUE(classInfo); - //classInfo.leaf = LF_STRUCTURE; - - CV_prop_t structProp = { 0 }; + //classInfo.leaf = LF_STRUCTURE; + + CV_prop_t structProp = { 0 }; if (structType->mAlign == 1) structProp.packed = true; int fieldListTag = 0; - int memberCount = 0; + int memberCount = 0; if (doDefine) { // Pass over all needed types first to make sure we generate any forward references we'll need @@ -598,18 +598,18 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) DbgGetTypeId(structType->mDerivedFrom); for (auto member : structType->mMembers) { - auto type = member->mType; + auto type = member->mType; DbgGetTypeId(type); } for (auto func : structType->mMethods) - DbgMakeFuncType(func); + DbgMakeFuncType(func); fieldListTag = mCurTagId++; //int tagStartPos = -1; DbgTStartTag(); outT.Write((int16)LF_FIELDLIST); - + if (structType->mDerivedFrom != NULL) { outT.Write((int16)LF_BCLASS); @@ -629,7 +629,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) int extFieldListTag = mCurTagId++; outT.Write((int16)LF_INDEX); - outT.Write((int16)0); // Padding + outT.Write((int16)0); // Padding outT.Write((int32)extFieldListTag); // Padding DbgTEndTag(); @@ -639,7 +639,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) }; for (auto member : structType->mMembers) - { + { _CheckFieldOverflow(); if (member->mIsStatic) @@ -657,7 +657,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) outT.Write(*(int16*)&attr); outT.Write(DbgGetTypeId(member->mType)); if (!member->mIsStatic) - DbgEncodeConstant(outT, member->mOffset); + DbgEncodeConstant(outT, member->mOffset); DbgEncodeString(outT, member->mName); memberCount++; DbgTAlign(); @@ -706,15 +706,15 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) outT.Write((int32)0); //derivedfrom - should we ever set this? outT.Write((int32)0); //vshape if (doDefine) - DbgEncodeConstant(outT, structType->mSize); + DbgEncodeConstant(outT, structType->mSize); else DbgEncodeConstant(outT, 0); String fullName; - ToString(structType, fullName); + ToString(structType, fullName); - DbgEncodeString(outT, fullName); + DbgEncodeString(outT, fullName); DbgTEndTag(); // LF_STRUCTURE - + if (doDefine) dbgType->mCvDefTypeId = mCurTagId++; else @@ -753,9 +753,9 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) return dbgType->mCvDefTypeId; } - + return dbgType->mCvDeclTypeId; - } + } else if (auto enumType = BeValueDynCast(dbgType)) { int fieldListId = 0; @@ -766,14 +766,14 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) //int tagStartPos = -1; DbgTStartTag(); outT.Write((int16)LF_FIELDLIST); - + for (auto member : enumType->mMembers) - { + { outT.Write((int16)LF_ENUMERATE); CV_fldattr_t attr = { 0 }; attr.access = 3; // public - outT.Write(*(int16*)&attr); + outT.Write(*(int16*)&attr); DbgEncodeConstant(outT, member->mValue); DbgEncodeString(outT, member->mName); DbgTAlign(); @@ -789,13 +789,13 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) //int32 elementId = DbgGetTypeId(enumType->mElementType); - CV_prop_t structProp = { 0 }; + CV_prop_t structProp = { 0 }; if (!enumType->mIsFullyDefined) structProp.fwdref = 1; DbgTStartTag(); outT.Write((int16)LF_ENUM); - outT.Write((int16)enumType->mMembers.size()); + outT.Write((int16)enumType->mMembers.size()); outT.Write(*(int16*)&structProp); outT.Write(elementId); outT.Write((int32)fieldListId); @@ -833,7 +833,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) break; case llvm::dwarf::DW_ATE_float: switch (dbgBasicType->mSize) - { + { case 4: dbgBasicType->mCvDefTypeId = T_REAL32; break; case 8: dbgBasicType->mCvDefTypeId = T_REAL64; break; } @@ -914,10 +914,10 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) int32 elementId = DbgGetTypeId(ptrType->mElement); DbgTStartTag(); - outT.Write((int16)LF_POINTER); + outT.Write((int16)LF_POINTER); outT.Write(elementId); outT.Write(*(int32*)&attr); - DbgTEndTag(); + DbgTEndTag(); dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++; return dbgType->mCvDefTypeId; } @@ -930,23 +930,23 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) int32 elementId = DbgGetTypeId(refType->mElement); DbgTStartTag(); - outT.Write((int16)LF_POINTER); + outT.Write((int16)LF_POINTER); outT.Write(elementId); - outT.Write(*(int32*)&attr); + outT.Write(*(int32*)&attr); DbgTEndTag(); dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++; return dbgType->mCvDefTypeId; } else if (auto constType = BeValueDynCast(dbgType)) - { - CV_modifier_t attr = { 0 }; + { + CV_modifier_t attr = { 0 }; attr.MOD_const = 1; int32 elementId = DbgGetTypeId(BeValueDynCast(constType->mElement)); DbgTStartTag(); - outT.Write((int16)LF_MODIFIER); + outT.Write((int16)LF_MODIFIER); outT.Write(elementId); - outT.Write(*(int16*)&attr); + outT.Write(*(int16*)&attr); DbgTEndTag(); dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++; return dbgType->mCvDefTypeId; @@ -958,7 +958,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) else if (auto arrayType = BeValueDynCast(dbgType)) { int32 elementId = DbgGetTypeId(arrayType->mElement); - + DbgTStartTag(); outT.Write((int16)LF_ARRAY); outT.Write((int32)elementId); @@ -968,11 +968,10 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine) DbgTEndTag(); dbgType->mCvDeclTypeId = dbgType->mCvDefTypeId = mCurTagId++; return dbgType->mCvDefTypeId; - } + } else BF_FATAL("NotImpl"); - BF_FATAL("Invalid type"); return -1; } @@ -986,12 +985,12 @@ void BeCOFFObject::DbgGenerateTypeInfo() outT.Write((int)CV_SIGNATURE_C13); for (auto mdNode : mBeModule->mDbgModule->mTypes) - { + { bool defineType = true; if (auto dbgStructType = BeValueDynCast(mdNode)) { if (!dbgStructType->mIsFullyDefined) - defineType = false; + defineType = false; } if (defineType) @@ -1010,8 +1009,8 @@ void BeCOFFObject::DbgGenerateTypeInfo() void BeCOFFObject::DbgStartSection(int sectionNum) { - auto& outS = mDebugSSect.mData; - BF_ASSERT(mSectionStartPos == -1); + auto& outS = mDebugSSect.mData; + BF_ASSERT(mSectionStartPos == -1); outS.Write((int32)sectionNum); outS.Write(0); // Temporary - size mSectionStartPos = outS.GetPos(); @@ -1019,9 +1018,9 @@ void BeCOFFObject::DbgStartSection(int sectionNum) void BeCOFFObject::DbgEndSection() { - auto& outS = mDebugSSect.mData; - int totalLen = outS.GetPos() - mSectionStartPos; - *((int32*)&outS.mData[mSectionStartPos - 4]) = totalLen; + auto& outS = mDebugSSect.mData; + int totalLen = outS.GetPos() - mSectionStartPos; + *((int32*)&outS.mData[mSectionStartPos - 4]) = totalLen; mSectionStartPos = -1; while ((outS.GetPos() & 3) != 0) outS.Write((uint8)0); @@ -1030,12 +1029,12 @@ void BeCOFFObject::DbgEndSection() void BeCOFFObject::DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range) { BF_ASSERT(range >= 0); - + auto funcSym = GetSymbol(dbgFunc->mValue); auto varType = BeValueDynCast(dbgVar->mType); - auto& outS = mDebugSSect.mData; + auto& outS = mDebugSSect.mData; if (varLoc.mKind == BeDbgVariableLoc::Kind_SymbolAddr) { BF_FATAL("Not supported"); @@ -1079,10 +1078,9 @@ void BeCOFFObject::DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* db reloc.mSymTableIdx = funcSym->mIdx; mDebugSSect.mRelocs.push_back(reloc); outS.Write((int16)0); // section - outS.Write((int16)range); // Range + outS.Write((int16)range); // Range } - void BeCOFFObject::DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array& emissions, int blockStartPos, int emissionStartIdx, int lineCount) { auto& outS = mDebugSSect.mData; @@ -1111,7 +1109,7 @@ void BeCOFFObject::DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array 0) { @@ -1137,23 +1135,23 @@ void BeCOFFObject::DbgSEndTag() } void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar) -{ +{ auto varType = BeValueDynCast(dbgVar->mType); // CodeView only allows 16-bit lengths, so we need to split ranges for very long spans if (dbgVar->mDeclEnd - dbgVar->mDeclStart > 0xFFFF) - { + { int splitPos = dbgVar->mDeclStart + 0xFFFF; BeDbgVariable varStart = *dbgVar; varStart.mDeclEnd = splitPos; Array* startArrs[2] = { &varStart.mSavedRanges, &varStart.mGaps }; for (auto& arr : startArrs) - { + { for (int arrIdx = 0; arrIdx < (int)arr->size(); arrIdx++) { auto& gap = (*arr)[arrIdx]; - + int gapStart = gap.mOffset; int gapEnd = gap.mOffset + gap.mLength; @@ -1186,17 +1184,17 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV { auto& gap = (*arr)[arrIdx]; - int gapStart = gap.mOffset; + int gapStart = gap.mOffset; if (gapStart < splitPos) gapStart = splitPos; if (gap.mLength == -1) - { + { gap.mOffset = gapStart; continue; } - int gapEnd = gap.mOffset + gap.mLength; + int gapEnd = gap.mOffset + gap.mLength; if (gapEnd < splitPos) gapEnd = splitPos; @@ -1229,13 +1227,13 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV outS.Write(*(int16*)&flags); bool isConst = false; - String varName = dbgVar->mName; + String varName = dbgVar->mName; bool isGlobal = false; // { auto checkVal = dbgVar->mValue; - + if (auto beCast = BeValueDynCast(checkVal)) checkVal = beCast->mTarget; if (auto beGlobal = BeValueDynCast(checkVal)) @@ -1278,8 +1276,8 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV { declEnd = dbgFunc->mCodeLen; if ((dbgVar->mGaps.size() == 1) && (dbgVar->mGaps[0].mOffset == dbgVar->mDeclStart) && (dbgVar->mGaps[0].mLength == -1) && (!isConst)) - { - // Variable not used + { + // Variable not used declEnd = dbgVar->mDeclStart; } } @@ -1294,7 +1292,7 @@ void BeCOFFObject::DbgOutputLocalVar(BeDbgFunction* dbgFunc, BeDbgVariable* dbgV continue; if (gap.mLength == -1) - { + { // Not a real gap, and not an unused variable indicator if (gap.mOffset > dbgVar->mDeclStart) continue; @@ -1348,7 +1346,7 @@ void BeCOFFObject::DbgOutputLocalVars(BeInlineLineBuilder* curInlineBuilder, BeD { auto& outS = mDebugSSect.mData; for (auto dbgVar : curInlineBuilder->mVariables) - { + { if (dbgVar == NULL) continue; DbgOutputLocalVar(dbgFunc, dbgVar); @@ -1362,15 +1360,15 @@ void BeCOFFObject::DbgGenerateModuleInfo() auto& outS = mDebugSSect.mData; outS.Write((int)CV_SIGNATURE_C13); - + Array fileDataPositions; Array inlinees; - + // Funcs for (auto dbgFunc : mBeModule->mDbgModule->mFuncs) { if (dbgFunc->mValue == NULL) - continue; + continue; if (dbgFunc->mCvFuncId == -1) continue; @@ -1380,9 +1378,9 @@ void BeCOFFObject::DbgGenerateModuleInfo() auto funcSym = GetSymbol(dbgFunc->mValue, false); if (funcSym == NULL) continue; - + DbgStartSection(DEBUG_S_SYMBOLS); - + DbgSStartTag(); if (dbgFunc->mValue->mLinkageType == BfIRLinkageType_Internal) outS.Write((int16)S_LPROC32_ID); @@ -1394,7 +1392,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() outS.Write((int32)BF_MAX(dbgFunc->mCodeLen, 0)); // CodeSize outS.Write((int32)0); // DbgStart outS.Write((int32)0); // DbgEnd - outS.Write(dbgFunc->mCvFuncId); + outS.Write(dbgFunc->mCvFuncId); BeMCRelocation reloc; reloc.mKind = BeMCRelocationKind_SECREL; @@ -1402,7 +1400,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() reloc.mSymTableIdx = funcSym->mIdx; mDebugSSect.mRelocs.push_back(reloc); outS.Write((int32)0); // off - + reloc.mKind = BeMCRelocationKind_SECTION; reloc.mOffset = outS.GetPos(); reloc.mSymTableIdx = funcSym->mIdx; @@ -1420,7 +1418,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() fullName += "::"; fullName += dbgFunc->mName; DbgEncodeString(outS, fullName); - DbgSEndTag(); + DbgSEndTag(); BeInlineLineBuilder* curInlineBuilder = NULL; BeDbgLoc* curDbgLoc = NULL; @@ -1437,28 +1435,28 @@ void BeCOFFObject::DbgGenerateModuleInfo() if (curDbgLoc != newDbgLoc) { curDbgLoc = newDbgLoc; - int newInlineDepth = newDbgLoc->GetInlineDepth(); + int newInlineDepth = newDbgLoc->GetInlineDepth(); int curInlineDepth = 0; if (curInlineBuilder != NULL) curInlineDepth = curInlineBuilder->mStartDbgLoc->GetInlineDepth(); - + int depthMatch = 0; if (curInlineBuilder != NULL) - depthMatch = curDbgLoc->GetInlineMatchDepth(curInlineBuilder->mStartDbgLoc); + depthMatch = curDbgLoc->GetInlineMatchDepth(curInlineBuilder->mStartDbgLoc); while (curInlineDepth > depthMatch) - { + { curInlineBuilder->End(&codeEmission); inlineStack.pop_back(); if (inlineStack.empty()) curInlineBuilder = NULL; else - curInlineBuilder = inlineStack.back(); + curInlineBuilder = inlineStack.back(); curInlineDepth--; } // Check for new inlines while (newInlineDepth > curInlineDepth) - { + { auto inlineBuilder = inlineBuilders.Alloc(); // If we add more than one inline depth at a time then we need to set startDbgLoc appropriately int inlineIdx = newInlineDepth - curInlineDepth - 2; @@ -1472,7 +1470,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() inlinees.Add(dbgFunc); inlineBuilder->mCurLine = dbgFunc->mLine; - inlineBuilder->Start(&codeEmission); + inlineBuilder->Start(&codeEmission); curInlineBuilder = inlineBuilder; inlineStack.push_back(curInlineBuilder); curInlineDepth++; @@ -1482,18 +1480,18 @@ void BeCOFFObject::DbgGenerateModuleInfo() } if (curInlineBuilder != NULL) - curInlineBuilder->Update(&codeEmission); - } + curInlineBuilder->Update(&codeEmission); + } } BF_ASSERT(inlineStack.empty()); for (auto dbgVar : dbgFunc->mVariables) { - if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL)) + if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL)) continue; if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL) continue; - + BeInlineLineBuilder* inlineBuilder = NULL; if (inlineMap.TryGetValue(dbgVar->mDeclDbgLoc->mDbgInlinedAt, &inlineBuilder)) { @@ -1504,19 +1502,19 @@ void BeCOFFObject::DbgGenerateModuleInfo() // Emit inlines and variables int inlineBuilderIdx = 0; - + curInlineBuilder = NULL; - + for (auto dbgVar : dbgFunc->mVariables) - { - if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL)) + { + if ((dbgVar == NULL) || (dbgVar->mDeclDbgLoc == NULL)) continue; if (dbgVar->mDeclDbgLoc->mDbgInlinedAt == NULL) DbgOutputLocalVar(dbgFunc, dbgVar); } while ((inlineBuilderIdx < (int)inlineBuilders.size()) || (curInlineBuilder != NULL) /*|| (varIdx < (int)dbgFunc->mVariables.size())*/) - { + { BeInlineLineBuilder* newInlineBuilder = NULL; int curInlineDepth = 0; @@ -1549,7 +1547,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() if (inlineStack.empty()) curInlineBuilder = NULL; else - curInlineBuilder = inlineStack.back(); + curInlineBuilder = inlineStack.back(); } if (newInlineDepth > curInlineDepth) @@ -1562,7 +1560,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() auto inlinedDbgFunc = newInlineBuilder->mStartDbgLoc->GetDbgFunc(); if (inlinedDbgFunc->mCvFuncId == -1) DbgMakeFunc(inlinedDbgFunc); - outS.Write(inlinedDbgFunc->mCvFuncId); + outS.Write(inlinedDbgFunc->mCvFuncId); outS.Write(&newInlineBuilder->mData[0], (int)newInlineBuilder->mData.size()); DbgSEndTag(); newInlineDepth++; @@ -1575,8 +1573,8 @@ void BeCOFFObject::DbgGenerateModuleInfo() // This can fail if an inlined method is not emitted contiguously, or if multiple copies of the same method // get inlined at exactly the same DbgLoc -- which isn't possible in Beef //BF_ASSERT(curInlineBuilder == newInlineBuilder); - } - + } + DbgSStartTag(); outS.Write((int16)S_PROC_ID_END); DbgSEndTag(); @@ -1611,21 +1609,21 @@ void BeCOFFObject::DbgGenerateModuleInfo() curDbgLoc = NULL; BeDbgFile* curFile = NULL; - int lastBlockStartPos = -1; - int lineCount = 0; + int lastBlockStartPos = -1; + int lineCount = 0; Array emissions; - emissions.Reserve(dbgFunc->mEmissions.size()); + emissions.Reserve(dbgFunc->mEmissions.size()); for (int emissionIdx = 0; emissionIdx < (int)dbgFunc->mEmissions.size(); emissionIdx++) { auto& codeEmission = dbgFunc->mEmissions[emissionIdx]; auto rootDbgLoc = codeEmission.mDbgLoc->GetRoot(); - + bool doEmission = true; if (!emissions.empty()) { if (rootDbgLoc == emissions.back().mDbgLoc) - doEmission = false; + doEmission = false; } if (doEmission) @@ -1636,7 +1634,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() emissions.push_back(newEmission); } } - + /// { int fileDataPos = 0; @@ -1656,7 +1654,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() for (int emissionIdx = 0; emissionIdx < (int)emissions.size(); emissionIdx++) { auto& codeEmission = emissions[emissionIdx]; - + auto dbgLoc = codeEmission.mDbgLoc; BeDbgFile* dbgFile = dbgLoc->GetDbgFile(); @@ -1669,9 +1667,9 @@ void BeCOFFObject::DbgGenerateModuleInfo() emissionStartIdx = emissionIdx; } - curDbgLoc = dbgLoc; + curDbgLoc = dbgLoc; curDbgFile = dbgFile; - + lastBlockStartPos = outS.GetPos(); outS.Write((int32)fileDataPositions[dbgFile->mIdx]); outS.Write((int32)0); // placeholder nLines @@ -1691,29 +1689,29 @@ void BeCOFFObject::DbgGenerateModuleInfo() if (curDbgLoc != NULL) DbgEndLineBlock(dbgFunc, emissions, lastBlockStartPos, emissionStartIdx, lineCount); DbgEndSection(); // DEBUG_S_LINES - } + } if (!inlinees.empty()) - { + { DbgStartSection(DEBUG_S_INLINEELINES); outS.Write((int32)0); // Lines type for (auto inlinedDbgFunc : inlinees) - { - BF_ASSERT(inlinedDbgFunc->mCvFuncId != -1); + { + BF_ASSERT(inlinedDbgFunc->mCvFuncId != -1); outS.Write(inlinedDbgFunc->mCvFuncId); - + auto dbgFile = inlinedDbgFunc->mFile; outS.Write((int32)fileDataPositions[dbgFile->mIdx]); outS.Write((int32)inlinedDbgFunc->mLine + 1); } DbgEndSection(); - } + } - // Global variables + // Global variables { - bool startedSymbols = false; + bool startedSymbols = false; for (auto dbgGlobalVar : mBeModule->mDbgModule->mGlobalVariables) - { + { auto gvSym = GetSymbol(dbgGlobalVar->mValue); if (gvSym == NULL) { @@ -1722,24 +1720,24 @@ void BeCOFFObject::DbgGenerateModuleInfo() } if (!startedSymbols) - { + { DbgStartSection(DEBUG_S_SYMBOLS); startedSymbols = true; } DbgSStartTag(); bool isTLS = false; - if (auto beGlobalVar = BeValueDynCast(dbgGlobalVar->mValue)) + if (auto beGlobalVar = BeValueDynCast(dbgGlobalVar->mValue)) isTLS = beGlobalVar->mIsTLS; - + if (isTLS) outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LTHREAD32 : (int16)S_GTHREAD32); else outS.Write(dbgGlobalVar->mIsLocalToUnit ? (int16)S_LDATA32 : (int16)S_GDATA32); - + outS.Write(DbgGetTypeId(BeValueDynCast(dbgGlobalVar->mType))); - BF_ASSERT(dbgGlobalVar->mValue != NULL); + BF_ASSERT(dbgGlobalVar->mValue != NULL); BeMCRelocation reloc; reloc.mKind = BeMCRelocationKind_SECREL; @@ -1761,7 +1759,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() if (startedSymbols) DbgEndSection(); // DEBUG_S_SYMBOLS - } + } bool startedUDT = false; for (auto dbgType : mBeModule->mDbgModule->mTypes) @@ -1798,7 +1796,7 @@ void BeCOFFObject::DbgGenerateModuleInfo() if (dbgFile->mMD5Hash.IsZero()) { - outS.Write((int32)0); // hashLen, hashType, padding + outS.Write((int32)0); // hashLen, hashType, padding } else { @@ -1838,8 +1836,8 @@ void BeCOFFObject::AlignConst(BeCOFFSection& sect, BeConstant* constVal) } void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) -{ - auto beType = constVal->GetType(); +{ + auto beType = constVal->GetType(); if (auto globalVar = BeValueDynCast(constVal)) { auto sym = GetSymbol(globalVar); @@ -1892,7 +1890,7 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) } else BF_FATAL("Invalid StructConst type"); - } + } else if (auto constStr = BeValueDynCast(constVal)) { sect.mData.Write((void*)constStr->mString.c_str(), (int)constStr->mString.length() + 1); @@ -1905,8 +1903,8 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) { if (auto globalVar = BeValueDynCast(constGep->mTarget)) { - BF_ASSERT(constGep->mIdx0 == 0); - + BF_ASSERT(constGep->mIdx0 == 0); + int64 dataOfs = 0; if (globalVar->mType->mTypeCode == BeTypeCode_Struct) { @@ -1944,7 +1942,7 @@ void BeCOFFObject::WriteConst(BeCOFFSection& sect, BeConstant* constVal) else if (beType->IsComposite()) { BF_ASSERT(constVal->mInt64 == 0); - + int64 zero = 0; int sizeLeft = beType->mSize; while (sizeLeft > 0) @@ -1985,7 +1983,7 @@ void BeCOFFObject::Generate(BeModule* module) InitSect(mDebugTSect, ".debug$T", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_READ, true, false); } InitSect(mPDataSect, ".pdata", IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ, true, false); - + mTextSect.mData.mData.Reserve(4096); BfSizedVector globalVarSyms; @@ -2005,7 +2003,7 @@ void BeCOFFObject::Generate(BeModule* module) sym->mIsStatic = globalVar->mLinkageType == BfIRLinkageType_Internal; sym->mSymKind = BeMCSymbolKind_External; sym->mIdx = (int)mSymbols.size() - 1; - sym->mIsTLS = globalVar->mIsTLS; + sym->mIsTLS = globalVar->mIsTLS; globalVarSyms.push_back(sym); mSymbolMap[globalVar] = sym; @@ -2015,7 +2013,7 @@ void BeCOFFObject::Generate(BeModule* module) { auto globalVar = module->mGlobalVariables[globalVarIdx]; - if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL)) + if ((globalVar->mRefCount == 0) && (globalVar->mInitializer == NULL)) continue; auto sym = globalVarSyms[globalVarIdx]; @@ -2037,7 +2035,7 @@ void BeCOFFObject::Generate(BeModule* module) mRDataSect.mAlign = BF_MAX(mRDataSect.mAlign, globalVar->mAlign); AlignConst(mRDataSect, constVal); - sym->mValue = mRDataSect.mData.GetSize(); + sym->mValue = mRDataSect.mData.GetSize(); WriteConst(mRDataSect, constVal); } else if (globalVar->mIsTLS) @@ -2085,8 +2083,8 @@ void BeCOFFObject::Generate(BeModule* module) mBSSSect.mSizeOverride = (mBSSSect.mSizeOverride + globalVar->mAlign - 1) & ~(globalVar->mAlign - 1); mBSSSect.mAlign = BF_MAX(mBSSSect.mAlign, globalVar->mAlign); sym->mValue = mBSSSect.mSizeOverride; - mBSSSect.mSizeOverride += globalVar->mType->mSize; - } + mBSSSect.mSizeOverride += globalVar->mType->mSize; + } } if (globalVar->mStorageKind == BfIRStorageKind_Export) @@ -2113,10 +2111,10 @@ void BeCOFFObject::Generate(BeModule* module) { auto func = mFuncWorkList[0]; mFuncWorkList.RemoveAt(0); - + module->mActiveFunction = func; if (!func->IsDecl()) - { + { BeMCSymbol* sym = GetSymbol(func); BF_ASSERT(sym != NULL); sym->mValue = mTextSect.mData.GetSize(); @@ -2138,7 +2136,7 @@ void BeCOFFObject::Generate(BeModule* module) InitSect(mDirectiveSect, ".drectve", IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_ALIGN_1BYTES, true, false); mDirectiveSect.mData.Write((void*)mDirectives.c_str(), (int)mDirectives.length()); } - + if (hasDebugInfo) { DbgGenerateTypeInfo(); @@ -2153,7 +2151,7 @@ void BeCOFFObject::Generate(BeModule* module) bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName) { BP_ZONE_F("BeCOFFObject::Generate %s", fileName.c_str()); - AutoPerf perf("BeCOFFObject::Generate", mPerfManager); + AutoPerf perf("BeCOFFObject::Generate", mPerfManager); if (mWriteToLib) { @@ -2171,13 +2169,13 @@ bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName) return false; for (auto sym : mSymbols) - { + { if (sym->mIsStatic) continue; if (((sym->mSymKind == BeMCSymbolKind_External) && (sym->mSectionNum != 0)) || ((sym->mSymKind == BeMCSymbolKind_Function))) - { + { libEntry->AddSymbol(sym->mName); } } @@ -2228,7 +2226,7 @@ void BeCOFFObject::Finish() memset(§Hdr, 0, sizeof(sectHdr)); BeCOFFSection* sect = mUsedSections[sectNum]; strcpy(sectHdr.mName, sect->mSectName.c_str()); - + int characteristics = sect->mCharacteristics; if (sect->mAlign != 0) { @@ -2246,8 +2244,8 @@ void BeCOFFObject::Finish() else if (sect->mAlign == 4) characteristics |= IMAGE_SCN_ALIGN_4BYTES; else if (sect->mAlign == 2) characteristics |= IMAGE_SCN_ALIGN_2BYTES; } - - sectData[sectNum] = sect; + + sectData[sectNum] = sect; int dataSize = sect->mData.GetSize(); if (dataSize != 0) { @@ -2267,9 +2265,9 @@ void BeCOFFObject::Finish() filePos += sizeof(COFFRelocation); } else - { + { sectHdr.mNumberOfRelocations = (int)sect->mRelocs.size(); - } + } filePos += (int)sect->mRelocs.size() * sizeof(COFFRelocation); } } @@ -2281,8 +2279,8 @@ void BeCOFFObject::Finish() sectHdr.mCharacteristics = characteristics; BF_ASSERT(characteristics != 0); } - - header.mPointerToSymbolTable = filePos; + + header.mPointerToSymbolTable = filePos; header.mNumberOfSymbols = (int)mSymbols.size(); mStream->WriteT(header); @@ -2323,7 +2321,7 @@ void BeCOFFObject::Finish() coffReloc.mVirtualAddress = reloc.mOffset; coffReloc.mSymbolTableIndex = reloc.mSymTableIdx; coffReloc.mType = IMAGE_REL_AMD64_ABSOLUTE; - + switch (reloc.mKind) { case BeMCRelocationKind_ADDR32NB: @@ -2350,7 +2348,7 @@ void BeCOFFObject::Finish() } BF_ASSERT(mStream->GetPos() == filePos); - + SizedArray symInfoVec; symInfoVec.reserve(mSymbols.size() + 16); @@ -2358,8 +2356,8 @@ void BeCOFFObject::Finish() { //BP_ZONE("Finish - AddSym"); - if (sym->mSymKind == BeMCSymbolKind_AuxPlaceholder) - continue; + if (sym->mSymKind == BeMCSymbolKind_AuxPlaceholder) + continue; PE_SymInfo symInfo; memset(&symInfo, 0, sizeof(symInfo)); @@ -2370,9 +2368,9 @@ void BeCOFFObject::Finish() symInfo.mNameOfs[1] = strTablePos + 4; } else - strcpy(symInfo.mName, sym->mName.c_str()); + strcpy(symInfo.mName, sym->mName.c_str()); if (sym->mSymKind == BeMCSymbolKind_SectionDef) - { + { symInfo.mSectionNum = sym->mSectionNum; symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC; symInfo.mNumOfAuxSymbols = 1; @@ -2390,41 +2388,41 @@ void BeCOFFObject::Finish() auxSymInfo.mSelection = 2; // Pick any (only applicable for COMDAT but ignored elsewhere) auxSymInfo.mUnused = 0; auxSymInfo.mUnused2 = 0; - auxSymInfo.mUnused3 = 0; + auxSymInfo.mUnused3 = 0; symInfoVec.push_back(*(PE_SymInfo*)&auxSymInfo); continue; } else if (sym->mSymKind == BeMCSymbolKind_SectionRef) { - symInfo.mSectionNum = sym->mSectionNum; - symInfo.mStorageClass = IMAGE_SYM_CLASS_SECTION; + symInfo.mSectionNum = sym->mSectionNum; + symInfo.mStorageClass = IMAGE_SYM_CLASS_SECTION; } else if (sym->mSymKind == BeMCSymbolKind_Function) { symInfo.mValue = sym->mValue; - symInfo.mSectionNum = mTextSect.mSectionIdx + 1; + symInfo.mSectionNum = mTextSect.mSectionIdx + 1; symInfo.mType = 0x20; //DT_FUNCTION if (sym->mIsStatic) symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC; else symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL; - } + } else if (sym->mSymKind == BeMCSymbolKind_COMDAT) { symInfo.mValue = sym->mValue; - symInfo.mSectionNum = sym->mSectionNum; + symInfo.mSectionNum = sym->mSectionNum; symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL; } else - { + { if (sym->mIsStatic) symInfo.mStorageClass = IMAGE_SYM_CLASS_STATIC; else symInfo.mStorageClass = IMAGE_SYM_CLASS_EXTERNAL; symInfo.mValue = sym->mValue; symInfo.mSectionNum = sym->mSectionNum; - } + } symInfoVec.push_back(symInfo); } if (!symInfoVec.IsEmpty()) @@ -2437,7 +2435,7 @@ void BeCOFFObject::Finish() } BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate) -{ +{ /*auto itr = mSymbolMap.find(value); if (itr != mSymbolMap.end()) return itr->second;*/ @@ -2446,7 +2444,7 @@ BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate) return *symbolPtr; if (allowCreate) - { + { if (auto func = BeValueDynCast(value)) { mFuncWorkList.Add(func); @@ -2475,7 +2473,7 @@ BeMCSymbol* BeCOFFObject::GetSymbol(BeValue* value, bool allowCreate) } BeMCSymbol* BeCOFFObject::GetSymbolRef(const StringImpl& name) -{ +{ /*auto itr = mNamedSymbolMap.find(name); if (itr != mNamedSymbolMap.end()) return itr->second;*/ @@ -2502,8 +2500,8 @@ void BeCOFFObject::MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol) if (getSectSymbol) { //TODO: We previously only did sectionDefs when we needed the SelectionNum value, but - // omitting this causes the MS linker to throw "multiple '' sections found with different - // attributes (0000000000) errors. This change could potentially break LIB creation in the + // omitting this causes the MS linker to throw "multiple '' sections found with different + // attributes (0000000000) errors. This change could potentially break LIB creation in the // linker. Verify it still works. if (((sect.mCharacteristics & IMAGE_SCN_LNK_COMDAT) != 0) || (true)) { @@ -2524,7 +2522,7 @@ void BeCOFFObject::MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol) else { // It's important for the linker's import library output to include - // section refs and not section defs, even when they aren't an external + // section refs and not section defs, even when they aren't an external // reference BeMCSymbol* sym; sym = mSymbols.Alloc(); @@ -2549,8 +2547,8 @@ BeMCSymbol* BeCOFFObject::GetCOMDAT(const StringImpl& name, void* data, int size BeCOFFSection mRData8Sect; auto* rdataSect = mDynSects.Alloc(); - int characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_MEM_READ; - InitSect(*rdataSect, ".rdata", characteristics, true, true); + int characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_MEM_READ; + InitSect(*rdataSect, ".rdata", characteristics, true, true); rdataSect->mAlign = align; auto sym = mSymbols.Alloc(); @@ -2559,9 +2557,9 @@ BeMCSymbol* BeCOFFObject::GetCOMDAT(const StringImpl& name, void* data, int size sym->mIdx = (int)mSymbols.size() - 1; sym->mSectionNum = rdataSect->mSectionIdx + 1; sym->mValue = rdataSect->mData.GetPos(); - mNamedSymbolMap[name] = sym; - rdataSect->mData.Write(data, size); - return sym; + mNamedSymbolMap[name] = sym; + rdataSect->mData.Write(data, size); + return sym; } BeCOFFSection* BeCOFFObject::CreateSect(const StringImpl& name, int characteristics, bool makeSectSymbol) diff --git a/IDEHelper/Backend/BeCOFFObject.h b/IDEHelper/Backend/BeCOFFObject.h index 78ce5a40..b69ca7a6 100644 --- a/IDEHelper/Backend/BeCOFFObject.h +++ b/IDEHelper/Backend/BeCOFFObject.h @@ -26,7 +26,7 @@ public: bool mIsStatic; bool mIsTLS; BeMCSymbolKind mSymKind; - int mValue; + int mValue; int mIdx; int mSectionNum; @@ -169,7 +169,7 @@ public: return false; for (int i = 0; i < (int)lhs->mType->mParams.size(); i++) if (lhs->mType->mParams[i] != rhs->mType->mParams[i]) - return false; + return false; return true; } }; @@ -215,16 +215,16 @@ public: PerfManager* mPerfManager; DataStream* mStream; BumpAllocator mAlloc; - BeModule* mBeModule; - OwnedVector mSymbols; + BeModule* mBeModule; + OwnedVector mSymbols; OwnedVector mDynSects; uint32 mTimestamp; BeCOFFSection mTextSect; BeCOFFSection mDataSect; - BeCOFFSection mRDataSect; - BeCOFFSection mBSSSect; - BeCOFFSection mTLSSect; + BeCOFFSection mRDataSect; + BeCOFFSection mBSSSect; + BeCOFFSection mTLSSect; BeCOFFSection mPDataSect; BeCOFFSection mXDataSect; BeCOFFSection mDebugSSect; @@ -234,8 +234,8 @@ public: int mBSSPos; Array mUsedSections; Dictionary mSymbolMap; - Dictionary mNamedSymbolMap; - HashSet mArgListSet; + Dictionary mNamedSymbolMap; + HashSet mArgListSet; HashSet mFuncTypeSet; Deque mFuncWorkList; int mTTagStartPos; @@ -244,10 +244,10 @@ public: int mSectionStartPos; int mCurStringId; int mCurJumpTableIdx; - bool mTypesLocked; + bool mTypesLocked; String mDirectives; -public: +public: void ToString(BeMDNode* mdNode, String& str); int GetCVRegNum(X64CPURegister reg, int bits); @@ -255,10 +255,10 @@ public: void DbgTStartTag(); void DbgTEndTag(); void DbgEncodeConstant(DynMemStream& memStream, int64 val); - void DbgEncodeString(DynMemStream& memStream, const StringImpl& str); + void DbgEncodeString(DynMemStream& memStream, const StringImpl& str); void DbgMakeFuncType(BeDbgFunction* dbgFunc); void DbgMakeFunc(BeDbgFunction* dbgFunc); - int DbgGetTypeId(BeDbgType* dbgType, bool doDefine = false); + int DbgGetTypeId(BeDbgType* dbgType, bool doDefine = false); void DbgGenerateTypeInfo(); void DbgSAlign(); @@ -270,18 +270,18 @@ public: void DbgEndSection(); void DbgStartVarDefRange(BeDbgFunction* dbgFunc, BeDbgVariable* dbgVar, const BeDbgVariableLoc& varLoc, int offset, int range); void DbgEndLineBlock(BeDbgFunction* dbgFunc, const Array& emissions, int blockStartPos, int emissionStartIdx, int lineCount); - void DbgGenerateModuleInfo(); + void DbgGenerateModuleInfo(); void InitSect(BeCOFFSection& sect, const StringImpl& name, int characteristics, bool addNow, bool makeSectSymbol); void AlignConst(BeCOFFSection& sect, BeConstant* constVal); void WriteConst(BeCOFFSection& sect, BeConstant* constVal); - + void Generate(BeModule* module); public: - BeCOFFObject(); + BeCOFFObject(); void Finish(); - bool Generate(BeModule* module, const StringImpl& fileName); + bool Generate(BeModule* module, const StringImpl& fileName); BeMCSymbol* GetSymbol(BeValue* value, bool allowCreate = true); BeMCSymbol* GetSymbolRef(const StringImpl& name); void MarkSectionUsed(BeCOFFSection& sect, bool getSectSymbol = false); diff --git a/IDEHelper/Backend/BeContext.cpp b/IDEHelper/Backend/BeContext.cpp index 21c7c707..ed457419 100644 --- a/IDEHelper/Backend/BeContext.cpp +++ b/IDEHelper/Backend/BeContext.cpp @@ -28,7 +28,7 @@ BeType* BeContext::GetPrimitiveType(BeTypeCode typeCode) primType->mTypeCode = typeCode; switch (typeCode) { - case BeTypeCode_None: + case BeTypeCode_None: primType->mSize = 0; primType->mAlign = 0; break; @@ -80,24 +80,24 @@ BeStructType* BeContext::CreateStruct(const StringImpl& name) BeStructType* structType = mTypes.Alloc(); structType->mContext = this; structType->mTypeCode = BeTypeCode_Struct; - structType->mName = name; + structType->mName = name; structType->mIsOpaque = true; return structType; } BeStructType* BeContext::CreateStruct(const SizedArrayImpl& types) -{ - BeStructType** valuePtr = NULL; - if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr)) - return *valuePtr; +{ + BeStructType** valuePtr = NULL; + if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr)) + return *valuePtr; Array key; for (auto type : types) key.Add(type); - + BeStructType* structType = CreateStruct(""); SetStructBody(structType, types, false); - mAnonymousStructMap.TryAdd(key, structType); + mAnonymousStructMap.TryAdd(key, structType); return structType; } @@ -109,7 +109,7 @@ BePointerType* BeContext::GetPointerTo(BeType* beType) pointerType->mTypeCode = BeTypeCode_Pointer; pointerType->mElementType = beType; pointerType->mSize = mPointerSize; - pointerType->mAlign = mPointerSize; + pointerType->mAlign = mPointerSize; beType->mPointerType = pointerType; /*if (beType->IsSizedArray()) @@ -197,12 +197,12 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs) { if (lhs == rhs) return true; - + if (lhs->mTypeCode != rhs->mTypeCode) return false; switch (lhs->mTypeCode) - { + { case BeTypeCode_None: case BeTypeCode_NullPtr: case BeTypeCode_Boolean: @@ -214,7 +214,7 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs) case BeTypeCode_Double: return true; case BeTypeCode_Pointer: - return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType); + return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType); case BeTypeCode_SizedArray: { auto lhsSizedArray = (BeSizedArrayType*)lhs; @@ -222,7 +222,7 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs) if (lhsSizedArray->mLength != rhsSizedArray->mLength) return false; return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType); - } + } case BeTypeCode_Vector: { auto lhsSizedArray = (BeVectorType*)lhs; @@ -233,5 +233,4 @@ bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs) } } return false; -} - +} \ No newline at end of file diff --git a/IDEHelper/Backend/BeContext.h b/IDEHelper/Backend/BeContext.h index 20d24152..e65f69f9 100644 --- a/IDEHelper/Backend/BeContext.h +++ b/IDEHelper/Backend/BeContext.h @@ -88,7 +88,6 @@ public: virtual ~BeType() { - } int GetStride() @@ -120,7 +119,6 @@ public: { return (mTypeCode == BeTypeCode_Float) || (mTypeCode == BeTypeCode_Double); } - bool IsStruct() { @@ -159,10 +157,10 @@ public: } virtual void HashContent(BeHashContext& hashCtx) - { + { BF_ASSERT(mTypeCode < BeTypeCode_Struct); hashCtx.Mixin(mTypeCode); - } + } }; class BeStructMember @@ -174,21 +172,21 @@ public: class BeStructType : public BeType { -public: +public: BeContext* mContext; String mName; - Array mMembers; + Array mMembers; bool mIsPacked; bool mIsOpaque; - + virtual void HashContent(BeHashContext& hashCtx) override - { + { hashCtx.MixinStr(mName); hashCtx.Mixin(mMembers.size()); for (auto& member : mMembers) { member.mType->HashReference(hashCtx); - hashCtx.Mixin(member.mByteOffset); + hashCtx.Mixin(member.mByteOffset); } hashCtx.Mixin(mIsPacked); hashCtx.Mixin(mIsOpaque); @@ -213,9 +211,9 @@ public: BeContext* mContext; BeType* mElementType; int mLength; - + virtual void HashContent(BeHashContext& hashCtx) override - { + { hashCtx.Mixin(BeTypeCode_SizedArray); hashCtx.Mixin(mLength); mElementType->HashReference(hashCtx); @@ -247,27 +245,27 @@ class BeFunctionType : public BeType { public: String mName; - BeType* mReturnType; + BeType* mReturnType; Array mParams; bool mIsVarArg; - + virtual void HashContent(BeHashContext& hashCtx) override { hashCtx.Mixin(BeTypeCode_Function); hashCtx.MixinStr(mName); - mReturnType->HashReference(hashCtx); + mReturnType->HashReference(hashCtx); hashCtx.Mixin(mParams.size()); for (auto& param : mParams) { param.mType->HashReference(hashCtx); } - hashCtx.Mixin(mIsVarArg); + hashCtx.Mixin(mIsVarArg); } }; class BeContext { -public: +public: int mPointerSize; //BumpAllocator mAlloc; BeType* mPrimitiveTypes[BeTypeCode_COUNT]; @@ -278,8 +276,8 @@ public: void NotImpl(); public: - BeContext(); - BeType* GetPrimitiveType(BeTypeCode typeCode); + BeContext(); + BeType* GetPrimitiveType(BeTypeCode typeCode); BeType* GetVoidPtrType(); BeStructType* CreateStruct(const StringImpl& name); BeStructType* CreateStruct(const SizedArrayImpl& types); diff --git a/IDEHelper/Backend/BeDbgModule.h b/IDEHelper/Backend/BeDbgModule.h index e40ce902..0c0cf57f 100644 --- a/IDEHelper/Backend/BeDbgModule.h +++ b/IDEHelper/Backend/BeDbgModule.h @@ -8,4 +8,3 @@ NS_BF_BEGIN NS_BF_END - diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index b4b7e497..64d09dbb 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -231,7 +231,7 @@ BeIRCodeGen::BeIRCodeGen() mBeContext = NULL; mBeModule = NULL; mHasDebugLoc = false; - mDebugging = false; + mDebugging = false; mCmdCount = 0; } @@ -239,7 +239,7 @@ BeIRCodeGen::~BeIRCodeGen() { BF_ASSERT(mSavedDebugLocs.size() == 0); delete mBeModule; - delete mBeContext; + delete mBeContext; delete mStream; } @@ -254,7 +254,7 @@ void BeIRCodeGen::Hash(BeHashContext& hashCtx) hashCtx.Mixin(mPtrSize); hashCtx.Mixin(mIsOptimized); if (mBeModule != NULL) - mBeModule->Hash(hashCtx); + mBeModule->Hash(hashCtx); Array structHashList; @@ -385,7 +385,7 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned) isSigned = true; beTypeCode = BeTypeCode_Float; break; - case BfTypeCode_Double: + case BfTypeCode_Double: isSigned = true; beTypeCode = BeTypeCode_Double; break; @@ -395,7 +395,7 @@ BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned) } BeIRTypeEntry& BeIRCodeGen::GetTypeEntry(int typeId) -{ +{ BeIRTypeEntry& typeEntry = mTypes[typeId]; if (typeEntry.mTypeId == -1) typeEntry.mTypeId = typeId; @@ -482,7 +482,7 @@ void BeIRCodeGen::ProcessBfIRData(const BfSizedArray& buffer) { BP_ZONE("BeIRCodeGen::ProcessBfIRData"); - Init(buffer); + Init(buffer); Process(); } @@ -490,7 +490,7 @@ BfTypeCode BeIRCodeGen::GetTypeCode(BeType * type, bool isSigned) { switch (type->mTypeCode) { - case BeTypeCode_Int8: + case BeTypeCode_Int8: return (isSigned) ? BfTypeCode_Int8 : BfTypeCode_UInt8; case BeTypeCode_Int16: return (isSigned) ? BfTypeCode_Int16 : BfTypeCode_UInt16; @@ -518,7 +518,7 @@ void BeIRCodeGen::SetResult(int id, BeValue* value) void BeIRCodeGen::SetResult(int id, BeType* type) { BeIRCodeGenEntry entry; - entry.mKind = BeIRCodeGenEntryKind_Type; + entry.mKind = BeIRCodeGenEntryKind_Type; entry.mBeType = type; mResults.TryAdd(id, entry); } @@ -549,7 +549,6 @@ int64 BeIRCodeGen::ReadSLEB128() byteVal = mStream->Read(); val |= ((int64)(byteVal & 0x7f)) << shift; shift += 7; - } while (byteVal >= 128); // Sign extend negative numbers. if ((byteVal & 0x40) && (shift < 64)) @@ -700,7 +699,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) CMD_PARAM(bool, isTLS); BF_ASSERT(varType != NULL); - + auto globalVariable = mBeModule->mGlobalVariables.Alloc(); globalVariable->mModule = mBeModule; globalVariable->mType = varType; @@ -710,7 +709,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) globalVariable->mName = name; globalVariable->mIsTLS = isTLS; globalVariable->mAlign = varType->mAlign; - globalVariable->mUnnamedAddr = false; + globalVariable->mUnnamedAddr = false; globalVariable->mStorageKind = BfIRStorageKind_Normal; if (initializer != NULL) BF_ASSERT(varType->mAlign > 0); @@ -723,16 +722,16 @@ void BeIRCodeGen::Read(BeValue*& beValue) beValue->mRefCount++; BE_MEM_END("ParamType_Const_GlobalVar"); return; - } + } else if ((constType == BfConstType_BitCast) || (constType == BfConstType_BitCastNull)) - { + { CMD_PARAM(BeConstant*, target); CMD_PARAM(BeType*, toType); auto castedVal = mBeModule->mAlloc.Alloc(); castedVal->mInt64 = target->mInt64; castedVal->mType = toType; - castedVal->mTarget = target; + castedVal->mTarget = target; BF_ASSERT(target->GetType() != NULL); BF_ASSERT(!target->GetType()->IsComposite()); beValue = castedVal; @@ -742,12 +741,12 @@ void BeIRCodeGen::Read(BeValue*& beValue) else if (constType == BfConstType_GEP32_1) { CMD_PARAM(BeConstant*, target); - CMD_PARAM(int, idx0); + CMD_PARAM(int, idx0); BF_ASSERT(target->GetType()->IsPointer()); auto gepConstant = mBeModule->mAlloc.Alloc(); gepConstant->mTarget = target; - gepConstant->mIdx0 = idx0; + gepConstant->mIdx0 = idx0; beValue = gepConstant; BE_MEM_END("ParamType_Const_GEP32_1"); @@ -758,7 +757,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) CMD_PARAM(BeConstant*, target); CMD_PARAM(int, idx0); CMD_PARAM(int, idx1); - + BF_ASSERT(target->GetType()->IsPointer()); auto gepConstant = mBeModule->mAlloc.Alloc(); gepConstant->mTarget = target; @@ -772,11 +771,11 @@ void BeIRCodeGen::Read(BeValue*& beValue) else if (constType == BfConstType_ExtractValue) { CMD_PARAM(BeConstant*, target); - CMD_PARAM(int, idx0); - + CMD_PARAM(int, idx0); + auto gepConstant = mBeModule->mAlloc.Alloc(); gepConstant->mTarget = target; - gepConstant->mIdx0 = idx0; + gepConstant->mIdx0 = idx0; beValue = gepConstant; BE_MEM_END("ParamType_Const_ExtractValue"); @@ -794,7 +793,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) auto castedVal = mBeModule->mAlloc.Alloc(); castedVal->mInt64 = target->mInt64; castedVal->mType = toType; - castedVal->mTarget = target; + castedVal->mTarget = target; BF_ASSERT(target->GetType() != NULL); beValue = castedVal; BE_MEM_END("ParamType_Const_PtrToInt"); @@ -858,11 +857,11 @@ void BeIRCodeGen::Read(BeValue*& beValue) } auto constStruct = mBeModule->mOwnedValues.Alloc(); - constStruct->mType = type; + constStruct->mType = type; for (int i = 0; i < (int)values.size(); i++) { auto val = values[i]; - BeConstant* constant = BeValueDynCast(val); + BeConstant* constant = BeValueDynCast(val); if (type->IsSizedArray()) { @@ -882,7 +881,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) { BF_ASSERT(type->IsStruct()); auto structType = (BeStructType*)type; - auto valType = constant->GetType(); + auto valType = constant->GetType(); if (structType->mIsOpaque) { Fail("ConstAgg with opaque struct"); @@ -922,7 +921,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) } else if (constType == BfConstType_Undef) { - CMD_PARAM(BeType*, type); + CMD_PARAM(BeType*, type); auto constUndef = mBeModule->mOwnedValues.Alloc(); constUndef->mType = type; beValue = constUndef; @@ -940,7 +939,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) CMD_PARAM(BeType*, type); CMD_PARAM(BeValue*, value); mReflectDataMap[type] = value; - beValue = value; + beValue = value; return; } @@ -969,26 +968,26 @@ void BeIRCodeGen::Read(BeValue*& beValue) } else if (typeCode == BfTypeCode_None) { - beValue = NULL; + beValue = NULL; BE_MEM_END("ParamType_Const_None"); } else if (typeCode == BfTypeCode_NullPtr) { - CMD_PARAM(BeType*, nullType); - beValue = mBeModule->GetConstantNull((BePointerType*)nullType); + CMD_PARAM(BeType*, nullType); + beValue = mBeModule->GetConstantNull((BePointerType*)nullType); BE_MEM_END("ParamType_Const_NullPtr"); } else if (BfIRBuilder::IsInt(typeCode)) - { + { int64 intVal = ReadSLEB128(); - auto constVal = mBeModule->GetConstant(llvmConstType, intVal); + auto constVal = mBeModule->GetConstant(llvmConstType, intVal); beValue = constVal; BE_MEM_END("ParamType_Const_Int"); } else { BF_FATAL("Unhandled"); - } + } } else if (paramType == BfIRParamType_Arg) { @@ -997,7 +996,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) BE_MEM_END("ParamType_Arg"); } else if (paramType == BfIRParamType_StreamId_Abs8) - { + { int cmdId = mStream->Read(); auto& result = mResults[cmdId]; BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); @@ -1005,13 +1004,13 @@ void BeIRCodeGen::Read(BeValue*& beValue) BE_MEM_END("ParamType_StreamId"); } else if (paramType == BfIRParamType_StreamId_Rel) - { + { int cmdId = mCmdCount - (int)ReadSLEB128(); auto& result = mResults[cmdId]; BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); beValue = result.mBeValue; BE_MEM_END("ParamType_StreamId"); - } + } else { int cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1; @@ -1019,7 +1018,7 @@ void BeIRCodeGen::Read(BeValue*& beValue) BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); beValue = result.mBeValue; BE_MEM_END("ParamType_StreamId"); - } + } if (beValue != NULL) beValue->mRefCount++; @@ -1052,7 +1051,7 @@ void BeIRCodeGen::Read(BeFunction*& beFunc) return; } auto& result = mResults[streamId]; - BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); + BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value); BF_ASSERT(BeValueDynCast(result.mBeValue)); beFunc = (BeFunction*)result.mBeValue; BE_MEM_END("BeFunction"); @@ -1097,7 +1096,7 @@ void BeIRCodeGen::HandleNextCmd() BfIRCmd cmd = (BfIRCmd)mStream->Read(); mCmdCount++; -#ifdef CODEGEN_TRACK +#ifdef CODEGEN_TRACK gBEMemReporter.BeginSection(gIRCmdNames[cmd]); gBEMemReporter.Add(1); #endif @@ -1111,11 +1110,11 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(bool, isOptimized); BF_ASSERT(mBeModule == NULL); - mPtrSize = ptrSize; + mPtrSize = ptrSize; mIsOptimized = isOptimized; mBeContext = new BeContext(); mBeModule = new BeModule(moduleName, mBeContext); - mBeModule->mBeIRCodeGen = this; + mBeModule->mBeIRCodeGen = this; mBeContext->mPointerSize = ptrSize; for (auto constInt : mConfigConsts) @@ -1163,7 +1162,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_SetType: { CMD_PARAM(int, typeId); - CMD_PARAM(BeType*, type); + CMD_PARAM(BeType*, type); auto& typeEntry = GetTypeEntry(typeId); typeEntry.mBeType = type; if (typeEntry.mInstBeType == NULL) @@ -1176,7 +1175,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeType*, type); GetTypeEntry(typeId).mInstBeType = type; } - break; + break; case BfIRCmd_PrimitiveType: { BfTypeCode typeCode = (BfTypeCode)mStream->Read(); @@ -1186,7 +1185,7 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_CreateStruct: { - CMD_PARAM(String, typeName); + CMD_PARAM(String, typeName); SetResult(curId, mBeContext->CreateStruct(typeName)); } break; @@ -1198,13 +1197,13 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_StructSetBody: - { + { CMD_PARAM(BeType*, type); CMD_PARAM(CmdParamVec, members); CMD_PARAM(int, instSize); CMD_PARAM(int, instAlign); CMD_PARAM(bool, isPacked); - BF_ASSERT(type->mTypeCode == BeTypeCode_Struct); + BF_ASSERT(type->mTypeCode == BeTypeCode_Struct); auto structType = (BeStructType*)type; mBeContext->SetStructBody(structType, members, isPacked); structType->mSize = instSize; @@ -1229,14 +1228,14 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeIRTypeEntry*, typeEntry); SetResult(curId, mBeContext->GetPointerTo(typeEntry->mInstBeType)); } - break; + break; case BfIRCmd_GetType: { CMD_PARAM(BeValue*, value); auto type = value->GetType(); SetResult(curId, type); } - break; + break; case BfIRCmd_GetPointerToFuncType: { CMD_PARAM(BeFunctionType*, funcType); @@ -1255,24 +1254,24 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, length); SetResult(curId, mBeContext->CreateSizedArrayType(elementType, length)); } - break; + break; case BfIRCmd_GetVectorType: { CMD_PARAM(BeType*, elementType); CMD_PARAM(int, length); SetResult(curId, mBeContext->CreateVectorType(elementType, length)); } - break; + break; case BfIRCmd_CreateConstAgg: - { + { CMD_PARAM(BeType*, type); CMD_PARAM(CmdParamVec, values); auto constStruct = mBeModule->mOwnedValues.Alloc(); constStruct->mType = type; - + if (type->IsStruct()) - { + { FixValues((BeStructType*)type, values); BF_ASSERT(((BeStructType*)type)->mMembers.size() == values.size()); @@ -1314,10 +1313,10 @@ void BeIRCodeGen::HandleNextCmd() beConst->mType = type; SetResult(curId, beConst); } - break; + break; case BfIRCmd_CreateConstString: { - CMD_PARAM(String, str); + CMD_PARAM(String, str); auto constStruct = mBeModule->mOwnedValues.Alloc(); constStruct->mString = str; auto charType = mBeContext->GetPrimitiveType(BeTypeCode_Int8); @@ -1351,7 +1350,7 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_NumericCast: - { + { CMD_PARAM(BeValue*, val); CMD_PARAM(bool, valIsSigned); @@ -1365,20 +1364,20 @@ void BeIRCodeGen::HandleNextCmd() BfTypeCode valTypeCode = GetTypeCode(valType, valIsSigned); if (auto srcCastConstant = BeValueDynCast(val)) - { + { BeType* toType = GetBeType(typeCode, valIsSigned); auto castedVal = mBeModule->mAlloc.Alloc(); castedVal->mInt64 = srcCastConstant->mInt64; castedVal->mType = toType; castedVal->mTarget = srcCastConstant->mTarget; - + SetResult(curId, castedVal); break; } - + bool toSigned = false; - auto toBeType = GetBeType(typeCode, toSigned); + auto toBeType = GetBeType(typeCode, toSigned); BeValue* retVal = mBeModule->CreateNumericCast(val, toBeType, valIsSigned, toSigned); SetResult(curId, retVal); } @@ -1401,13 +1400,13 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeValue*, lhs); CMD_PARAM(BeValue*, rhs); - SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SLT, lhs, rhs)); + SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SLT, lhs, rhs)); } break; case BfIRCmd_CmpULT: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateCmp(BeCmpKind_ULT, lhs, rhs)); } break; @@ -1421,7 +1420,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_CmpULE: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateCmp(BeCmpKind_ULE, lhs, rhs)); } break; @@ -1435,7 +1434,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_CmpUGT: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateCmp(BeCmpKind_UGT, lhs, rhs)); } break; @@ -1449,14 +1448,14 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_CmpUGE: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateCmp(BeCmpKind_UGE, lhs, rhs)); } break; case BfIRCmd_Add: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); CMD_PARAM(int8, overflowCheckKind); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_Add, lhs, rhs, (BfOverflowCheckKind)overflowCheckKind)); } @@ -1487,7 +1486,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_UDiv: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_UDivide, lhs, rhs)); } break; @@ -1508,42 +1507,42 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_And: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_BitwiseAnd, lhs, rhs)); } break; case BfIRCmd_Or: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_BitwiseOr, lhs, rhs)); } break; case BfIRCmd_Xor: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_ExclusiveOr, lhs, rhs)); } break; case BfIRCmd_Shl: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_LeftShift, lhs, rhs)); } break; case BfIRCmd_AShr: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_ARightShift, lhs, rhs)); } break; case BfIRCmd_LShr: { CMD_PARAM(BeValue*, lhs); - CMD_PARAM(BeValue*, rhs); + CMD_PARAM(BeValue*, rhs); SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_RightShift, lhs, rhs)); } break; @@ -1552,7 +1551,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeValue*, val); auto negInst = mBeModule->AllocInst(); - negInst->mValue = val; + negInst->mValue = val; SetResult(curId, negInst); } break; @@ -1594,7 +1593,7 @@ void BeIRCodeGen::HandleNextCmd() numericCastInst->mValue = val; numericCastInst->mValSigned = false; numericCastInst->mToType = beType; - numericCastInst->mToSigned = isSigned; + numericCastInst->mToSigned = isSigned; SetResult(curId, numericCastInst); } break; @@ -1602,7 +1601,7 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeValue*, val); CMD_PARAM(BeType*, toType); - + auto bitcastInst = mBeModule->AllocInst(); bitcastInst->mValue = val; bitcastInst->mToType = toType; @@ -1649,26 +1648,26 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeValue*, val); BF_ASSERT(val->GetType()->IsPointer()); - SetResult(curId, mBeModule->CreateCmp(BeCmpKind_EQ, val, mBeModule->GetConstantNull((BePointerType*)val->GetType()))); + SetResult(curId, mBeModule->CreateCmp(BeCmpKind_EQ, val, mBeModule->GetConstantNull((BePointerType*)val->GetType()))); } break; case BfIRCmd_IsNotNull: { CMD_PARAM(BeValue*, val); BF_ASSERT(val->GetType()->IsPointer()); - SetResult(curId, mBeModule->CreateCmp(BeCmpKind_NE, val, mBeModule->GetConstantNull((BePointerType*)val->GetType()))); + SetResult(curId, mBeModule->CreateCmp(BeCmpKind_NE, val, mBeModule->GetConstantNull((BePointerType*)val->GetType()))); } break; case BfIRCmd_ExtractValue: { CMD_PARAM(BeValue*, val); CMD_PARAM(int, idx); - + BF_ASSERT(val->GetType()->IsComposite()); auto extractValueInst = mBeModule->AllocInst(); extractValueInst->mAggVal = val; - extractValueInst->mIdx = idx; + extractValueInst->mIdx = idx; SetResult(curId, extractValueInst); } break; @@ -1681,7 +1680,7 @@ void BeIRCodeGen::HandleNextCmd() auto insertValueInst = mBeModule->AllocInst(); insertValueInst->mAggVal = agg; insertValueInst->mMemberVal = val; - insertValueInst->mIdx = idx; + insertValueInst->mIdx = idx; SetResult(curId, insertValueInst); } break; @@ -1691,18 +1690,18 @@ void BeIRCodeGen::HandleNextCmd() if (type->IsStruct()) { BF_ASSERT(!((BeStructType*)type)->mIsOpaque); - } + } auto allocaInst = mBeModule->CreateAlloca(type); allocaInst->mAlign = type->mAlign; - SetResult(curId, allocaInst); + SetResult(curId, allocaInst); } break; case BfIRCmd_AllocaArray: { CMD_PARAM(BeType*, type); CMD_PARAM(BeValue*, arraySize); - + if (auto constant = BeValueDynCast(arraySize)) { //BF_ASSERT(constant->mInt64 >= 0); @@ -1710,9 +1709,9 @@ void BeIRCodeGen::HandleNextCmd() auto allocaInst = mBeModule->AllocInst(); allocaInst->mType = type; - allocaInst->mAlign = type->mAlign; + allocaInst->mAlign = type->mAlign; allocaInst->mArraySize = arraySize; - + SetResult(curId, allocaInst); } break; @@ -1722,7 +1721,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, alignment); auto inst = BeValueDynCast(val); - inst->mAlign = alignment; + inst->mAlign = alignment; //TODO: Implement /*inst->setAlignment(alignment);*/ } @@ -1754,6 +1753,14 @@ void BeIRCodeGen::HandleNextCmd() SetResult(curId, inst); } break; + case BfIRCmd_LifetimeSoftEnd: + { + CMD_PARAM(BeValue*, val); + auto inst = mBeModule->AllocInst(); + inst->mPtr = val; + SetResult(curId, inst); + } + break; case BfIRCmd_LifetimeExtend: { CMD_PARAM(BeValue*, val); @@ -1765,7 +1772,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_ValueScopeStart: { auto inst = mBeModule->AllocInst(); - SetResult(curId, inst); + SetResult(curId, inst); } break; case BfIRCmd_ValueScopeRetain: @@ -1776,7 +1783,7 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_ValueScopeSoftEnd: - { + { CMD_PARAM(BeValue*, val); auto inst = mBeModule->AllocInst(); inst->mScopeStart = (BeValueScopeStartInst*)val; @@ -1786,7 +1793,7 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_ValueScopeHardEnd: - { + { CMD_PARAM(BeValue*, val); auto inst = mBeModule->AllocInst(); inst->mScopeStart = (BeValueScopeStartInst*)val; @@ -1812,7 +1819,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_Load: { CMD_PARAM(BeValue*, val); -#ifdef _DEBUG +#ifdef _DEBUG auto ptrType = val->GetType(); BF_ASSERT(ptrType->IsPointer()); // We call via a function pointer so there's never a reason to allow loading of a funcPtr @@ -1828,7 +1835,7 @@ void BeIRCodeGen::HandleNextCmd() } #endif - CMD_PARAM(bool, isVolatile); + CMD_PARAM(bool, isVolatile); SetResult(curId, mBeModule->CreateLoad(val, isVolatile)); } break; @@ -1888,7 +1895,7 @@ void BeIRCodeGen::HandleNextCmd() #ifdef _DEBUG auto ptrType = ptr->GetType(); - auto valType = val->GetType(); + auto valType = val->GetType(); if ((!ptrType->IsPointer()) || (!mBeContext->AreTypesEqual(((BePointerType*)ptrType)->mElementType, valType))) { String errStr; @@ -1907,7 +1914,7 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_MemSet: { - auto inst = mBeModule->AllocInst(); + auto inst = mBeModule->AllocInst(); Read(inst->mAddr); Read(inst->mVal); Read(inst->mSize); @@ -1938,11 +1945,11 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeType*, varType); CMD_PARAM(bool, isConstant); - BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); + BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); CMD_PARAM(StringT<256>, name); CMD_PARAM(bool, isTLS); CMD_PARAM(BeConstant*, initializer); - + BF_ASSERT(varType != NULL); auto globalVariable = mBeModule->mGlobalVariables.Alloc(); @@ -1951,7 +1958,7 @@ void BeIRCodeGen::HandleNextCmd() globalVariable->mIsConstant = isConstant; globalVariable->mLinkageType = linkageType; globalVariable->mInitializer = initializer; - globalVariable->mName = name; + globalVariable->mName = name; globalVariable->mIsTLS = isTLS; globalVariable->mUnnamedAddr = false; globalVariable->mStorageKind = BfIRStorageKind_Normal; @@ -1962,8 +1969,8 @@ void BeIRCodeGen::HandleNextCmd() BF_ASSERT(mBeContext->AreTypesEqual(varType, initializer->GetType())); } else - globalVariable->mAlign = -1; - + globalVariable->mAlign = -1; + SetResult(curId, globalVariable); } break; @@ -1974,18 +1981,18 @@ void BeIRCodeGen::HandleNextCmd() BF_ASSERT(BeValueDynCast(val) != NULL); - ((BeGlobalVariable*)val)->mUnnamedAddr = true; + ((BeGlobalVariable*)val)->mUnnamedAddr = true; } break; case BfIRCmd_GlobalVar_SetInitializer: { CMD_PARAM(BeValue*, val); CMD_PARAM(BeConstant*, initializer); - + BF_ASSERT(BeValueDynCast(val) != NULL); auto globalVariable = (BeGlobalVariable*)val; - globalVariable->mInitializer = initializer; + globalVariable->mInitializer = initializer; if (globalVariable->mInitializer != NULL) { @@ -2019,7 +2026,7 @@ void BeIRCodeGen::HandleNextCmd() BF_ASSERT(BeValueDynCast(val) != NULL); auto globalVariable = (BeGlobalVariable*)val; - globalVariable->mStorageKind = (BfIRStorageKind)storageKind; + globalVariable->mStorageKind = (BfIRStorageKind)storageKind; } break; case BfIRCmd_GlobalStringPtr: @@ -2042,11 +2049,11 @@ void BeIRCodeGen::HandleNextCmd() globalVariable->mAlign = 1; globalVariable->mUnnamedAddr = false; - auto castedVal = mBeModule->mAlloc.Alloc(); + auto castedVal = mBeModule->mAlloc.Alloc(); castedVal->mType = mBeContext->GetPointerTo(charType); castedVal->mTarget = globalVariable; SetResult(curId, castedVal); - + //SetResult(curId, globalVariable); } break; @@ -2061,7 +2068,7 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(String, name); CMD_PARAM(bool, addNow); - auto block = mBeModule->CreateBlock(name); + auto block = mBeModule->CreateBlock(name); if (addNow) mBeModule->AddBlock(mActiveFunction, block); @@ -2077,7 +2084,7 @@ void BeIRCodeGen::HandleNextCmd() auto bb = mBeModule->CreateBlock(name); mBeModule->CreateBr(bb); mBeModule->AddBlock(mActiveFunction, bb); - mBeModule->SetInsertPoint(bb); + mBeModule->SetInsertPoint(bb); newBlock = bb; } SetResult(curId, newBlock); @@ -2086,7 +2093,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_AddBlock: { CMD_PARAM(BeBlock*, block); - mBeModule->AddBlock(mActiveFunction, block); + mBeModule->AddBlock(mActiveFunction, block); } break; case BfIRCmd_DropBlocks: @@ -2095,10 +2102,10 @@ void BeIRCodeGen::HandleNextCmd() auto& basicBlockList = mActiveFunction->mBlocks; int postExitBlockIdx = -1; - /*auto itr = basicBlockList.begin(); + /*auto itr = basicBlockList.begin(); while (itr != basicBlockList.end()) { - auto block = *itr; + auto block = *itr; if (block == startingBlock) { basicBlockList.erase(itr, basicBlockList.end()); @@ -2120,21 +2127,21 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_MergeBlockDown: { CMD_PARAM(BeBlock*, fromBlock); - CMD_PARAM(BeBlock*, intoBlock); + CMD_PARAM(BeBlock*, intoBlock); for (auto inst : fromBlock->mInstructions) inst->mParentBlock = intoBlock; if (!fromBlock->mInstructions.IsEmpty()) intoBlock->mInstructions.Insert(0, &fromBlock->mInstructions[0], fromBlock->mInstructions.size()); mBeModule->RemoveBlock(mActiveFunction, fromBlock); } - break; + break; case BfIRCmd_GetInsertBlock: { SetResult(curId, mBeModule->mActiveBlock); } break; case BfIRCmd_SetInsertPoint: - { + { CMD_PARAM(BeBlock*, block); mBeModule->SetInsertPoint(block); } @@ -2153,9 +2160,9 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_DeleteBlock: { - CMD_PARAM(BeBlock*, block); + CMD_PARAM(BeBlock*, block); } - break; + break; case BfIRCmd_EraseInstFromParent: { CMD_PARAM(BeValue*, instVal); @@ -2164,7 +2171,7 @@ void BeIRCodeGen::HandleNextCmd() bool wasRemoved = inst->mParentBlock->mInstructions.Remove(inst); BF_ASSERT(wasRemoved); #ifdef _DEBUG - inst->mWasRemoved = true; + inst->mWasRemoved = true; #endif } break; @@ -2178,7 +2185,7 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeBlock*, block); auto inst = mBeModule->CreateBr(block); - inst->mIsFake = true; + inst->mIsFake = true; } break; case BfIRCmd_CreateBr_NoCollapse: @@ -2212,15 +2219,15 @@ void BeIRCodeGen::HandleNextCmd() auto switchInst = mBeModule->AllocInstOwned(); switchInst->mValue = val; switchInst->mDefaultBlock = dest; - switchInst->mCases.Reserve(numCases); + switchInst->mCases.Reserve(numCases); SetResult(curId, switchInst); } break; case BfIRCmd_AddSwitchCase: - { + { CMD_PARAM(BeValue*, switchVal); CMD_PARAM(BeValue*, caseVal); - CMD_PARAM(BeBlock*, caseBlock); + CMD_PARAM(BeBlock*, caseBlock); BeSwitchCase switchCase; switchCase.mValue = (BeConstant*)caseVal; @@ -2261,7 +2268,7 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_GetIntrinsic: - { + { CMD_PARAM(String, intrinName); CMD_PARAM(int, intrinId); CMD_PARAM(BeType*, returnType); @@ -2275,7 +2282,7 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_CreateFunctionType: - { + { CMD_PARAM(BeType*, resultType); CMD_PARAM(CmdParamVec, paramTypes); CMD_PARAM(bool, isVarArg); @@ -2288,7 +2295,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeFunctionType*, type); BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); CMD_PARAM(String, name); - SetResult(curId, mBeModule->CreateFunction(type, linkageType, name)); + SetResult(curId, mBeModule->CreateFunction(type, linkageType, name)); } break; case BfIRCmd_SetFunctionName: @@ -2301,7 +2308,6 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_EnsureFunctionPatchable: { - } break; case BfIRCmd_RemapBindFunction: @@ -2342,25 +2348,25 @@ void BeIRCodeGen::HandleNextCmd() dbgGlobalVariable->mDecl = decl; }*/ } - + SetResult(curId, mBeModule->CreateLoad(beFunc->mRemapBindVar, false)); } else - SetResult(curId, func); + SetResult(curId, func); } break; case BfIRCmd_SetActiveFunction: { - CMD_PARAM(BeFunction*, func); + CMD_PARAM(BeFunction*, func); mActiveFunction = func; mBeModule->mActiveFunction = func; } break; case BfIRCmd_CreateCall: - { + { CMD_PARAM(BeValue*, func); CMD_PARAM(CmdParamVec, args); - + #ifdef BE_EXTRA_CHECKS auto funcPtrType = func->GetType(); if (funcPtrType != NULL) @@ -2412,7 +2418,7 @@ void BeIRCodeGen::HandleNextCmd() BF_ASSERT(func->GetTypeId() == BeIntrinsic::TypeId); } #endif - SetResult(curId, mBeModule->CreateCall(func, args)); + SetResult(curId, mBeModule->CreateCall(func, args)); } break; case BfIRCmd_SetCallCallingConv: @@ -2425,7 +2431,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_SetFuncCallingConv: { CMD_PARAM(BeFunction*, func); - BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read(); + BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read(); func->mCallingConv = callingConv; } break; @@ -2438,9 +2444,9 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetCallAttribute: { - CMD_PARAM(BeValue*, callInstVal); + CMD_PARAM(BeValue*, callInstVal); CMD_PARAM(int, paramIdx); - BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); + BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); BeCallInst* callInst = (BeCallInst*)callInstVal; if (attribute == BfIRAttribute_NoReturn) callInst->mNoReturn = true; @@ -2495,7 +2501,7 @@ void BeIRCodeGen::HandleNextCmd() else if (attribute == BfIRAttribute_NoCapture) callInst->mArgs[argIdx - 1].mNoCapture = true; else if (attribute == BfIRAttribute_ByVal) - { + { } else BF_FATAL("Unhandled"); @@ -2503,10 +2509,10 @@ void BeIRCodeGen::HandleNextCmd() else { if (attribute == BfIRAttribute_NoReturn) - callInst->mNoReturn = true; + callInst->mNoReturn = true; else BF_FATAL("Unhandled"); - } + } } break; case BfIRCmd_Call_AddAttribute1: @@ -2515,7 +2521,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, argIdx); BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); CMD_PARAM(int, arg); - + BeCallInst* callInst = BeValueDynCast(inst); if (callInst != NULL) { @@ -2570,7 +2576,7 @@ void BeIRCodeGen::HandleNextCmd() if (attribute == BfIRAttribute_VarRet) func->mIsVarReturn = true; else if (attribute == BFIRAttribute_AlwaysInline) - func->mAlwaysInline = true; + func->mAlwaysInline = true; else if (attribute == BFIRAttribute_NoUnwind) func->mNoUnwind = true; else if (attribute == BFIRAttribute_UWTable) @@ -2594,7 +2600,7 @@ void BeIRCodeGen::HandleNextCmd() } else BF_FATAL("Unhandled"); - } + } } break; case BfIRCmd_Func_AddAttribute1: @@ -2602,15 +2608,15 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeFunction*, func); CMD_PARAM(int, argIdx); BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); - CMD_PARAM(int, arg); + CMD_PARAM(int, arg); // This is for adding things like Dereferencable, which we don't use if (argIdx > 0) { if (attribute == BfIRAttribute_Dereferencable) func->mParams[argIdx - 1].mDereferenceableSize = arg; - else if (attribute == BfIRAttribute_ByVal) - func->mParams[argIdx - 1].mByValSize = arg; + else if (attribute == BfIRAttribute_ByVal) + func->mParams[argIdx - 1].mByValSize = arg; else BF_FATAL("Unhandled"); } @@ -2624,9 +2630,9 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, argIdx); CMD_PARAM(String, name); if (argIdx > 0) - func->mParams[argIdx - 1].mName = name; + func->mParams[argIdx - 1].mName = name; } - break; + break; case BfIRCmd_Func_DeleteBody: { CMD_PARAM(BeFunction*, func); @@ -2639,10 +2645,18 @@ void BeIRCodeGen::HandleNextCmd() func->mName += StrFormat("__RENAME%d", curId); } break; + case BfIRCmd_Func_SafeRenameFrom: + { + CMD_PARAM(BeFunction*, func); + CMD_PARAM(String, prevName); + if (func->mName == prevName) + func->mName += StrFormat("__RENAME%d", curId); + } + break; case BfIRCmd_Func_SetLinkage: { CMD_PARAM(BeFunction*, func); - BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); + BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); func->mLinkageType = linkageType; } break; @@ -2666,7 +2680,7 @@ void BeIRCodeGen::HandleNextCmd() { mBeModule->SetCurrentDebugLocation(NULL); } - break; + break; case BfIRCmd_ClearDebugLocationInst: { CMD_PARAM(BeValue*, instValue); @@ -2680,7 +2694,7 @@ void BeIRCodeGen::HandleNextCmd() { auto inst = mBeModule->mActiveBlock->mInstructions.back(); inst->mDbgLoc = NULL; - } + } } break; case BfIRCmd_UpdateDebugLocation: @@ -2702,7 +2716,7 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_Nop: { - mBeModule->CreateNop(); + mBeModule->CreateNop(); } break; case BfIRCmd_EnsureInstructionAt: @@ -2712,7 +2726,6 @@ void BeIRCodeGen::HandleNextCmd() break; case BfIRCmd_StatementStart: { - } break; case BfIRCmd_ObjectAccessCheck: @@ -2731,7 +2744,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int32, error); auto inst = mBeModule->AllocInst(); - inst->mError = error; + inst->mError = error; SetResult(curId, inst); } break; @@ -2815,7 +2828,6 @@ void BeIRCodeGen::HandleNextCmd() typeEntry.mInstDIType->resolveCycles(); } mDIBuilder->finalize();*/ - } break; case BfIRCmd_DbgCreateCompileUnit: @@ -2828,7 +2840,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(String, flags); CMD_PARAM(int, runtimeVer); CMD_PARAM(bool, linesOnly); - + mBeModule->mDbgModule->mFileName = fileName; mBeModule->mDbgModule->mDirectory = directory; mBeModule->mDbgModule->mProducer = producer; @@ -2845,17 +2857,17 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(Val128, md5Hash); auto dbgFile = mBeModule->mDbgModule->mFiles.Alloc(); - dbgFile->mFileName = fileName; + dbgFile->mFileName = fileName; dbgFile->mDirectory = directory; dbgFile->mMD5Hash = md5Hash; dbgFile->mIdx = (int)mBeModule->mDbgModule->mFiles.size() - 1; - SetResult(curId, dbgFile); + SetResult(curId, dbgFile); } break; case BfIRCmd_DbgGetCurrentLocation: { - SetResult(curId, mBeModule->mCurDbgLoc); + SetResult(curId, mBeModule->mCurDbgLoc); } break; case BfIRCmd_DbgSetType: @@ -2919,7 +2931,7 @@ void BeIRCodeGen::HandleNextCmd() auto dbgNamespace = mBeModule->mOwnedValues.Alloc(); dbgNamespace->mScope = scope; dbgNamespace->mName = name; - SetResult(curId, dbgNamespace); + SetResult(curId, dbgNamespace); } break; case BfIRCmd_DbgCreateImportedModule: @@ -2943,7 +2955,7 @@ void BeIRCodeGen::HandleNextCmd() dbgType->mSize = (int)(sizeInBits / 8); dbgType->mAlign = (int)(alignInBits / 8); dbgType->mEncoding = encoding; - + SetResult(curId, dbgType); } break; @@ -2958,21 +2970,21 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, flags); CMD_PARAM(BeMDNode*, derivedFrom); CMD_PARAM(CmdParamVec, members); - + auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); dbgType->mScope = context; dbgType->mName = name; dbgType->mSize = (int)(sizeInBits / 8); - dbgType->mAlign = (int)(alignInBits / 8); + dbgType->mAlign = (int)(alignInBits / 8); dbgType->mDerivedFrom = BeValueDynCast(derivedFrom); dbgType->mDefFile = (BeDbgFile*)file; dbgType->mDefLine = lineNum - 1; - dbgType->mIsFullyDefined = true; + dbgType->mIsFullyDefined = true; dbgType->SetMembers(members); - + SetResult(curId, dbgType); } - break; + break; case BfIRCmd_DbgCreateEnumerationType: { CMD_PARAM(BeMDNode*, context); @@ -2980,10 +2992,10 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeMDNode*, file); CMD_PARAM(int, lineNum); CMD_PARAM(int64, sizeInBits); - CMD_PARAM(int64, alignInBits); + CMD_PARAM(int64, alignInBits); CMD_PARAM(CmdParamVec, members); CMD_PARAM(BeMDNode*, underlyingType); - + auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); dbgType->mScope = context; dbgType->mName = name; @@ -2996,7 +3008,7 @@ void BeIRCodeGen::HandleNextCmd() if (auto enumMember = BeValueDynCast(member)) { dbgType->mMembers.push_back(enumMember); - } + } else NotImpl(); } @@ -3007,9 +3019,9 @@ void BeIRCodeGen::HandleNextCmd() } break; case BfIRCmd_DbgCreatePointerType: - { + { CMD_PARAM(BeMDNode*, elementTypeNode); - + BeDbgType* elementType = BeValueDynCast(elementTypeNode); if (elementType == NULL) { @@ -3022,7 +3034,7 @@ void BeIRCodeGen::HandleNextCmd() dbgType->mTypeId = bfPtrType->mTypeId; SetResult(curId, dbgType); break; - } + } } BeDbgType* useType = elementType->FindDerivedType(BeDbgPointerType::TypeId); @@ -3034,7 +3046,7 @@ void BeIRCodeGen::HandleNextCmd() dbgType->mAlign = mPtrSize; elementType->mDerivedTypes.PushFront(dbgType, &mBeModule->mAlloc); useType = dbgType; - } + } SetResult(curId, useType); } @@ -3042,7 +3054,7 @@ void BeIRCodeGen::HandleNextCmd() case BfIRCmd_DbgCreateReferenceType: { CMD_PARAM(BeMDNode*, elementTypeNode); - + BeDbgType* elementType = BeValueDynCast(elementTypeNode); if (elementType == NULL) { @@ -3057,7 +3069,7 @@ void BeIRCodeGen::HandleNextCmd() break; } } - + auto useType = mBeModule->mDbgModule->CreateReferenceType(elementType); SetResult(curId, useType); } @@ -3066,7 +3078,7 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeMDNode*, elementTypeNode); - BeDbgType* elementType = BeValueDynCast(elementTypeNode); + BeDbgType* elementType = BeValueDynCast(elementTypeNode); if (elementType == NULL) { auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); @@ -3097,7 +3109,7 @@ void BeIRCodeGen::HandleNextCmd() // Does the artificial thing do anything for us actually? auto dbgType = diType; - SetResult(curId, dbgType); + SetResult(curId, dbgType); } break; case BfIRCmd_DbgCreateArrayType: @@ -3144,13 +3156,13 @@ void BeIRCodeGen::HandleNextCmd() dbgType->mScope = scope; dbgType->mName = name; dbgType->mSize = (int)(sizeInBits / 8); - dbgType->mAlign = (int)(alignInBits / 8); + dbgType->mAlign = (int)(alignInBits / 8); //dbgType->mDefFile = (BeDbgFile*)file; //dbgType->mDefLine = line - 1; SetResult(curId, dbgType); } else - NotImpl(); + NotImpl(); } break; case BfIRCmd_DbgCreateForwardDecl: @@ -3165,7 +3177,7 @@ void BeIRCodeGen::HandleNextCmd() { auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); dbgType->mScope = scope; - dbgType->mName = name; + dbgType->mName = name; dbgType->mDefFile = (BeDbgFile*)file; dbgType->mDefLine = line; SetResult(curId, dbgType); @@ -3178,7 +3190,7 @@ void BeIRCodeGen::HandleNextCmd() SetResult(curId, dbgType); } else - NotImpl(); + NotImpl(); } break; case BfIRCmd_DbgCreateSizedForwardDecl: @@ -3190,7 +3202,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int, line); CMD_PARAM(int64, sizeInBits); CMD_PARAM(int64, alignInBits); - + if (tag == llvm::dwarf::DW_TAG_structure_type) { auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); @@ -3204,7 +3216,7 @@ void BeIRCodeGen::HandleNextCmd() } else if (tag == llvm::dwarf::DW_TAG_enumeration_type) { - auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); + auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); dbgType->mScope = scope; dbgType->mName = name; dbgType->mSize = (int)(sizeInBits / 8); @@ -3222,14 +3234,14 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(int64, alignInBits); if (auto dbgType = BeValueDynCast(mdType)) - { + { dbgType->mSize = (int)(sizeInBits / 8); dbgType->mAlign = (int)(alignInBits / 8); - } + } } break; case BfIRCmd_DbgReplaceAllUses: - { + { CMD_PARAM(BeMDNode*, diPrevNode); CMD_PARAM(BeMDNode*, diNewNode); /*diPrevNode->replaceAllUsesWith(diNewNode); */ @@ -3247,12 +3259,12 @@ void BeIRCodeGen::HandleNextCmd() { CMD_PARAM(BeMDNode*, diNode); CMD_PARAM(BeMDNode*, diBaseType); - CMD_PARAM(CmdParamVec, members); - + CMD_PARAM(CmdParamVec, members); + if (auto dbgType = BeValueDynCast(diNode)) { dbgType->SetMembers(members); - } + } else if (auto dbgType = BeValueDynCast(diNode)) { dbgType->mElementType = BeValueDynCast(diBaseType); @@ -3306,7 +3318,7 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeMDNode*, type); CMD_PARAM(int, flags); CMD_PARAM(BeConstant*, val); - + BF_ASSERT(type != NULL); auto dbgMember = mBeModule->mOwnedValues.Alloc(); @@ -3339,8 +3351,8 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(String, name); CMD_PARAM(String, linkageName); CMD_PARAM(BeMDNode*, file); - CMD_PARAM(int, lineNum); - CMD_PARAM(BeMDNode*, type); + CMD_PARAM(int, lineNum); + CMD_PARAM(BeMDNode*, type); CMD_PARAM(bool, isLocalToUnit); CMD_PARAM(bool, isDefinition); CMD_PARAM(int, vk); @@ -3366,14 +3378,14 @@ void BeIRCodeGen::HandleNextCmd() dbgFunc->mIsStaticMethod = (flags & llvm::DINode::FlagStaticMember) != 0; dbgFunc->mFlags = flags; - for (auto arg : genericArgs) + for (auto arg : genericArgs) { BF_ASSERT(arg != NULL); dbgFunc->mGenericArgs.Add(BeValueDynCast(arg)); } for (auto genericConstValue : genericConstValueArgs) dbgFunc->mGenericConstValueArgs.Add(genericConstValue); - + if (dbgFunc->mValue != NULL) dbgFunc->mValue->mDbgFunction = dbgFunc; dbgFunc->mIdx = (int)mBeModule->mDbgModule->mFuncs.size(); @@ -3388,15 +3400,15 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(String, name); CMD_PARAM(String, linkageName); CMD_PARAM(BeMDNode*, file); - CMD_PARAM(int, lineNum); - CMD_PARAM(BeMDNode*, type); + CMD_PARAM(int, lineNum); + CMD_PARAM(BeMDNode*, type); CMD_PARAM(bool, isLocalToUnit); - CMD_PARAM(bool, isDefinition); + CMD_PARAM(bool, isDefinition); CMD_PARAM(int, scopeLine); CMD_PARAM(int, flags); CMD_PARAM(bool, isOptimized); CMD_PARAM(BeValue*, fn); - + auto dbgFunc = mBeModule->mOwnedValues.Alloc(); dbgFunc->mScope = context; dbgFunc->mFile = (BeDbgFile*)file; @@ -3414,12 +3426,11 @@ void BeIRCodeGen::HandleNextCmd() } else { - }*/ if (dbgFunc->mValue != NULL) dbgFunc->mValue->mDbgFunction = dbgFunc; dbgFunc->mIdx = (int)mBeModule->mDbgModule->mFuncs.size(); - mBeModule->mDbgModule->mFuncs.push_back(dbgFunc); + mBeModule->mDbgModule->mFuncs.push_back(dbgFunc); SetResult(curId, dbgFunc); } @@ -3455,7 +3466,7 @@ void BeIRCodeGen::HandleNextCmd() dbgFunc->mVariables.Insert(argIdx, dbgVar); } //mActiveFunction->mDbgFunction->mVariables.push_back(dbgVar); - + //dbgVar->mValue = mBeModule->GetArgument(argNo - 1); SetResult(curId, dbgVar); @@ -3556,11 +3567,11 @@ void BeIRCodeGen::HandleNextCmd() CMD_PARAM(BeMDNode*, file); CMD_PARAM(int, lineNum); CMD_PARAM(BeMDNode*, type); - CMD_PARAM(bool, isLocalToUnit); + CMD_PARAM(bool, isLocalToUnit); CMD_PARAM(BeConstant*, val); CMD_PARAM(BeMDNode*, decl); - auto dbgGlobalVariable = mBeModule->mDbgModule->mGlobalVariables.Alloc(); + auto dbgGlobalVariable = mBeModule->mDbgModule->mGlobalVariables.Alloc(); dbgGlobalVariable->mContext = context; dbgGlobalVariable->mName = name; dbgGlobalVariable->mLinkageName = linkageName; @@ -3586,10 +3597,10 @@ void BeIRCodeGen::HandleNextCmd() dbgLexicalBlock->mFile = (BeDbgFile*)file; dbgLexicalBlock->mScope = scope; dbgLexicalBlock->mId = mBeModule->mCurLexBlockId++; - + SetResult(curId, dbgLexicalBlock); } - break; + break; case BfIRCmd_DbgCreateAnnotation: { CMD_PARAM(BeMDNode*, scope); @@ -3602,13 +3613,13 @@ void BeIRCodeGen::HandleNextCmd() BeDbgType** dbgTypePtr; if (mOnDemandTypeMap.TryAdd(beType, NULL, &dbgTypePtr)) { - auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); + auto dbgType = mBeModule->mDbgModule->mTypes.Alloc(); dbgType->mSize = beType->mSize; dbgType->mAlign = beType->mAlign; dbgType->mEncoding = llvm::dwarf::DW_ATE_signed; *dbgTypePtr = dbgType; } - + auto dbgVar = mBeModule->mOwnedValues.Alloc(); dbgVar->mName = "#" + name; dbgVar->mType = *dbgTypePtr; @@ -3619,7 +3630,7 @@ void BeIRCodeGen::HandleNextCmd() auto inst = mBeModule->AllocInst(); inst->mValue = value; inst->mDbgVar = dbgVar; - inst->mIsValue = true; + inst->mIsValue = true; } else NotImpl(); @@ -3628,9 +3639,9 @@ void BeIRCodeGen::HandleNextCmd() default: BF_FATAL("Unhandled"); break; - } + } -#ifdef CODEGEN_TRACK +#ifdef CODEGEN_TRACK gBEMemReporter.EndSection(); gBEMemReporterSize += mStream->GetReadPos() - curId; @@ -3640,7 +3651,7 @@ void BeIRCodeGen::HandleNextCmd() void BeIRCodeGen::SetConfigConst(int idx, int value) { BF_ASSERT(idx == (int)mConfigConsts.size()); - mConfigConsts.Add(value); + mConfigConsts.Add(value); } BeValue* BeIRCodeGen::GetBeValue(int id) @@ -3708,4 +3719,4 @@ void BeIRCodeGen::SetState(const BeState& state) mBeModule->mCurDbgLoc = state.mCurDbgLoc; mBeModule->mPrevDbgLocInline = state.mPrevDbgLocInline; mBeModule->mLastDbgLoc = state.mLastDbgLoc; -} +} \ No newline at end of file diff --git a/IDEHelper/Backend/BeIRCodeGen.h b/IDEHelper/Backend/BeIRCodeGen.h index e18426ba..cc99faa6 100644 --- a/IDEHelper/Backend/BeIRCodeGen.h +++ b/IDEHelper/Backend/BeIRCodeGen.h @@ -75,40 +75,40 @@ class BeIRCodeGen : public BfIRCodeGenBase { public: bool mDebugging; - - BfIRBuilder* mBfIRBuilder; + + BfIRBuilder* mBfIRBuilder; BeFunction* mActiveFunction; BeContext* mBeContext; - BeModule* mBeModule; - Array mSavedDebugLocs; - bool mHasDebugLoc; + BeModule* mBeModule; + Array mSavedDebugLocs; + bool mHasDebugLoc; int mCmdCount; Dictionary mResults; - Dictionary mTypes; + Dictionary mTypes; Dictionary mOnDemandTypeMap; Dictionary mReflectDataMap; - Array mConfigConsts; + Array mConfigConsts; -public: +public: void FatalError(const StringImpl& str); void NotImpl(); BfTypeCode GetTypeCode(BeType* type, bool isSigned); void SetResult(int id, BeValue* value); void SetResult(int id, BeType* type); void SetResult(int id, BeBlock* value); - void SetResult(int id, BeMDNode* md); + void SetResult(int id, BeMDNode* md); BeType* GetBeType(BfTypeCode typeCode, bool& isSigned); - BeIRTypeEntry& GetTypeEntry(int typeId); + BeIRTypeEntry& GetTypeEntry(int typeId); void FixValues(BeStructType* structType, CmdParamVec& values); public: BeIRCodeGen(); - ~BeIRCodeGen(); + ~BeIRCodeGen(); void Hash(BeHashContext& hashCtx); bool IsModuleEmpty(); @@ -127,12 +127,12 @@ public: void Read(BeConstant*& beConstant); void Read(BeFunction*& beFunc); void Read(BeBlock*& beBlock); - void Read(BeMDNode*& beMD); + void Read(BeMDNode*& beMD); template void Read(SizedArrayImpl& vec) { - int len = (int)ReadSLEB128(); + int len = (int)ReadSLEB128(); for (int i = 0; i < len; i++) { T result; @@ -140,11 +140,11 @@ public: vec.push_back(result); } } - + void Init(const BfSizedArray& buffer); void Process(); - virtual void ProcessBfIRData(const BfSizedArray& buffer) override; + virtual void ProcessBfIRData(const BfSizedArray& buffer) override; virtual void HandleNextCmd() override; virtual void SetConfigConst(int idx, int value) override; diff --git a/IDEHelper/Backend/BeLibManger.cpp b/IDEHelper/Backend/BeLibManger.cpp index 22590719..30fc23f0 100644 --- a/IDEHelper/Backend/BeLibManger.cpp +++ b/IDEHelper/Backend/BeLibManger.cpp @@ -1,4 +1,3 @@ - #pragma warning(disable:4996) #include "BeLibManger.h" #include "BeefySysLib/util/BeefPerf.h" @@ -37,7 +36,7 @@ bool BeLibFile::ReadLib() mOldFileStream.Read(fileId, 8); if (strncmp(fileId, "!\n", 8) != 0) return false; - + const char* libStrTable = NULL; Dictionary pendingLibEntryMap; @@ -62,18 +61,18 @@ bool BeLibFile::ReadLib() mOldFileStream.Read(data, len); int numSymbols = FromBigEndian(*(int32*)data); - + uint8* strTab = data + 4 + numSymbols * 4; for (int symIdx = 0; symIdx < numSymbols; symIdx++) - { + { const char* str = (char*)strTab; strTab += strlen((char*)strTab) + 1; int offset = FromBigEndian(((int32*)(data + 4))[symIdx]); - - BeLibEntry* pendingEntry; - + + BeLibEntry* pendingEntry; + BeLibEntry** pendingEntryPtr = NULL; if (!pendingLibEntryMap.TryAdd(offset, NULL, &pendingEntryPtr)) { @@ -93,7 +92,6 @@ bool BeLibFile::ReadLib() } else { - } } else if (strncmp(header.mName, "// ", 3) == 0) @@ -115,7 +113,7 @@ bool BeLibFile::ReadLib() fileName.Append(&libStrTable[tabIdx], checkIdx - tabIdx); break; } - } + } } else { @@ -125,9 +123,9 @@ bool BeLibFile::ReadLib() fileName.Append(&header.mName[0], i); } } - + BeLibEntry* libEntry = NULL; - + if (!pendingLibEntryMap.TryGetValue(headerFilePos, &libEntry)) { libEntry = new BeLibEntry(); @@ -171,11 +169,11 @@ bool BeLibFile::ReadLib() } bool BeLibFile::Init(const StringImpl& filePath, bool moveFile) -{ - bool isInitialized = false; +{ + bool isInitialized = false; if (FileExists(filePath)) - { + { String altName; if (moveFile) { @@ -196,14 +194,14 @@ bool BeLibFile::Init(const StringImpl& filePath, bool moveFile) if (!mOldFileStream.Open(altName, "rb")) return false; - + if (!ReadLib()) return false; - } - - String newLibName = filePath; + } + + String newLibName = filePath; mFilePath = newLibName; - + return true; } @@ -212,9 +210,9 @@ bool BeLibFile::Finish() BP_ZONE("BeLibFile::Finish"); //mOldEntries.clear(); - - Dictionary* libEntryMaps[2] = { &mEntries, &mOldEntries }; - + + Dictionary* libEntryMaps[2] = { &mEntries, &mOldEntries }; + Array libEntries; bool isAllReferenced = true; @@ -241,7 +239,7 @@ bool BeLibFile::Finish() } if (!mFileStream.Open(mFilePath, "wb")) - { + { mFailed = true; return false; } @@ -255,7 +253,7 @@ bool BeLibFile::Finish() mFileStream.Write("!\n", 8); - std::sort(libEntries.begin(), libEntries.end(), + std::sort(libEntries.begin(), libEntries.end(), [&](BeLibEntry* lhs, BeLibEntry* rhs) { return lhs->mName < rhs->mName; @@ -263,12 +261,12 @@ bool BeLibFile::Finish() int longNamesSize = 0; - int tabSize = 4; // num symbols + int tabSize = 4; // num symbols int numSymbols = 0; for (auto libEntry : libEntries) { if (libEntry->mName.length() > 15) - { + { longNamesSize += (int)libEntry->mName.length() + 2; } @@ -277,28 +275,27 @@ bool BeLibFile::Finish() numSymbols++; tabSize += 4; // Offset tabSize += (int)sym.length() + 1; // String table - } + } } - + // Determine where all these entries will be placed int predictPos = mFileStream.GetPos() + sizeof(BeLibMemberHeader) + BF_ALIGN(tabSize, 2); if (longNamesSize > 0) - predictPos += sizeof(BeLibMemberHeader) + BF_ALIGN(longNamesSize, 2); + predictPos += sizeof(BeLibMemberHeader) + BF_ALIGN(longNamesSize, 2); for (auto libEntry : libEntries) { libEntry->mNewDataPos = predictPos; - + predictPos += sizeof(BeLibMemberHeader); - predictPos += BF_ALIGN(libEntry->mLength, 2); + predictPos += BF_ALIGN(libEntry->mLength, 2); } int tabStartPos = mFileStream.GetPos(); - - + BeLibMemberHeader header; - header.Init("/", "0", tabSize); + header.Init("/", "0", tabSize); mFileStream.WriteT(header); mFileStream.Write(ToBigEndian((int32)numSymbols)); @@ -308,7 +305,7 @@ bool BeLibFile::Finish() for (auto& sym : libEntry->mSymbols) { mFileStream.Write((int32)ToBigEndian(libEntry->mNewDataPos)); - } + } } // String map table @@ -317,11 +314,11 @@ bool BeLibFile::Finish() for (auto& sym : libEntry->mSymbols) { mFileStream.Write((uint8*)sym.c_str(), (int)sym.length() + 1); - } + } } int actualTabSize = mFileStream.GetPos() - tabStartPos - sizeof(BeLibMemberHeader); - + //return true; if ((tabSize % 2) != 0) @@ -332,16 +329,16 @@ bool BeLibFile::Finish() // Create long names table if (longNamesSize > 0) { - header.Init("//", "0", longNamesSize); + header.Init("//", "0", longNamesSize); mFileStream.WriteT(header); for (auto libEntry : libEntries) { - if (libEntry->mName.length() > 15) + if (libEntry->mName.length() > 15) { mFileStream.Write((uint8*)libEntry->mName.c_str(), (int)libEntry->mName.length()); mFileStream.Write("/\n", 2); - } + } } if ((longNamesSize % 2) != 0) @@ -357,9 +354,9 @@ bool BeLibFile::Finish() String entryName; if (libEntry->mName.length() > 15) - { - char idxStr[32]; - _itoa(longNamesPos, idxStr, 10); + { + char idxStr[32]; + _itoa(longNamesPos, idxStr, 10); entryName = "/"; entryName += idxStr; longNamesPos += (int)libEntry->mName.length() + 2; @@ -370,7 +367,7 @@ bool BeLibFile::Finish() entryName += "/"; } - header.Init(entryName.c_str(), "644", libEntry->mLength); + header.Init(entryName.c_str(), "644", libEntry->mLength); mFileStream.WriteT(header); if (libEntry->mOldDataPos != -1) @@ -383,11 +380,11 @@ bool BeLibFile::Finish() } else if (libEntry->mData.size() != 0) { - mFileStream.Write((uint8*)&libEntry->mData[0], (int)libEntry->mData.size()); + mFileStream.Write((uint8*)&libEntry->mData[0], (int)libEntry->mData.size()); } if ((libEntry->mLength % 2) != 0) - mFileStream.Write((uint8)0); + mFileStream.Write((uint8)0); } mFileStream.Close(); @@ -448,7 +445,7 @@ BeLibEntry* BeLibManager::AddFile(const StringImpl& filePath, void* data, int si libFile = *libFilePtr; } else - { + { libFile = new BeLibFile(); *libFilePtr = libFile; @@ -485,7 +482,7 @@ BeLibEntry* BeLibManager::AddFile(const StringImpl& filePath, void* data, int si // It's possible that we rebuild a type (generic, probably), decide we don't have any refs so we delete the type, // but then we specialize methods and then have to recreate it. Thus two entries here. delete *libEntryPtr; - } + } libEntry = new BeLibEntry(); libEntry->mLibFile = libFile; *libEntryPtr = libEntry; @@ -494,7 +491,7 @@ BeLibEntry* BeLibManager::AddFile(const StringImpl& filePath, void* data, int si libEntry->mName = fileName; libEntry->mData.Insert(0, (uint8*)data, size); libEntry->mLength = size; - + return libEntry; } @@ -533,5 +530,4 @@ String BeLibManager::GetLibFilePath(const StringImpl& objFilePath) BeLibManager* BeLibManager::Get() { return &gBfLibManager; -} - +} \ No newline at end of file diff --git a/IDEHelper/Backend/BeLibManger.h b/IDEHelper/Backend/BeLibManger.h index a1634e79..3d073eb0 100644 --- a/IDEHelper/Backend/BeLibManger.h +++ b/IDEHelper/Backend/BeLibManger.h @@ -39,7 +39,7 @@ struct BeLibMemberHeader memcpy(mDate, "0", 1); memcpy(mMode, mode, strlen(mode)); - char sizeStr[32]; + char sizeStr[32]; sprintf(sizeStr, "%d", size); memcpy(mSize, sizeStr, strlen(sizeStr)); } @@ -60,7 +60,7 @@ public: Array mData; BeLibEntry* mNextWithSameName; -public: +public: BeLibEntry() { mReferenced = false; @@ -84,7 +84,7 @@ public: String mFilePath; String mOldFilePath; FileStream mOldFileStream; - FileStream mFileStream; + FileStream mFileStream; Dictionary mOldEntries; Dictionary mEntries; bool mFailed; @@ -107,7 +107,7 @@ public: Dictionary mLibFiles; Array mErrors; -public: +public: BeLibManager(); ~BeLibManager(); @@ -118,8 +118,7 @@ public: void Finish(); static String GetLibFilePath(const StringImpl& objFilePath); - static BeLibManager* Get(); + static BeLibManager* Get(); }; - NS_BF_END diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index af011570..e6cb6228 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -34,11 +34,10 @@ static const char* gOpName[] = "@DefLoad", "@DefPhi", "@DbgDecl", - "@DbgRangeStart", - "@DbgRangeEnd", "@LifetimeExtend", "@LifetimeStart", "@LifetimeEnd", + "@LifetimeSoftEnd", "@ValueScopeSoftEnd", "@ValueScopeHardEnd", "@Label", @@ -252,7 +251,6 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, SizedArr else newList->mNumChanges = 0; - return newList; } @@ -302,7 +300,6 @@ BeVTrackingList* BeVTrackingContext::AddFiltered(BeVTrackingList* list, int idx, else newList->mNumChanges = 0; - return newList; } @@ -461,7 +458,6 @@ BeVTrackingList* BeVTrackingContext::SetChanges(BeVTrackingList* prevDestEntry, return newList; } - BeVTrackingList* BeVTrackingContext::ClearFiltered(BeVTrackingList* list, const SizedArrayImpl& indices) { /*int newSize = list->mSize - indices.size(); @@ -895,7 +891,7 @@ void BeMCColorizer::Prepare() //node->mWantsReg = false; //vregInfo->mReg = X64Reg_None; - //continue; + //continue; } if ((vregInfo->mRefCount > 0) || (vregInfo->mIsRetVal)) @@ -1047,7 +1043,7 @@ void BeMCColorizer::GenerateRegCosts() auto restoreInst = mcBlock->mInstructions[restoreIdx]; // Any vregs alive during this call will incur a cost of saving/restoring if we allocate onto a volatile register. - // If the vreg is either input-only or output-only (short lived temporary) then we can map it directly to a volatile register + // If the vreg is either input-only or output-only (short lived temporary) then we can map it directly to a volatile register for (int vregIdx : *inst->mLiveness) { if (vregIdx >= mContext->mLivenessContext.mNumItems) @@ -1272,8 +1268,8 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { highestReg = X64Reg_M128_XMM14; // Leave X64Reg_M128_XMM15 as a scratch reg validRegs = { - X64Reg_M128_XMM0, X64Reg_M128_XMM1, X64Reg_M128_XMM2, X64Reg_M128_XMM3, - X64Reg_M128_XMM4, X64Reg_M128_XMM5, X64Reg_M128_XMM6, X64Reg_M128_XMM7, + X64Reg_M128_XMM0, X64Reg_M128_XMM1, X64Reg_M128_XMM2, X64Reg_M128_XMM3, + X64Reg_M128_XMM4, X64Reg_M128_XMM5, X64Reg_M128_XMM6, X64Reg_M128_XMM7, X64Reg_M128_XMM8, X64Reg_M128_XMM9, X64Reg_M128_XMM10, X64Reg_M128_XMM11, X64Reg_M128_XMM12, X64Reg_M128_XMM13, X64Reg_M128_XMM14 /*, X64Reg_M128_XMM15*/}; } @@ -1416,7 +1412,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) { BP_ZONE("Spill"); - // We need to spill! + // We need to spill! int bestSpillVReg = -1; for (int regPassIdx = 0; regPassIdx < 2; regPassIdx++) { @@ -1433,7 +1429,7 @@ void BeMCColorizer::AssignRegs(RegKind regKind) if (bestSpillVReg != -1) break; - // Order by mem cost + // Order by mem cost orderedSpillList.reserve(vregGraph.size()); for (int graphIdx = 0; graphIdx < (int)vregGraph.size(); graphIdx++) { @@ -1505,7 +1501,6 @@ void BeMCColorizer::AssignRegs(RegKind regKind) dbgStr += StrFormat("VReg %d ", vregIdx); }*/ - BeMCVRegInfo* vregInfo = mContext->mVRegInfo[vregIdx]; Node* node = &mNodes[vregIdx]; @@ -1545,12 +1540,12 @@ void BeMCColorizer::AssignRegs(RegKind regKind) } } auto bestReg = X64Reg_None; - int bestRegCost = 0x07FFFFFF; // 0x0FFFFFFF is considered illegal for a reg, so set the mem cost to lower than that...; + int bestRegCost = 0x07FFFFFF; // 0x0FFFFFFF is considered illegal for a reg, so set the mem cost to lower than that...; // This is the cost of just leaving the vreg as a memory access. In cases where we bind to a volatile // register, we need to consider the cost of preserving and restoring that register across calls, so // it cases where we have just a few accesses to this vreg but it spans a lot of calls then we just - // leave it as memory + // leave it as memory if (!vregInfo->mForceReg) bestRegCost = node->mMemCost; @@ -1945,7 +1940,7 @@ void BeMCContext::Fail(const StringImpl& str) BeDumpContext dumpCtx; errStr += "\n DbgLoc : "; dumpCtx.ToString(errStr, mActiveInst->mDbgLoc); - } + } BfpSystem_FatalError(errStr.c_str(), "FATAL ERROR"); } @@ -2290,13 +2285,13 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a auto result = mcVal; - // We assume we never do both an idx0 and idx1 at once. Fix if we change that. + // We assume we never do both an idx0 and idx1 at once. Fix if we change that. int byteOffset = 0; BeType* elementType = ptrType->mElementType; byteOffset += gepConstant->mIdx0 * ptrType->mElementType->GetStride(); - + result = AllocRelativeVirtualReg(ptrType, result, GetImmediate(byteOffset), 1); - // The def is primary to create a single 'master location' for the GEP vreg to become legalized before use + // The def is primary to create a single 'master location' for the GEP vreg to become legalized before use auto vregInfo = GetVRegInfo(result); vregInfo->mDefOnFirstUse = true; result.mKind = BeMCOperandKind_VReg; @@ -2315,7 +2310,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a auto result = mcVal; - // We assume we never do both an idx0 and idx1 at once. Fix if we change that. + // We assume we never do both an idx0 and idx1 at once. Fix if we change that. int byteOffset = 0; BeType* elementType = NULL; byteOffset += gepConstant->mIdx0 * ptrType->mElementType->GetStride(); @@ -2344,7 +2339,7 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a auto elementPtrType = mModule->mContext->GetPointerTo(elementType); result = AllocRelativeVirtualReg(elementPtrType, result, GetImmediate(byteOffset), 1); - // The def is primary to create a single 'master location' for the GEP vreg to become legalized before use + // The def is primary to create a single 'master location' for the GEP vreg to become legalized before use auto vregInfo = GetVRegInfo(result); vregInfo->mDefOnFirstUse = true; result.mKind = BeMCOperandKind_VReg; @@ -2389,7 +2384,6 @@ BeMCOperand BeMCContext::GetOperand(BeValue* value, bool allowMetaResult, bool a break; case BeDbgVariable::TypeId: { - } } @@ -2587,7 +2581,7 @@ BeMCOperand BeMCContext::TryToVector(BeValue* value) auto operand = GetOperand(value); auto type = GetType(operand); if (!type->IsPointer()) - return operand; + return operand; return CreateLoad(operand); } @@ -2627,7 +2621,7 @@ BeType* BeMCContext::GetType(const BeMCOperand& operand) case BeMCOperandKind_Immediate_i8: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int8); break; case BeMCOperandKind_Immediate_i16: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int16); break; case BeMCOperandKind_Immediate_i32: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int32); break; - case BeMCOperandKind_Immediate_i64: + case BeMCOperandKind_Immediate_i64: case BeMCOperandKind_Immediate_HomeSize: return mModule->mContext->GetPrimitiveType(BeTypeCode_Int64); break; case BeMCOperandKind_Immediate_Null: return operand.mType; break; case BeMCOperandKind_Immediate_f32: @@ -2747,7 +2741,7 @@ BeMCInst* BeMCContext::AllocInst(BeMCInstKind instKind, const BeMCOperand& arg0, } BeMCInst* BeMCContext::AllocInst(BeMCInstKind instKind, const BeMCOperand& arg0, const BeMCOperand& arg1, int insertIdx) -{ +{ auto mcInst = AllocInst(insertIdx); mcInst->mKind = instKind; mcInst->mArg0 = arg0; @@ -2767,7 +2761,7 @@ void BeMCContext::MergeInstFlags(BeMCInst* prevInst, BeMCInst* inst, BeMCInst* n void BeMCContext::RemoveInst(BeMCBlock* block, int instIdx, bool needChangesMerged, bool removeFromList) { // If neither the instruction before or after this one shares the vregsInitialized flags, then we need to - // merge down our Changes to the next instruction + // merge down our Changes to the next instruction auto inst = block->mInstructions[instIdx]; if (instIdx > 0) { @@ -2792,7 +2786,6 @@ void BeMCContext::RemoveInst(BeMCBlock* block, int instIdx, bool needChangesMerg block->mInstructions.RemoveAt(instIdx); } - BeMCOperand BeMCContext::GetCallArgVReg(int argIdx, BeTypeCode typeCode) { int pIdx = argIdx; @@ -2859,7 +2852,7 @@ BeMCOperand BeMCContext::GetCallArgVReg(int argIdx, BeTypeCode typeCode) } BeMCOperand BeMCContext::CreateCall(const BeMCOperand &func, const SizedArrayImpl& args, BeType* retType, BfIRCallingConv callingConv, bool structRet, bool noReturn, bool isVarArg) -{ +{ SizedArray opArgs; for (auto itr = args.begin(); itr != args.end(); ++itr) { @@ -2901,7 +2894,7 @@ static bool NeedsDecompose(BeConstant* constant) for (auto& val : arrayConst->mMemberValues) { if (NeedsDecompose(val)) - return true; + return true; } return false; } @@ -2913,14 +2906,14 @@ static bool NeedsDecompose(BeConstant* constant) else if (auto castConst = BeValueDynCast(constant)) { return true; - } + } else if (auto castConst = BeValueDynCast(constant)) { if (auto targetConstant = BeValueDynCast(castConst->mValue)) return NeedsDecompose(targetConstant); } else if (auto castConst = BeValueDynCast(constant)) - { + { return NeedsDecompose(castConst->mTarget); } else if (auto castConst = BeValueDynCast(constant)) @@ -2932,10 +2925,10 @@ static bool NeedsDecompose(BeConstant* constant) } void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, const BeMCOperand& ptr) -{ +{ BeMCOperand mcVal = val; BeMCOperand mcPtr = ptr; - + if (mcVal.mKind == BeMCOperandKind_ConstAgg) { if (auto aggConst = BeValueDynCast(mcVal.mConstant)) @@ -2945,9 +2938,9 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con int offset = 0; auto aggType = aggConst->GetType(); - + for (int memberIdx = 0; memberIdx < (int)aggConst->mMemberValues.size(); memberIdx++) - { + { auto val = aggConst->mMemberValues[memberIdx]; BeType* elemType = NULL; if (aggType->IsSizedArray()) @@ -2960,7 +2953,7 @@ void BeMCContext::CreateStore(BeMCInstKind instKind, const BeMCOperand& val, con } if (elemType->mSize == 0) continue; - + auto destOperand = AllocVirtualReg(mModule->mContext->GetPointerTo(elemType)); auto vregInfo = GetVRegInfo(destOperand); vregInfo->mDefOnFirstUse = true; @@ -3056,7 +3049,7 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp }; SizedArray<_ShadowReg, 8> shadowRegs; - + mMaxCallParamCount = BF_MAX(mMaxCallParamCount, argCount); for (int argIdx = args.size() - 1; argIdx >= 0; argIdx--) { @@ -3598,7 +3591,7 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B brInstIdx = checkIdx; checkInst->mArg0 = landinglabel; found = true; - // Don't break, if we're are chained to another PHI then we need to modify all the labels + // Don't break, if we're are chained to another PHI then we need to modify all the labels isFalseCmpResult = false; if ((checkIdx >= 2) && (checkInst->mKind == BeMCInstKind_Br)) @@ -3611,7 +3604,6 @@ void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const B isFalseCmpResult = true; } } - } } }; @@ -3704,7 +3696,7 @@ void BeMCContext::CreatePhiAssign(BeMCBlock* mcBlock, const BeMCOperand& testVal { SetAndRestoreValue prevActiveBlock(mActiveBlock, block); for (int checkIdx = (int)block->mInstructions.size() - 1; checkIdx >= 0; checkIdx--) - { + { auto checkInst = block->mInstructions[checkIdx]; if ((checkInst->mArg0.mKind == BeMCOperandKind_Block) && (checkInst->mArg0.mBlock == phi->mBlock)) @@ -3718,18 +3710,18 @@ void BeMCContext::CreatePhiAssign(BeMCBlock* mcBlock, const BeMCOperand& testVal auto prevDest = checkInst->mArg0; checkInst->mArg0 = falseLabel; - checkInst->mArg1.mCmpKind = BeModule::InvertCmp(checkInst->mArg1.mCmpKind); + checkInst->mArg1.mCmpKind = BeModule::InvertCmp(checkInst->mArg1.mCmpKind); int insertIdx = checkIdx + 1; SetAndRestoreValue prevInsertIdxRef(mInsertInstIdxRef, &insertIdx); CreateStore(BeMCInstKind_Mov, phiVal.mValue, OperandToAddr(result)); AllocInst(BeMCInstKind_Br, prevDest); - AllocInst(BeMCInstKind_Label, falseLabel); + AllocInst(BeMCInstKind_Label, falseLabel); } else - { + { int insertIdx = checkIdx; - SetAndRestoreValue prevInsertIdxRef(mInsertInstIdxRef, &insertIdx); + SetAndRestoreValue prevInsertIdxRef(mInsertInstIdxRef, &insertIdx); CreateStore(BeMCInstKind_Mov, phiVal.mValue, OperandToAddr(result)); } @@ -3902,7 +3894,7 @@ bool BeMCContext::ContainsNonOffsetRef(const BeMCOperand& checkOperand, const Be // For all values that we are certain we will immediately use, we directly do a Def preceding its first use. // For Allocas in the head, however, we may not use that memory for a long time so we imply the Def location -// in DoDefPass. That allows us to limit how long that vreg will hold onto a register, reducing register +// in DoDefPass. That allows us to limit how long that vreg will hold onto a register, reducing register // contention. BeMCInst* BeMCContext::CreateDefineVReg(const BeMCOperand& vreg, int insertIdx) { @@ -4215,26 +4207,26 @@ bool BeMCContext::CouldBeReg(const BeMCOperand& operand) // { // if (operand.mKind != BeMCOperandKind_VReg) // return false; -// +// // auto vregInfo = GetVRegInfo(operand); // if ((vregInfo->mIsRetVal) && (mCompositeRetVRegIdx != -1) && (mCompositeRetVRegIdx != operand.mVRegIdx)) // { // return CouldBeReg(BeMCOperand::FromVReg(mCompositeRetVRegIdx)); // } -// +// // if (vregInfo->mReg != X64Reg_None) // return true; -// +// // if (vregInfo->mForceMem) // return false; -// +// // if (vregInfo->mIsExpr) // { // if (vregInfo->mRelOffset) -// return false; +// return false; // return CouldBeReg(vregInfo->mRelTo); // } -// +// // return !vregInfo->mType->IsNonVectorComposite(); // } @@ -4262,7 +4254,7 @@ void BeMCContext::MarkLive(BeVTrackingList* liveRegs, SizedArrayImpl& newRe if (!mColorizer.mNodes.empty()) { - // Is new + // Is new for (int i = 0; i < liveRegs->mSize; i++) { int checkReg = liveRegs->mEntries[i]; @@ -4412,7 +4404,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC //if (mDebugging) debugging = true; //if (mBeFunction->mName == "?Draw@DarkEditWidgetContent@dark@theme@Beefy@@UEAAXPEAVGraphics@gfx@4@@Z") //debugging = true; - //"?DrawEntry@DrawContext@PerfView@BeefPerf@@QEAAXPEAVGraphics@gfx@Beefy@@PEAVTrackNodeEntry@23@MM@Z") + //"?DrawEntry@DrawContext@PerfView@BeefPerf@@QEAAXPEAVGraphics@gfx@Beefy@@PEAVTrackNodeEntry@23@MM@Z") //debugging &= mcColorizer != NULL; if (debugging) @@ -4555,7 +4547,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC // It's possible this vregsInitialized is equivalent to the one in 'inst', but also merged with another 'inst' // during legalization. We need to avoid uninitializing vregs if that's the case. - // the entry above this + // the entry above this if (inst->mVRegsInitialized->ContainsChange(vregIdxEx)) continue; @@ -4573,7 +4565,7 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC if (!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, inst->mArg0.mVRegIdx)) { // There are some rare cases with conditional branches where one branch will have a vreg marked as - // initialized, which causes the variable to be marked as live, which propagates upward into the block + // initialized, which causes the variable to be marked as live, which propagates upward into the block // containing a variable declaration, before the actual def point DedupPushBack(removeVec, inst->mArg0.mVRegIdx); } @@ -4582,8 +4574,8 @@ void BeMCContext::GenerateLiveness(BeMCBlock* block, BeVTrackingGenContext* genC } // This is used for clearing out things like usage of inline return values, which will be accessed after their - // lifetime end (the lifetime ends inside the inlined method but the value is used afterward, in the inlining - // function. This will emit as a load of a dbgVar, so we need to drill down into the relTo values + // lifetime end (the lifetime ends inside the inlined method but the value is used afterward, in the inlining + // function. This will emit as a load of a dbgVar, so we need to drill down into the relTo values if (inst->mKind == BeMCInstKind_LifetimeStart) { BEMC_ASSERT(inst->mArg0.IsVRegAny()); @@ -4903,52 +4895,52 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) switch (reg) { case X64Reg_XMM0_f32: - case X64Reg_XMM0_f64: + case X64Reg_XMM0_f64: case X64Reg_M128_XMM0: return X64Reg_M128_XMM0; case X64Reg_XMM1_f32: - case X64Reg_XMM1_f64: + case X64Reg_XMM1_f64: case X64Reg_M128_XMM1: return X64Reg_M128_XMM1; case X64Reg_XMM2_f32: - case X64Reg_XMM2_f64: + case X64Reg_XMM2_f64: case X64Reg_M128_XMM2: return X64Reg_M128_XMM2; case X64Reg_XMM3_f32: - case X64Reg_XMM3_f64: + case X64Reg_XMM3_f64: case X64Reg_M128_XMM3: return X64Reg_M128_XMM3; case X64Reg_XMM4_f32: - case X64Reg_XMM4_f64: + case X64Reg_XMM4_f64: case X64Reg_M128_XMM4: return X64Reg_M128_XMM4; case X64Reg_XMM5_f32: - case X64Reg_XMM5_f64: + case X64Reg_XMM5_f64: case X64Reg_M128_XMM5: return X64Reg_M128_XMM5; case X64Reg_XMM6_f32: - case X64Reg_XMM6_f64: + case X64Reg_XMM6_f64: case X64Reg_M128_XMM6: return X64Reg_M128_XMM6; case X64Reg_XMM7_f32: - case X64Reg_XMM7_f64: + case X64Reg_XMM7_f64: case X64Reg_M128_XMM7: return X64Reg_M128_XMM7; case X64Reg_XMM8_f32: - case X64Reg_XMM8_f64: + case X64Reg_XMM8_f64: case X64Reg_M128_XMM8: return X64Reg_M128_XMM8; case X64Reg_XMM9_f32: - case X64Reg_XMM9_f64: + case X64Reg_XMM9_f64: case X64Reg_M128_XMM9: return X64Reg_M128_XMM9; case X64Reg_XMM10_f32: - case X64Reg_XMM10_f64: + case X64Reg_XMM10_f64: case X64Reg_M128_XMM10: return X64Reg_M128_XMM10; case X64Reg_XMM11_f32: - case X64Reg_XMM11_f64: + case X64Reg_XMM11_f64: case X64Reg_M128_XMM11: return X64Reg_M128_XMM11; case X64Reg_XMM12_f32: - case X64Reg_XMM12_f64: + case X64Reg_XMM12_f64: case X64Reg_M128_XMM12: return X64Reg_M128_XMM12; case X64Reg_XMM13_f32: - case X64Reg_XMM13_f64: + case X64Reg_XMM13_f64: case X64Reg_M128_XMM13: return X64Reg_M128_XMM13; case X64Reg_XMM14_f32: - case X64Reg_XMM14_f64: + case X64Reg_XMM14_f64: case X64Reg_M128_XMM14: return X64Reg_M128_XMM14; case X64Reg_XMM15_f32: - case X64Reg_XMM15_f64: + case X64Reg_XMM15_f64: case X64Reg_M128_XMM15: return X64Reg_M128_XMM15; } } @@ -5019,52 +5011,52 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) case X64Reg_R15: return X64Reg_R15; case X64Reg_XMM0_f32: - case X64Reg_XMM0_f64: + case X64Reg_XMM0_f64: case X64Reg_M128_XMM0: return X64Reg_XMM0_f64; case X64Reg_XMM1_f32: - case X64Reg_XMM1_f64: + case X64Reg_XMM1_f64: case X64Reg_M128_XMM1: return X64Reg_XMM1_f64; case X64Reg_XMM2_f32: - case X64Reg_XMM2_f64: + case X64Reg_XMM2_f64: case X64Reg_M128_XMM2: return X64Reg_XMM2_f64; case X64Reg_XMM3_f32: - case X64Reg_XMM3_f64: + case X64Reg_XMM3_f64: case X64Reg_M128_XMM3: return X64Reg_XMM3_f64; case X64Reg_XMM4_f32: - case X64Reg_XMM4_f64: + case X64Reg_XMM4_f64: case X64Reg_M128_XMM4: return X64Reg_XMM4_f64; case X64Reg_XMM5_f32: - case X64Reg_XMM5_f64: + case X64Reg_XMM5_f64: case X64Reg_M128_XMM5: return X64Reg_XMM5_f64; case X64Reg_XMM6_f32: - case X64Reg_XMM6_f64: + case X64Reg_XMM6_f64: case X64Reg_M128_XMM6: return X64Reg_XMM6_f64; case X64Reg_XMM7_f32: - case X64Reg_XMM7_f64: + case X64Reg_XMM7_f64: case X64Reg_M128_XMM7: return X64Reg_XMM7_f64; case X64Reg_XMM8_f32: - case X64Reg_XMM8_f64: + case X64Reg_XMM8_f64: case X64Reg_M128_XMM8: return X64Reg_XMM8_f64; case X64Reg_XMM9_f32: - case X64Reg_XMM9_f64: + case X64Reg_XMM9_f64: case X64Reg_M128_XMM9: return X64Reg_XMM9_f64; case X64Reg_XMM10_f32: - case X64Reg_XMM10_f64: + case X64Reg_XMM10_f64: case X64Reg_M128_XMM10: return X64Reg_XMM10_f64; case X64Reg_XMM11_f32: - case X64Reg_XMM11_f64: + case X64Reg_XMM11_f64: case X64Reg_M128_XMM11: return X64Reg_XMM11_f64; case X64Reg_XMM12_f32: - case X64Reg_XMM12_f64: + case X64Reg_XMM12_f64: case X64Reg_M128_XMM12: return X64Reg_XMM12_f64; case X64Reg_XMM13_f32: - case X64Reg_XMM13_f64: + case X64Reg_XMM13_f64: case X64Reg_M128_XMM13: return X64Reg_XMM13_f64; case X64Reg_XMM14_f32: - case X64Reg_XMM14_f64: + case X64Reg_XMM14_f64: case X64Reg_M128_XMM14: return X64Reg_XMM14_f64; case X64Reg_XMM15_f32: - case X64Reg_XMM15_f64: + case X64Reg_XMM15_f64: case X64Reg_M128_XMM15: return X64Reg_XMM15_f64; } return reg; @@ -5135,52 +5127,52 @@ X64CPURegister BeMCContext::ResizeRegister(X64CPURegister reg, int numBytes) case X64Reg_R15: return X64Reg_R15D; case X64Reg_XMM0_f32: - case X64Reg_XMM0_f64: + case X64Reg_XMM0_f64: case X64Reg_M128_XMM0: return X64Reg_XMM0_f32; case X64Reg_XMM1_f32: - case X64Reg_XMM1_f64: + case X64Reg_XMM1_f64: case X64Reg_M128_XMM1: return X64Reg_XMM1_f32; case X64Reg_XMM2_f32: - case X64Reg_XMM2_f64: + case X64Reg_XMM2_f64: case X64Reg_M128_XMM2: return X64Reg_XMM2_f32; case X64Reg_XMM3_f32: - case X64Reg_XMM3_f64: + case X64Reg_XMM3_f64: case X64Reg_M128_XMM3: return X64Reg_XMM3_f32; case X64Reg_XMM4_f32: - case X64Reg_XMM4_f64: + case X64Reg_XMM4_f64: case X64Reg_M128_XMM4: return X64Reg_XMM4_f32; case X64Reg_XMM5_f32: - case X64Reg_XMM5_f64: + case X64Reg_XMM5_f64: case X64Reg_M128_XMM5: return X64Reg_XMM5_f32; case X64Reg_XMM6_f32: - case X64Reg_XMM6_f64: + case X64Reg_XMM6_f64: case X64Reg_M128_XMM6: return X64Reg_XMM6_f32; case X64Reg_XMM7_f32: - case X64Reg_XMM7_f64: + case X64Reg_XMM7_f64: case X64Reg_M128_XMM7: return X64Reg_XMM7_f32; case X64Reg_XMM8_f32: - case X64Reg_XMM8_f64: + case X64Reg_XMM8_f64: case X64Reg_M128_XMM8: return X64Reg_XMM8_f32; case X64Reg_XMM9_f32: - case X64Reg_XMM9_f64: + case X64Reg_XMM9_f64: case X64Reg_M128_XMM9: return X64Reg_XMM9_f32; case X64Reg_XMM10_f32: - case X64Reg_XMM10_f64: + case X64Reg_XMM10_f64: case X64Reg_M128_XMM10: return X64Reg_XMM10_f32; case X64Reg_XMM11_f32: - case X64Reg_XMM11_f64: + case X64Reg_XMM11_f64: case X64Reg_M128_XMM11: return X64Reg_XMM11_f32; case X64Reg_XMM12_f32: - case X64Reg_XMM12_f64: + case X64Reg_XMM12_f64: case X64Reg_M128_XMM12: return X64Reg_XMM12_f32; case X64Reg_XMM13_f32: - case X64Reg_XMM13_f64: + case X64Reg_XMM13_f64: case X64Reg_M128_XMM13: return X64Reg_XMM13_f32; case X64Reg_XMM14_f32: - case X64Reg_XMM14_f64: + case X64Reg_XMM14_f64: case X64Reg_M128_XMM14: return X64Reg_XMM14_f32; case X64Reg_XMM15_f32: - case X64Reg_XMM15_f64: + case X64Reg_XMM15_f64: case X64Reg_M128_XMM15: return X64Reg_XMM15_f32; } } @@ -5331,52 +5323,52 @@ X64CPURegister BeMCContext::GetFullRegister(X64CPURegister reg) switch (reg) { case X64Reg_XMM0_f32: - case X64Reg_XMM0_f64: + case X64Reg_XMM0_f64: case X64Reg_M128_XMM0: return X64Reg_M128_XMM0; case X64Reg_XMM1_f32: - case X64Reg_XMM1_f64: + case X64Reg_XMM1_f64: case X64Reg_M128_XMM1: return X64Reg_M128_XMM1; case X64Reg_XMM2_f32: - case X64Reg_XMM2_f64: + case X64Reg_XMM2_f64: case X64Reg_M128_XMM2: return X64Reg_M128_XMM2; case X64Reg_XMM3_f32: - case X64Reg_XMM3_f64: + case X64Reg_XMM3_f64: case X64Reg_M128_XMM3: return X64Reg_M128_XMM3; case X64Reg_XMM4_f32: - case X64Reg_XMM4_f64: + case X64Reg_XMM4_f64: case X64Reg_M128_XMM4: return X64Reg_M128_XMM4; case X64Reg_XMM5_f32: - case X64Reg_XMM5_f64: + case X64Reg_XMM5_f64: case X64Reg_M128_XMM5: return X64Reg_M128_XMM5; case X64Reg_XMM6_f32: - case X64Reg_XMM6_f64: + case X64Reg_XMM6_f64: case X64Reg_M128_XMM6: return X64Reg_M128_XMM6; case X64Reg_XMM7_f32: - case X64Reg_XMM7_f64: + case X64Reg_XMM7_f64: case X64Reg_M128_XMM7: return X64Reg_M128_XMM7; case X64Reg_XMM8_f32: - case X64Reg_XMM8_f64: + case X64Reg_XMM8_f64: case X64Reg_M128_XMM8: return X64Reg_M128_XMM8; case X64Reg_XMM9_f32: - case X64Reg_XMM9_f64: + case X64Reg_XMM9_f64: case X64Reg_M128_XMM9: return X64Reg_M128_XMM9; case X64Reg_XMM10_f32: - case X64Reg_XMM10_f64: + case X64Reg_XMM10_f64: case X64Reg_M128_XMM10: return X64Reg_M128_XMM10; case X64Reg_XMM11_f32: - case X64Reg_XMM11_f64: + case X64Reg_XMM11_f64: case X64Reg_M128_XMM11: return X64Reg_M128_XMM11; case X64Reg_XMM12_f32: - case X64Reg_XMM12_f64: + case X64Reg_XMM12_f64: case X64Reg_M128_XMM12: return X64Reg_M128_XMM12; case X64Reg_XMM13_f32: - case X64Reg_XMM13_f64: + case X64Reg_XMM13_f64: case X64Reg_M128_XMM13: return X64Reg_M128_XMM13; case X64Reg_XMM14_f32: - case X64Reg_XMM14_f64: + case X64Reg_XMM14_f64: case X64Reg_M128_XMM14: return X64Reg_M128_XMM14; case X64Reg_XMM15_f32: - case X64Reg_XMM15_f64: + case X64Reg_XMM15_f64: case X64Reg_M128_XMM15: return X64Reg_M128_XMM15; } return ResizeRegister(reg, 8); @@ -5513,7 +5505,7 @@ uint8 BeMCContext::GetREX(const BeMCOperand& r, const BeMCOperand& rm, bool is64 case X64Reg_XMM12_f64: case X64Reg_XMM13_f64: case X64Reg_XMM14_f64: case X64Reg_XMM15_f64: case X64Reg_XMM8_f32: case X64Reg_XMM9_f32: case X64Reg_XMM10_f32: case X64Reg_XMM11_f32: case X64Reg_XMM12_f32: case X64Reg_XMM13_f32: case X64Reg_XMM14_f32: case X64Reg_XMM15_f32: - case X64Reg_M128_XMM8: case X64Reg_M128_XMM9: case X64Reg_M128_XMM10: case X64Reg_M128_XMM11: + case X64Reg_M128_XMM8: case X64Reg_M128_XMM9: case X64Reg_M128_XMM10: case X64Reg_M128_XMM11: case X64Reg_M128_XMM12: case X64Reg_M128_XMM13: case X64Reg_M128_XMM14: case X64Reg_M128_XMM15: is64BitExR = true; } @@ -5600,7 +5592,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_XMM0_f64: case X64Reg_M128_XMM0: case X64Reg_XMM8_f32: - case X64Reg_XMM8_f64: + case X64Reg_XMM8_f64: case X64Reg_M128_XMM8: return 0; case X64Reg_CL: @@ -5627,7 +5619,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R10D: case X64Reg_R10W: case X64Reg_R10B: - case X64Reg_MM2: + case X64Reg_MM2: case X64Reg_XMM2_f32: case X64Reg_XMM2_f64: case X64Reg_M128_XMM2: @@ -5643,7 +5635,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R11D: case X64Reg_R11W: case X64Reg_R11B: - case X64Reg_MM3: + case X64Reg_MM3: case X64Reg_XMM3_f32: case X64Reg_XMM3_f64: case X64Reg_M128_XMM3: @@ -5660,7 +5652,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R12D: case X64Reg_R12W: case X64Reg_R12B: - case X64Reg_MM4: + case X64Reg_MM4: case X64Reg_XMM4_f32: case X64Reg_XMM4_f64: case X64Reg_M128_XMM4: @@ -5676,7 +5668,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R13D: case X64Reg_R13W: case X64Reg_R13B: - case X64Reg_MM5: + case X64Reg_MM5: case X64Reg_XMM5_f32: case X64Reg_XMM5_f64: case X64Reg_M128_XMM5: @@ -5693,7 +5685,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R14D: case X64Reg_R14W: case X64Reg_R14B: - case X64Reg_MM6: + case X64Reg_MM6: case X64Reg_XMM6_f32: case X64Reg_XMM6_f64: case X64Reg_M128_XMM6: @@ -5710,7 +5702,7 @@ uint8 BeMCContext::EncodeRegNum(X64CPURegister regNum) case X64Reg_R15D: case X64Reg_R15W: case X64Reg_R15B: - case X64Reg_MM7: + case X64Reg_MM7: case X64Reg_XMM7_f32: case X64Reg_XMM7_f64: case X64Reg_M128_XMM7: @@ -5743,12 +5735,12 @@ void BeMCContext::ValidateRMResult(const BeMCOperand& operand, BeRMParamsInfo& r //TODO: WTF- this previous version just seems to be wrong! Why did think this was true? the REX.X and REX.B flags fix these // in a SIB, the base can't be R13 (which is RBP+REX), and the scaled index can't be R12 (which is RSP+REX) - //if ((regB != X64Reg_None) && + //if ((regB != X64Reg_None) && // ((regA == X64Reg_R13) || (regB == X64Reg_R12))) - //{ + //{ // // We can't just swap the regs if we have a scale applied // if (bScale != 1) - // { + // { // if (errorVReg != NULL) // *errorVReg = -2; // Scale error // return BeMCRMMode_Invalid; @@ -5914,12 +5906,11 @@ void BeMCContext::GetRMParams(const BeMCOperand& operand, BeRMParamsInfo& rmInfo // A deref can only stand alone, and no double-derefs if ((vregInfo->mRelOffset) || (vregInfo->mRelOffsetScale != 1) || (operand.mKind == BeMCOperandKind_VRegLoad)) { - BF_ASSERT(vregInfo->mRelTo.IsVRegAny()); rmInfo.mErrorVReg = vregInfo->mRelTo.mVRegIdx; // For some reason we had changed this to: //*errorVReg = operand.mVRegIdx; - // This doesn't work, it's the deref that we want to isolate, otherwise we just end up creating another invalid expression + // This doesn't work, it's the deref that we want to isolate, otherwise we just end up creating another invalid expression rmInfo.mMode = BeMCRMMode_Invalid; return; } @@ -6117,7 +6108,6 @@ void BeMCContext::GetValAddr(const BeMCOperand& operand, X64CPURegister& reg, in offset = mStackSize + vregInfo->mFrameOffset; } - int BeMCContext::GetHighestVRegRef(const BeMCOperand& operand) { if (!operand.IsVRegAny()) @@ -6355,7 +6345,7 @@ void BeMCContext::EmitModRM(int rx, BeMCOperand rm, int relocOfs) BeRMParamsInfo rmInfo; GetRMParams(rm, rmInfo); - //BF_ASSERT(resultType != BeMCRMMode_Invalid); + //BF_ASSERT(resultType != BeMCRMMode_Invalid); BF_ASSERT(rmInfo.mMode == BeMCRMMode_Deref); EmitModRMRel(rx, rmInfo.mRegA, rmInfo.mRegB, rmInfo.mBScale, rmInfo.mDisp); return; @@ -6669,7 +6659,6 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } } - if ((inst->mResult) && (inst->mResult.mKind == BeMCOperandKind_CmpResult)) { auto& cmpResult = mCmpResults[inst->mResult.mCmpResultIdx]; @@ -6716,7 +6705,6 @@ void BeMCContext::InitializedPassHelper(BeMCBlock* mcBlock, BeVTrackingGenContex } } - if (inst->mKind == BeMCInstKind_LifetimeEnd) { // In some cases we can have a dbg variable that actually points to a global variable (due to macros/inlining/etc), so this check is for that case: @@ -6966,7 +6954,6 @@ void BeMCContext::ReplaceVRegsInit(BeMCBlock* mcBlock, int startInstIdx, BeVTrac // This pass does bottom-up initialization for "simple" vregs (ie: not variables) void BeMCContext::SimpleInitializedPass() { - } void BeMCContext::GenerateVRegInitFlags(BeVTrackingGenContext& genCtx) @@ -7083,7 +7070,7 @@ bool BeMCContext::DoInitializedPass() // Unused block - clear almost all instructions int newIdx = 0; // for (int instIdx = 0; instIdx < (int)mcBlock->mInstructions.size(); instIdx++) - // { + // { // auto inst = mcBlock->mInstructions[instIdx]; // if (inst->mKind == BeMCInstKind_ValueScopeHardEnd) // { @@ -7225,6 +7212,9 @@ void BeMCContext::DoChainedBlockMerge() for (int blockIdx = 0; blockIdx < mBlocks.size() - 1; blockIdx++) { auto mcBlock = mBlocks[blockIdx]; + if (mcBlock->mHasFakeBr) + continue; + auto nextMcBlock = mBlocks[blockIdx + 1]; // We only branch into one block, and the the next block only has current block as a predecessor? @@ -7355,7 +7345,6 @@ void BeMCContext::DoSplitLargeBlocks() } } } - } void BeMCContext::DetectLoops() @@ -7581,7 +7570,7 @@ void BeMCContext::DoInstCombinePass() SetCurrentInst(inst); //TODO: Remove - // if we've remapped other vregs onto this that aren't dead, then we can't end the value lifetime but we + // if we've remapped other vregs onto this that aren't dead, then we can't end the value lifetime but we // must end the lifetime of the visible debug variable /*if (inst->mKind == BeMCInstKind_LifetimeEnd) { @@ -7730,7 +7719,7 @@ void BeMCContext::DoInstCombinePass() if ((vregInfo->IsDirectRelTo()) && (vregInfo->mDbgVariable == NULL) && (CheckVRegEqualityRange(mcBlock, instIdx, mcLoaded, mcAddr, regRemaps, true))) { // If the source value doesn't change in the lifetime of the loaded value then - // we can just map directly to the source - no copy needed. + // we can just map directly to the source - no copy needed. inst->mKind = BeMCInstKind_Def; AddRegRemap(inst->mArg0.mVRegIdx, vregInfoDest->mRelTo.mVRegIdx, regRemaps, true); continue; @@ -7921,8 +7910,8 @@ void BeMCContext::DoInstCombinePass() } else { - // If we're dealing with a non-Mov instruction, then the values of both of these vregs will - // be different after the instruction, so we can only map them if the incoming vreg will be dead + // If we're dealing with a non-Mov instruction, then the values of both of these vregs will + // be different after the instruction, so we can only map them if the incoming vreg will be dead // afterwards. If both are dbgVariables then we can't allow them to coeexist because the user // could edit one of the values in the debugger and we don't want the other one changing. if ((nextNextInst != NULL) && @@ -7939,8 +7928,8 @@ void BeMCContext::DoInstCombinePass() if (vregInfoDest->mIsRetVal) { - // We don't do a remap for this return value optimization, because we want both vregs - // to still show in the debugger - even though they will point to the same address + // We don't do a remap for this return value optimization, because we want both vregs + // to still show in the debugger - even though they will point to the same address // now (in the case of a struct return) vregInfoCheck->SetRetVal(); //BF_ASSERT(mCompositeRetVRegIdx != -1); @@ -8013,11 +8002,10 @@ void BeMCContext::DoInstCombinePass() } } - // For the form // %vreg0, %vreg1 // Test %vreg0, 1 - // Remove test, because the BinOp will already set the correct flags + // Remove test, because the BinOp will already set the correct flags if ((nextInst->mKind == BeMCInstKind_Test) && (nextInst->mArg1.IsImmediateInt()) && (nextInst->mArg1.mImmediate == 1) && (nextInst->mArg0 == inst->mArg0)) { @@ -8077,7 +8065,7 @@ void BeMCContext::DoInstCombinePass() // For the form: // %vreg2 = %vreg0, %vreg1 - // If %vreg0 ends its life on this instruction, + // If %vreg0 ends its life on this instruction, // Replace all instances of %vreg2 with %vreg0 if ((inst->mResult.mKind == BeMCOperandKind_VReg) && (inst->mArg0.mKind == BeMCOperandKind_VReg) && (inst->mResult != inst->mArg0)) @@ -8120,7 +8108,7 @@ void BeMCContext::DoInstCombinePass() if (!hadInvalidInst) { - // We return after this, we don't need to restore volatiles + // We return after this, we don't need to restore volatiles inst->mArg1 = BeMCOperand::FromPreserveFlag(BeMCPreserveFlag_NoRestore); continue; } @@ -8164,12 +8152,12 @@ void BeMCContext::DoInstCombinePass() } } - // For the form: + // For the form: // %vreg0 = CmpToBool // Test %vreg0, %vreg0 // CondBr %label, eq - // If %vreg0 has no other references, convert to: - // CondBr %label, + // If %vreg0 has no other references, convert to: + // CondBr %label, if ((inst->mKind == BeMCInstKind_CmpToBool) && (nextInst->mKind == BeMCInstKind_Test) && (nextInst->mArg0 == nextInst->mArg1) && (nextNextInst->mKind == BeMCInstKind_CondBr) && @@ -8219,7 +8207,6 @@ void BeMCContext::DoInstCombinePass() int* prevBestVRegIdxPtr = NULL; if (defMap.TryGetValue(remapTo, &prevBestVRegIdxPtr)) { - } else defMap[remapTo] = bestVRegIdx; @@ -8233,7 +8220,7 @@ void BeMCContext::DoInstCombinePass() Array<_RemapEntry> initRemaps; - // We have a many-to-one relation so we have to use both a + // We have a many-to-one relation so we have to use both a HashSet keepDefs; for (auto& defPair : defMap) keepDefs.Add(defPair.mValue); @@ -8390,7 +8377,7 @@ void BeMCContext::DoRegAssignPass() BP_ZONE("BeMCContext::DoRegAssignPass"); bool generateLiveness = true; - // + // if (generateLiveness) { for (auto& node : mColorizer.mNodes) @@ -8455,18 +8442,17 @@ void BeMCContext::DoRegAssignPass() #endif } - void BeMCContext::DoFrameObjPass() { - BF_ASSERT(mBlocks.size() == 1); + BF_ASSERT(mBlocks.size() == 1); SetCurrentInst(NULL); // MS x64 ABI requires a "home address" of 4 intptrs when we call a function, plus whatever - // we need for calls with more than 4 params. + // we need for calls with more than 4 params. // If we're doing UseBP, we have to allocate these at call time int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16); - + mStackSize = 0; if (mUseBP) @@ -8522,7 +8508,7 @@ void BeMCContext::DoFrameObjPass() } } - // If we have dynamic stack resizing then we have a stack frame and must be 16-byte aligned + // If we have dynamic stack resizing then we have a stack frame and must be 16-byte aligned // even if we're a leaf function bool mHasFramePointer = false; @@ -8535,7 +8521,7 @@ void BeMCContext::DoFrameObjPass() //if (!mUseBP) { // MS x64 ABI requires a "home address" of 4 intptrs when we call a function, plus whatever - // we need for calls with more than 4 params. + // we need for calls with more than 4 params. // If we're doing UseBP, we have to allocate these at call time if (mMaxCallParamCount != -1) { @@ -8557,7 +8543,7 @@ void BeMCContext::DoFrameObjPass() } mActiveBlock = mBlocks[0]; - + if (mUseBP) { AllocInst(BeMCInstKind_Unwind_SetBP, 0); @@ -9035,14 +9021,18 @@ bool BeMCContext::DoLegalization() auto scratchVRegInfo = mVRegInfo[scratchReg.mVRegIdx]; // If a scratch vreg needs to preserve a register like the remapped vreg + scratchVRegInfo->mDisableR11 |= remappedVRegInfo->mDisableR11; + scratchVRegInfo->mDisableR12 |= remappedVRegInfo->mDisableR12; + scratchVRegInfo->mDisableR13 |= remappedVRegInfo->mDisableR13; scratchVRegInfo->mDisableRAX |= remappedVRegInfo->mDisableRAX; scratchVRegInfo->mDisableRDX |= remappedVRegInfo->mDisableRDX; + scratchVRegInfo->mDisableEx |= remappedVRegInfo->mDisableEx; if ((insertPos == instIdx) || (!scratchForceReg)) { // Only allow short-lived forceRegs instIdx += 2; - //origOperand.mVRegIdx = scratchReg.mVRegIdx; + //origOperand.mVRegIdx = scratchReg.mVRegIdx; origOperand = newOperand; } else @@ -9146,7 +9136,7 @@ bool BeMCContext::DoLegalization() bool isIncOrDec = false; isIncOrDec = (((inst->mKind == BeMCInstKind_Add) || (inst->mKind == BeMCInstKind_Sub)) && (arg1.IsImmediateInt()) && (arg1.mImmediate == 1)); - + if ((!isIncOrDec) && (!isIntMul) && (!isIntDiv)) { if ((arg0.MayBeMemory()) && (arg1.MayBeMemory())) @@ -9182,7 +9172,7 @@ bool BeMCContext::DoLegalization() if (badOps) { - // On X64 we can never have an instruction where both args are memory so we create a short-lived scratch vreg + // On X64 we can never have an instruction where both args are memory so we create a short-lived scratch vreg // and run another reg pass to generate register access // From: a, b @@ -9190,7 +9180,7 @@ bool BeMCContext::DoLegalization() // mov scratch, b // a, scratch auto targetType = GetType(inst->mArg0); - + if ((targetType->IsFloat()) && (!inst->mResult) && (arg0.IsVReg()) && (arg1.IsImmediateFloat())) { auto vregInfo0 = GetVRegInfo(arg0); @@ -9210,7 +9200,7 @@ bool BeMCContext::DoLegalization() continue; } } - + if (!targetType->IsNonVectorComposite()) { auto scratchType = GetType(inst->mArg1); @@ -9290,7 +9280,7 @@ bool BeMCContext::DoLegalization() { // From: b = Sub a, b // To: Neg b - // Add b, a + // Add b, a AllocInst(BeMCInstKind_Add, inst->mResult, inst->mArg0, instIdx + 1); inst->mKind = BeMCInstKind_Neg; inst->mArg0 = inst->mResult; @@ -9389,7 +9379,7 @@ bool BeMCContext::DoLegalization() if (!mLivenessContext.IsSet(nextInst->mLiveness, underlyingVRegIdx)) { // Convert a "Mul %vreg0, %vreg1" - // To + // To // Mul %reg1, %vreg0 // Mov %vreg0, %reg1 // This only works if %reg1 dies after this instruction and this is @@ -9420,14 +9410,13 @@ bool BeMCContext::DoLegalization() if (inst->mKind == BeMCInstKind_Call) { - // Convert from // Mov %reg0, // .. // Call %reg0 // To "Call " // This is a common case for virtual dispatch where complex address expressions get actualized - // but then we end up with an 'extra' vreg + // but then we end up with an 'extra' vreg if (inst->mArg0.IsVReg()) { auto vregInfo = GetVRegInfo(inst->mArg0); @@ -9618,7 +9607,7 @@ bool BeMCContext::DoLegalization() //if (vregExprChangeSet.find(errorVRegIdx) != vregExprChangeSet.end()) if (vregExprChangeSet.Contains(rmInfo.mErrorVReg)) { - // This means we have already modified some dependent vregs, so we may be legalized already. + // This means we have already modified some dependent vregs, so we may be legalized already. // Wait till next iteration to determine that. BF_ASSERT(!isFinalRun); isValid = true; // @@ -9668,8 +9657,8 @@ bool BeMCContext::DoLegalization() else { // We don't want to have too many concurrent ForceReg vregs at once, since that causes too much register pressure and - // can cause register allocation to fail at the extreme end. The scratchReg adds another ForceReg for the lifetime - // of the def vreg, so if the def vreg doesn't immediately die and there are already too many ForceRegs active then + // can cause register allocation to fail at the extreme end. The scratchReg adds another ForceReg for the lifetime + // of the def vreg, so if the def vreg doesn't immediately die and there are already too many ForceRegs active then // we need to actualize ourselves bool actualizeSelf = false; if (instIdx < mcBlock->mInstructions.size() - 2) @@ -9701,7 +9690,7 @@ bool BeMCContext::DoLegalization() } else { - // This may be a local variable that failed to be assigned to a reg, create a scratch local with a forced reg + // This may be a local variable that failed to be assigned to a reg, create a scratch local with a forced reg auto errorVReg = BeMCOperand::FromVReg(rmInfo.mErrorVReg); auto errorVRegLoad = BeMCOperand::ToLoad(errorVReg); @@ -9732,7 +9721,7 @@ bool BeMCContext::DoLegalization() } else if ((vregInfo->mRelTo == errorVRegLoad) || (vregInfo->mRelOffset == errorVRegLoad)) { - auto scratchType = GetType(errorVRegLoad); + auto scratchType = GetType(errorVRegLoad); auto scratchReg = AllocVirtualReg(scratchType, 2, false); auto scratchVRegInfo = mVRegInfo[scratchReg.mVRegIdx]; @@ -9844,8 +9833,6 @@ bool BeMCContext::DoLegalization() break; } - - if (!mVRegInitializedContext.IsSet(inst->mVRegsInitialized, vregIdx)) { if ((dbgVar->mPendingInitType != BfIRInitType_NotNeeded) && (dbgVar->mPendingInitType != BfIRInitType_NotNeeded_AliveOnDecl)) @@ -10111,7 +10098,7 @@ bool BeMCContext::DoLegalization() if (preserveRDX) DisableRegister(inst->mArg0, X64Reg_RDX); AllocInst(BeMCInstKind_Mov, inst->mArg0, mcRemaindier, instIdx++ + 1); - } + } } else { @@ -10180,8 +10167,8 @@ bool BeMCContext::DoLegalization() AllocInst(BeMCInstKind_PreserveVolatiles, BeMCOperand::FromReg(X64Reg_RAX), instIdx++); DisableRegister(inst->mArg0, X64Reg_RAX); - DisableRegister(inst->mArg1, X64Reg_RAX); - + DisableRegister(inst->mArg1, X64Reg_RAX); + AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(X64Reg_AL), inst->mArg1, instIdx++); AllocInst(BeMCInstKind_Shl, BeMCOperand::FromReg(X64Reg_AX), BeMCOperand::FromImmediate(8), instIdx++); AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(X64Reg_AL), inst->mArg0, instIdx++); @@ -10226,7 +10213,7 @@ bool BeMCContext::DoLegalization() AllocInst(BeMCInstKind_RestoreVolatiles, BeMCOperand::FromReg(X64Reg_RDX), instIdx++ + 1); AllocInst(BeMCInstKind_RestoreVolatiles, BeMCOperand::FromReg(X64Reg_RAX), instIdx++ + 1); - isFinalRun = false; + isFinalRun = false; break; } @@ -10240,26 +10227,26 @@ bool BeMCContext::DoLegalization() } if (inst->mArg0.IsNativeReg()) - { + { auto vregInfo1 = GetVRegInfo(inst->mArg1); if (vregInfo1 != NULL) { auto arg1 = GetFixedOperand(inst->mArg1); if ((arg1.IsNativeReg()) && (inst->mArg0.mReg == arg1.mReg) && ((ResizeRegister(arg1.mReg, 8) == X64Reg_RAX) || (ResizeRegister(arg1.mReg, 8) == X64Reg_RDX))) - { + { DisableRegister(inst->mArg1, X64Reg_RAX); DisableRegister(inst->mArg1, X64Reg_RDX); isFinalRun = false; } } } - + if (!handled) { if (inst->mResult) { - // The 3-op form of MUL must be in "reg, r/m64, imm" form + // The 3-op form of MUL must be in "reg, r/m64, imm" form if (!inst->mArg1.IsImmediateInt()) { SoftFail("Not supported"); @@ -10321,7 +10308,6 @@ bool BeMCContext::DoLegalization() case BeMCInstKind_Add: case BeMCInstKind_Sub: { - } break; case BeMCInstKind_Shl: @@ -10422,7 +10408,7 @@ bool BeMCContext::DoLegalization() { NotImpl(); //mcBlock->RemoveInst(instIdx); - //instIdx--; + //instIdx--; } else { @@ -10595,7 +10581,7 @@ bool BeMCContext::DoLegalization() isFinalRun = false; } continue; - } + } else // Struct = Struct { auto arg0Addr = OperandToAddr(arg0); @@ -10609,7 +10595,6 @@ bool BeMCContext::DoLegalization() OutputDebugStrF(" Mov MemCpy\n"); break; } - } if ((arg0Type->IsFloat()) && (arg1Type->IsIntable())) @@ -10650,9 +10635,9 @@ bool BeMCContext::DoLegalization() } else if ((!isSignedExt) || (arg1Type->mSize < 4)) { - // Int->Float conversions only work on 32 and 64-bit signed values, so we + // Int->Float conversions only work on 32 and 64-bit signed values, so we // zero-extend into a larger scratch vreg and then we do the signed conversion on that. - // Convert from + // Convert from // mov float, uint // to // mov scratch int, uint @@ -10687,7 +10672,7 @@ bool BeMCContext::DoLegalization() if ((arg0Type->mTypeCode == BeTypeCode_Double) && (arg1.IsImmediate())) { // One option would be to do a "movsd xmm, .rdata" to load up the immediate... - // and that would leave arg0 with the possibility of binding to a register + // and that would leave arg0 with the possibility of binding to a register // in a subsequent reg pass, but we don't do that. //ReplaceWithNewVReg(inst->mArg1, instIdx, true); @@ -10831,7 +10816,7 @@ bool BeMCContext::DoLegalization() case BeMCInstKind_Load: { // And Load gets converted to a "Load %reg0, [%reg1]" - // So both mArg0 and mArg1 must be a register + // So both mArg0 and mArg1 must be a register if (!IsAddressable(arg1)) { // Convert to @@ -10859,7 +10844,7 @@ bool BeMCContext::DoLegalization() break; case BeMCInstKind_Store: { - // Store gets converted to a "Store [reg], reg" + // Store gets converted to a "Store [reg], reg" if (!IsAddressable(arg0)) { // Convert to @@ -11393,7 +11378,7 @@ void BeMCContext::DoRegFinalization() } // This is similar to an optimization we have in DoLegalization, but it allows for directRelTo's to match - // We can't match those in DoLegalization because it would alter the liveness + // We can't match those in DoLegalization because it would alter the liveness if (inst->mKind == BeMCInstKind_Mov) { // Useless mov, remove it @@ -11440,7 +11425,6 @@ void BeMCContext::DoRegFinalization() { if (inst->mArg1.IsNativeReg()) { - } }*/ @@ -11556,7 +11540,7 @@ void BeMCContext::DoRegFinalization() continue; } - if (IsVolatileReg(vregInfo->mReg)) + if ((inst->mArg0.IsNativeReg()) || (IsVolatileReg(vregInfo->mReg))) { if (vregInfo->mVolatileVRegSave == -1) { @@ -11679,7 +11663,7 @@ void BeMCContext::DoRegFinalization() if (isFinalPass) { - // We've failed to reorder + // We've failed to reorder int deferredIdx = 0; for (int instIdx = preserveIdx + 1; instIdx < instEndIdx; instIdx++) @@ -11696,7 +11680,7 @@ void BeMCContext::DoRegFinalization() auto reg = GetFullRegister(inst->mArg0.mReg); if (regFailed[(int)reg]) { - // Convert + // Convert // Mov , vreg0 // To // Push vreg0 @@ -11733,8 +11717,8 @@ void BeMCContext::DoRegFinalization() } else { - // Use R11 or XMM5 as our temporary - they are the least likely volatiles to be - // allocated, so we may not need to restore them after using them + // Use R11 or XMM5 as our temporary - they are the least likely volatiles to be + // allocated, so we may not need to restore them after using them X64CPURegister scratchReg; if (pushType->mTypeCode == BeTypeCode_Float) @@ -11890,8 +11874,8 @@ BeMCInstForm BeMCContext::GetInstForm(BeMCInst* inst) switch (arg1Type->mTypeCode) { case BeTypeCode_Float: return BeMCInstForm_XMM64_FRM32; - case BeTypeCode_Double: return BeMCInstForm_XMM64_FRM64; - case BeTypeCode_Int32: return BeMCInstForm_XMM64_RM32; + case BeTypeCode_Double: return BeMCInstForm_XMM64_FRM64; + case BeTypeCode_Int32: return BeMCInstForm_XMM64_RM32; case BeTypeCode_Int64: return BeMCInstForm_XMM64_RM64; case BeTypeCode_Pointer: return BeMCInstForm_XMM64_RM64; default: NotImpl(); @@ -11954,7 +11938,7 @@ BeMCInstForm BeMCContext::GetInstForm(BeMCInst* inst) else NotImpl(); } - } + } if ((arg1.IsImmediate()) && (arg0Type != NULL)) // MOV r/m64, imm32 { @@ -12281,7 +12265,7 @@ void BeMCContext::EmitStdInst(BeMCInstForm instForm, BeMCInst * inst, uint8 opco case BeMCInstForm_RM16_IMM8: EmitInst(BeMCInstForm_RM16_IMM8, opcode_rm_imm8, opcode_rm_imm8_rx, inst); break; case BeMCInstForm_RM32_IMM8: EmitInst(BeMCInstForm_RM32_IMM8, opcode_rm_imm8, opcode_rm_imm8_rx, inst); break; case BeMCInstForm_RM64_IMM8: EmitInst(BeMCInstForm_RM64_IMM8, opcode_rm_imm8, opcode_rm_imm8_rx, inst); break; - // These immediate forms assume an expansion to imm32, OR the register size for 8 and 16 bit registers + // These immediate forms assume an expansion to imm32, OR the register size for 8 and 16 bit registers case BeMCInstForm_RM32_IMM16: EmitInst(BeMCInstForm_RM32_IMM32, opcode_rm_imm, opcode_rm_imm_rx, inst); break; case BeMCInstForm_RM16_IMM16: EmitInst(BeMCInstForm_RM16_IMM16, opcode_rm_imm, opcode_rm_imm_rx, inst); break; case BeMCInstForm_RM64_IMM16: EmitInst(BeMCInstForm_RM64_IMM32, opcode_rm_imm, opcode_rm_imm_rx, inst); break; @@ -12339,7 +12323,7 @@ bool BeMCContext::EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 op } if (arg1Type->IsFloat()) - { + { if (elemType == BeTypeCode_Double) Emit(0x66); EmitREX(arg1, arg1, false); @@ -12347,7 +12331,7 @@ bool BeMCContext::EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 op EmitModRM(arg1, arg1); Emit(0); } - + if (elemType == BeTypeCode_Double) Emit(0x66); EmitREX(arg0, arg1, is64Bit); @@ -12364,7 +12348,7 @@ bool BeMCContext::EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 op // } NOP; - break; + break; } return false; @@ -12532,7 +12516,7 @@ bool BeMCContext::EmitIntBitwiseXMMInst(BeMCInstForm instForm, BeMCInst* inst, u auto arg0 = GetFixedOperand(inst->mArg0); auto arg1 = GetFixedOperand(inst->mArg1); - auto arg0Type = GetType(inst->mArg0); + auto arg0Type = GetType(inst->mArg0); if (arg0Type->IsExplicitVectorType()) { @@ -12540,7 +12524,7 @@ bool BeMCContext::EmitIntBitwiseXMMInst(BeMCInstForm instForm, BeMCInst* inst, u if ((vecType->mElementType->mTypeCode == BeTypeCode_Int8) || (vecType->mElementType->mTypeCode == BeTypeCode_Int16) || (vecType->mElementType->mTypeCode == BeTypeCode_Int32)) - { + { arg1 = IntXMMGetPacked(arg1, vecType); Emit(0x66); @@ -12934,7 +12918,7 @@ void BeMCContext::DoCodeEmission() bool allowEmission = true; if (inst->mKind == BeMCInstKind_DbgDecl) { - // We need to separate out dbgDecls if we are attempting to extend a previous one, + // We need to separate out dbgDecls if we are attempting to extend a previous one, // otherwise wait for a real instruction if (dbgExtendLifetime) { @@ -13036,7 +13020,6 @@ void BeMCContext::DoCodeEmission() dbgStr += StrFormat("#### %d Dbg End Gap %s\n", funcCodePos, dbgVar->mName.c_str()); } } - } } else // Removed @@ -13079,7 +13062,7 @@ void BeMCContext::DoCodeEmission() } // Finish range for variables exiting liveness. Since liveness is built in end-to-start order, - // an "add" means that the NEXT instruction won't have this entry (if the next entry doesn't share + // an "add" means that the NEXT instruction won't have this entry (if the next entry doesn't share // the exact liveness value) if ((inst->mLiveness != NULL) && (inst->mLiveness != vregsLive)) { @@ -13124,8 +13107,8 @@ void BeMCContext::DoCodeEmission() dbgStr += StrFormat("#### %d Dbg Setting LifetimeExtend %s\n", funcCodePos, dbgVar->mName.c_str()); } dbgVar->mDeclLifetimeExtend = dbgExtendLifetime; - //if (dbgExtendLifetime) - //dbgVar->mDeclEnd++; + //if (dbgExtendLifetime) + //dbgVar->mDeclEnd++; } } } @@ -13230,29 +13213,28 @@ void BeMCContext::DoCodeEmission() } } break; - case BeMCInstKind_DbgRangeStart: - { - - } - break; - case BeMCInstKind_DbgRangeEnd: - { - auto vregInfo = GetVRegInfo(inst->mArg0); - if (vregInfo->mDbgVariable != NULL) - { - auto dbgVar = vregInfo->mDbgVariable; - dbgVar->mDeclEnd = funcCodePos; - dbgVar->mDeclLifetimeExtend = false; - BF_ASSERT((uint)dbgVar->mDeclEnd >= (uint)dbgVar->mDeclStart); - } - } - break; case BeMCInstKind_LifetimeExtend: break; case BeMCInstKind_LifetimeStart: break; case BeMCInstKind_LifetimeEnd: break; + case BeMCInstKind_LifetimeSoftEnd: + { + auto vregInfo = GetVRegInfo(inst->mArg0); + if ((vregInfo != NULL) && (vregInfo->mDbgVariable != NULL)) + { + auto dbgVar = vregInfo->mDbgVariable; + if (dbgVar->mDeclStart != -1) + { + dbgVar->mDeclEnd = funcCodePos; + dbgVar->mDeclLifetimeExtend = false; + dbgVar->mDbgLifeEnded = true; + BF_ASSERT((uint)dbgVar->mDeclEnd >= (uint)dbgVar->mDeclStart); + } + } + } + break; case BeMCInstKind_ValueScopeSoftEnd: break; case BeMCInstKind_ValueScopeHardEnd: @@ -13341,7 +13323,7 @@ void BeMCContext::DoCodeEmission() X64CPURegister srcReg = X64Reg_R11; int destOfs = 0; int srcOfs = 0; - + if (inst->mArg1) { BF_ASSERT(inst->mArg1.mKind == BeMCOperandKind_VRegPair); @@ -13460,7 +13442,7 @@ void BeMCContext::DoCodeEmission() Emit(0x8B); Emit(0x04 | (EncodeRegNum(vregInfo->mReg) << 3)); Emit(0x25); mOut.Write((int32)0x58); - // mov tlsReg, qword ptr [tlsReg + 8*rax] + // mov tlsReg, qword ptr [tlsReg + 8*rax] EmitREX(tlsOperand, tlsOperand, true); Emit(0x8B); EmitModRMRel(EncodeRegNum(vregInfo->mReg), vregInfo->mReg, X64Reg_RAX, 8, 0); @@ -13468,7 +13450,7 @@ void BeMCContext::DoCodeEmission() } break; case BeMCInstKind_PreserveVolatiles: - { + { for (int vregIdx : *inst->mLiveness) { if (vregIdx >= mLivenessContext.mNumItems) @@ -13552,7 +13534,7 @@ void BeMCContext::DoCodeEmission() } lastLabelIdx = inst->mArg0.mLabelIdx; labelPositions[inst->mArg0.mLabelIdx] = funcCodePos; - // This ensures we can't jump back into the hot jump area + // This ensures we can't jump back into the hot jump area break; case BeMCInstKind_Nop: Emit(0x90); @@ -13845,8 +13827,8 @@ void BeMCContext::DoCodeEmission() EmitREX(arg0, arg1, true); Emit(0x0F); Emit(0x10); - if (arg1.IsImmediateInt()) - arg1.mKind = BeMCOperandKind_Immediate_int32x4; + if (arg1.IsImmediateInt()) + arg1.mKind = BeMCOperandKind_Immediate_int32x4; EmitModRM(arg0, arg1); } @@ -13873,7 +13855,7 @@ void BeMCContext::DoCodeEmission() Emit(0x0F); Emit(0x54); EmitModRM(xmm15, imm1); - // PACKUSWB xmm15, xmm15 + // PACKUSWB xmm15, xmm15 Emit(0x66); EmitREX(xmm15, xmm15, true); Emit(0x0F); Emit(0x67); EmitModRM(xmm15, xmm15); @@ -13916,8 +13898,7 @@ void BeMCContext::DoCodeEmission() } else if ((arg0Type->mTypeCode == BeTypeCode_Int32) || (arg0Type->mTypeCode == BeTypeCode_Int64)) { - - // For 64-bit writes, we would like to use 32-bit zero extension but we resort to the full + // For 64-bit writes, we would like to use 32-bit zero extension but we resort to the full // 64-bits if necessary auto arg0 = inst->mArg0; if (arg0Type->mTypeCode == BeTypeCode_Int64) @@ -14163,7 +14144,6 @@ void BeMCContext::DoCodeEmission() if (inst->mArg1.IsSymbol()) { BF_ASSERT(inst->mArg0.IsNativeReg()); - } switch (instForm) @@ -14274,7 +14254,7 @@ void BeMCContext::DoCodeEmission() BF_ASSERT(inst->mArg1.IsImmediate()); // Is there a performance benefit to properly using MOVAPD vs MOVAPS if we only // use this register for double storage? - // MOVAPS + // MOVAPS EmitREX(inst->mArg0, BeMCOperand(), false); Emit(0x0F); Emit(0x29); EmitModRMRel(EncodeRegNum(inst->mArg0.mReg), X64Reg_RSP, X64Reg_None, 1, (int)inst->mArg1.mImmediate); @@ -14331,7 +14311,7 @@ void BeMCContext::DoCodeEmission() BF_ASSERT(inst->mArg1.IsImmediate()); // Is there a performance benefit to properly using MOVAPD vs MOVAPS if we only // use this register for double storage? - // MOVAPS + // MOVAPS EmitREX(inst->mArg0, BeMCOperand(), false); Emit(0x0F); Emit(0x28); // Push always uses RSP (required for stack unwinding), but Pop uses RBP when applicable @@ -14583,7 +14563,7 @@ void BeMCContext::DoCodeEmission() } //Fallthrough case BeMCInstKind_IMul: - { + { if (instForm == BeMCInstForm_XMM128_RM128) { if (arg0Type->IsExplicitVectorType()) @@ -14599,7 +14579,7 @@ void BeMCContext::DoCodeEmission() else { Emit(0x38); Emit(0x40); // PMULLD - } + } EmitModRM(arg0, arg1); break; } @@ -14617,7 +14597,7 @@ void BeMCContext::DoCodeEmission() BF_ASSERT(inst->mArg1.IsImmediate()); if ((inst->mArg0.IsNativeReg()) && (!inst->mDisableShortForm) && ((inst->mArg1.mImmediate == 2) || (inst->mArg1.mImmediate == 4) || (inst->mArg1.mImmediate == 8))) - { + { // LEA form auto resultType = GetType(inst->mArg0); if (resultType->mTypeCode != BeTypeCode_Int8) @@ -14739,7 +14719,7 @@ void BeMCContext::DoCodeEmission() case BeTypeCode_Int16: BF_ASSERT((inst->mArg0.IsNativeReg()) && (inst->mArg0.mReg == X64Reg_AX)); // XOR dx, dx - Emit(0x66); Emit(0x31); Emit(0xD2); + Emit(0x66); Emit(0x31); Emit(0xD2); // DIV rm Emit(0x66); EmitREX(BeMCOperand::FromReg(X64Reg_AX), inst->mArg1, false); @@ -14945,7 +14925,7 @@ void BeMCContext::DoCodeEmission() NotImpl(); } - //XOR arg0, arg0 + //XOR arg0, arg0 modInst.mKind = BeMCInstKind_Xor; modInst.mArg1 = modInst.mArg0; EmitStdInst(instForm, &modInst, 0x31, 0x33, 0x81, 0x6, 0x83, 0x6); @@ -14965,14 +14945,14 @@ void BeMCContext::DoCodeEmission() } break; case BeMCInstKind_Or: - { + { if (EmitIntBitwiseXMMInst(instForm, inst, 0xEB)) //POR break; EmitStdInst(instForm, inst, 0x09, 0x0B, 0x81, 0x1, 0x83, 0x1); } break; case BeMCInstKind_Xor: - { + { if (EmitIntBitwiseXMMInst(instForm, inst, 0xEF)) //PXOR break; if (EmitPackedXMMInst(instForm, inst, 0x57)) @@ -15018,16 +14998,16 @@ void BeMCContext::DoCodeEmission() case BeMCInstKind_Shl: Emit(0xF1); // PSLLW break; - case BeMCInstKind_Shr: + case BeMCInstKind_Shr: Emit(0xD1); // PSRLW break; - case BeMCInstKind_Sar: + case BeMCInstKind_Sar: Emit(0xE1); // PSRAW break; } EmitModRM(arg0, arg1); - } + } break; } @@ -15043,7 +15023,7 @@ void BeMCContext::DoCodeEmission() case BeMCInstKind_Sar: rx = 7; break; - } + } bool handled = false; switch (instForm) @@ -15143,7 +15123,7 @@ void BeMCContext::DoCodeEmission() BeMCJump jump; jump.mCodeOffset = funcCodePos; jump.mLabelIdx = inst->mArg0.mLabelIdx; - // Speculatively make it a short jump + // Speculatively make it a short jump jump.mJumpKind = 0; jump.mCmpKind = BeCmpKind_None; deferredJumps.push_back(jump); @@ -15210,7 +15190,6 @@ void BeMCContext::DoCodeEmission() } break; } - } //mOut.Write((uint8)0xC3); break; @@ -15278,7 +15257,7 @@ void BeMCContext::DoCodeEmission() if ((jump.mJumpKind == 0) && ((offset < -0x80) || (offset > 0x7F))) { - // Extend this guy into a rel32 + // Extend this guy into a rel32 int adjustFrom = jump.mCodeOffset + 2; int adjustBytes = 3; if (jump.mCmpKind != BeCmpKind_None) @@ -15296,7 +15275,6 @@ void BeMCContext::DoCodeEmission() codeVec[jump.mCodeOffset + 1 + textSectStartPos] = GetJumpOpCode(jump.mCmpKind, true); } - #define CODE_OFFSET_ADJUST(val) if (val >= adjustFrom) val += adjustBytes for (auto& labelPosition : labelPositions) CODE_OFFSET_ADJUST(labelPosition); @@ -15336,7 +15314,7 @@ void BeMCContext::DoCodeEmission() didWidening = true; } - //TODO: Test extending into a long jump + //TODO: Test extending into a long jump if (jump.mJumpKind == 0) codeVec[jump.mCodeOffset + 1 + textSectStartPos] = (uint8)offset; @@ -15495,7 +15473,7 @@ void BeMCContext::DoCodeEmission() mCOFFObject->mPDataSect.mRelocs.push_back(reloc); mCOFFObject->mPDataSect.mData.Write((int32)codeLen); - // XDATA pos + // XDATA pos reloc.mKind = BeMCRelocationKind_ADDR32NB; reloc.mOffset = mCOFFObject->mPDataSect.mData.GetPos(); reloc.mSymTableIdx = mCOFFObject->mXDataSect.mSymbolIdx; @@ -15585,7 +15563,7 @@ void BeMCContext::HandleParams() int regIdxOfs = 0; int paramOfs = 0; auto retType = mBeFunction->GetFuncType()->mReturnType; - + X64CPURegister compositeRetReg = X64Reg_None; bool flipFirstRegs = false; if (mBeFunction->HasStructRet()) @@ -15726,7 +15704,7 @@ void BeMCContext::HandleParams() paramVRegInfo->mFrameOffset = paramIdx * 8 + 8; CreateDefineVReg(paramVReg); } - //paramVRegInfo->mDbgVariable = mDbgFunction->mParams[paramIdx]; + //paramVRegInfo->mDbgVariable = mDbgFunction->mParams[paramIdx]; mValueToOperand[beArg] = paramVReg; } @@ -16139,7 +16117,7 @@ void BeMCContext::Generate(BeFunction* function) mDbgPreferredRegs[32] = X64Reg_R8;*/ //mDbgPreferredRegs[8] = X64Reg_RAX; - //mDebugging = (function->mName == "?Main@TestProgram@BeefTest@bf@@CAXXZ"); + //mDebugging = (function->mName == "?stbi__gif_load_next@6$StbImage@StbImageBeef@bf@@SAPEAEPEAVstbi__context@123@PEAVstbi__gif@123@PEAHHPEAE@Z"); // || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ"); // || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // ; @@ -16220,7 +16198,7 @@ void BeMCContext::Generate(BeFunction* function) mHasVAStart = true; break; } - } + } } break; case BeMemSetInst::TypeId: @@ -16471,7 +16449,7 @@ void BeMCContext::Generate(BeFunction* function) doSignExtension = true; if (mcValue.IsImmediate()) - doSignExtension = false; + doSignExtension = false; if (doSignExtension) { @@ -16505,21 +16483,21 @@ void BeMCContext::Generate(BeFunction* function) // { // BeMCPhi* origPhi = mcValue.mPhi; // BeMCPhi* newPhi = mPhiAlloc.Alloc(); - // + // // *newPhi = *origPhi; // BF_SWAP(newPhi->mBrTrue, newPhi->mBrFalse); // result.mKind = BeMCOperandKind_Phi; // result.mPhi = newPhi; // break; // } - // + // // if (mcValue.mKind == BeMCOperandKind_CmpResult) // { // auto origCmpResult = mCmpResults[mcValue.mCmpResultIdx]; - // + // // auto cmpResultIdx = (int)mCmpResults.size(); // BeCmpResult cmpResult; - // cmpResult.mCmpKind = BeModule::InvertCmp(origCmpResult.mCmpKind); + // cmpResult.mCmpKind = BeModule::InvertCmp(origCmpResult.mCmpKind); // mCmpResults.push_back(cmpResult); // result.mKind = BeMCOperandKind_CmpResult; // result.mCmpResultIdx = cmpResultIdx; @@ -16600,9 +16578,9 @@ void BeMCContext::Generate(BeFunction* function) switch (castedInst->mOpKind) { - case BeBinaryOpKind_Add: result = AllocBinaryOp(BeMCInstKind_Add, mcLHS, mcRHS, BeMCBinIdentityKind_Any_IsZero, - ((castedInst->mOverflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? BeMCOverflowCheckKind_O : - ((castedInst->mOverflowCheckKind & BfOverflowCheckKind_Unsigned) != 0) ? BeMCOverflowCheckKind_B : BeMCOverflowCheckKind_None); + case BeBinaryOpKind_Add: result = AllocBinaryOp(BeMCInstKind_Add, mcLHS, mcRHS, BeMCBinIdentityKind_Any_IsZero, + ((castedInst->mOverflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? BeMCOverflowCheckKind_O : + ((castedInst->mOverflowCheckKind & BfOverflowCheckKind_Unsigned) != 0) ? BeMCOverflowCheckKind_B : BeMCOverflowCheckKind_None); break; case BeBinaryOpKind_Subtract: result = AllocBinaryOp(BeMCInstKind_Sub, mcLHS, mcRHS, BeMCBinIdentityKind_Right_IsZero, ((castedInst->mOverflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? BeMCOverflowCheckKind_O : @@ -16691,7 +16669,7 @@ void BeMCContext::Generate(BeFunction* function) auto cmpResultIdx = (int)mCmpResults.size(); BeCmpResult cmpResult; - cmpResult.mCmpKind = castedInst->mCmpKind; + cmpResult.mCmpKind = castedInst->mCmpKind; if (valType->IsFloat()) { @@ -16923,7 +16901,7 @@ void BeMCContext::Generate(BeFunction* function) ptrValue = AllocVirtualReg(intType); auto vregInfo = mVRegInfo[ptrValue.mVRegIdx]; vregInfo->mIsExpr = true; - vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP); + vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP); vregInfo->mRelOffset.mKind = BeMCOperandKind::BeMCOperandKind_Immediate_HomeSize; CreateDefineVReg(ptrValue); } @@ -16998,6 +16976,16 @@ void BeMCContext::Generate(BeFunction* function) } } break; + case BeLifetimeSoftEndInst::TypeId: + { + auto castedInst = (BeLifetimeSoftEndInst*)inst; + auto mcPtr = GetOperand(castedInst->mPtr, false, true, true); + if (mcPtr.IsVRegAny()) + { + AllocInst(BeMCInstKind_LifetimeSoftEnd, mcPtr); + } + } + break; case BeValueScopeStartInst::TypeId: { result = BeMCOperand::FromImmediate((int)mVRegInfo.size()); @@ -17151,7 +17139,6 @@ void BeMCContext::Generate(BeFunction* function) CreateDefineVReg(result); //TODO: Always correct? result.mKind = BeMCOperandKind_VReg; - } else SoftFail("Invalid GEP", inst->mDbgLoc); @@ -17235,6 +17222,7 @@ void BeMCContext::Generate(BeFunction* function) { mcInst->mArg1.mKind = BeMCOperandKind_Immediate_i8; mcInst->mArg1.mImmediate = 2; + mcBlock->mHasFakeBr = true; } } break; @@ -17292,11 +17280,10 @@ void BeMCContext::Generate(BeFunction* function) } }*/ - result.mKind = BeMCOperandKind_Phi; result.mPhi = mcPhi; - // DefPhi is important because when we convert a CondBr of a PHI, because we will need to create jumps to the correct + // DefPhi is important because when we convert a CondBr of a PHI, because we will need to create jumps to the correct // location when we create it as a value (specifically in the bool case) AllocInst(BeMCInstKind_DefPhi, result); } @@ -17342,7 +17329,7 @@ void BeMCContext::Generate(BeFunction* function) BF_ASSERT(retVal.IsVReg()); auto vregInfo = GetVRegInfo(retVal); - vregInfo->SetRetVal(); + vregInfo->SetRetVal(); } else if (retType->IsVector()) { @@ -17421,7 +17408,7 @@ void BeMCContext::Generate(BeFunction* function) { auto mcLHS = TryToVector(castedInst->mArgs[0].mValue); BeMCOperand mcRHS; - + if ((intrin->mKind == BfIRIntrinsic_SAR) || (intrin->mKind == BfIRIntrinsic_SHL) || (intrin->mKind == BfIRIntrinsic_SHR)) @@ -17470,12 +17457,12 @@ void BeMCContext::Generate(BeFunction* function) break; // case BfIRIntrinsic_Cast: // { -// +// // } // break; case BfIRIntrinsic_Not: { - auto mcLHS = TryToVector(castedInst->mArgs[0].mValue); + auto mcLHS = TryToVector(castedInst->mArgs[0].mValue); BeMCOperand mcRHS = BeMCOperand::FromImmediate(-1); result = AllocBinaryOp(BeMCInstKind_Xor, mcLHS, mcRHS, BeMCBinIdentityKind_None); break; } @@ -17832,7 +17819,7 @@ void BeMCContext::Generate(BeFunction* function) { auto valPtr = GetOperand(castedInst->mArgs[0].mValue); auto idx = GetOperand(castedInst->mArgs[1].mValue); - + auto valType = GetType(valPtr); if (!valType->IsPointer()) { @@ -17848,13 +17835,13 @@ void BeMCContext::Generate(BeFunction* function) } auto vectorType = (BeVectorType*)valType; - + auto elementPtrType = mModule->mContext->GetPointerTo(vectorType->mElementType); result = AllocVirtualReg(elementPtrType); CreateDefineVReg(result); auto vregInfo = GetVRegInfo(result); - vregInfo->mRelTo = valPtr; + vregInfo->mRelTo = valPtr; vregInfo->mRelOffset = idx; vregInfo->mRelOffsetScale = vectorType->mElementType->mSize; vregInfo->mIsExpr = true; @@ -17924,13 +17911,13 @@ void BeMCContext::Generate(BeFunction* function) auto mcType = GetOperand(castedInst->mArgs[2].mValue); BeType* beType = mModule->mBeIRCodeGen->GetBeTypeById((int32)mcType.mImmediate); - + auto mcList = AllocVirtualReg(mModule->mContext->GetPointerTo(mModule->mContext->GetPrimitiveType(BeTypeCode_NullPtr))); CreateDefineVReg(mcList); auto listVRegInfo = GetVRegInfo(mcList); listVRegInfo->mRelTo = mcListPtr; listVRegInfo->mIsExpr = true; - + auto mcSrc = AllocVirtualReg(mModule->mContext->GetPointerTo(beType)); CreateDefineVReg(mcSrc); auto srcVRegInfo = GetVRegInfo(mcSrc); @@ -17969,7 +17956,7 @@ void BeMCContext::Generate(BeFunction* function) CreateDefineVReg(vaStartVal); AllocInst(BeMCInstKind_Mov, BeMCOperand::ToLoad(destVal), BeMCOperand::FromVRegAddr(vaStartVal.mVRegIdx)); - } + } break; default: SoftFail(StrFormat("Intrinsic not handled: '%s'", intrin->mName.c_str()), castedInst->mDbgLoc); @@ -18076,9 +18063,9 @@ void BeMCContext::Generate(BeFunction* function) isFirstBlock = false; } mCurDbgLoc = NULL; - - BEMC_ASSERT(valueScopeStack.size() == 0); - BEMC_ASSERT(retCount == 1); + + BEMC_ASSERT(valueScopeStack.size() == 0); + BEMC_ASSERT(retCount == 1); bool wantDebug = mDebugging; //wantDebug |= function->mName == "?__BfCtor@SpriteBatchRenderer@Repo@bf@@QEAAXTint@@@Z"; @@ -18222,4 +18209,4 @@ void BeMCContext::Generate(BeFunction* function) } DoCodeEmission(); -} +} \ No newline at end of file diff --git a/IDEHelper/Backend/BeMCContext.h b/IDEHelper/Backend/BeMCContext.h index ecaa4692..3f22e05b 100644 --- a/IDEHelper/Backend/BeMCContext.h +++ b/IDEHelper/Backend/BeMCContext.h @@ -14,7 +14,6 @@ NS_BF_BEGIN class BeMCAddInst { public: - }; struct BeVTrackingBits @@ -109,9 +108,7 @@ public: DiffIterator& operator++() { - } - };*/ Iterator begin() @@ -198,7 +195,7 @@ enum BeMCOperandKind BeMCOperandKind_Immediate_f64, BeMCOperandKind_Immediate_f32_Packed128, BeMCOperandKind_Immediate_f64_Packed128, - BeMCOperandKind_Immediate_int32x4, + BeMCOperandKind_Immediate_int32x4, BeMCOperandKind_ConstAgg, BeMCOperandKind_Block, BeMCOperandKind_Label, @@ -484,11 +481,10 @@ enum BeMCInstKind BeMCInstKind_DefLoad, BeMCInstKind_DefPhi, BeMCInstKind_DbgDecl, - BeMCInstKind_DbgRangeStart, - BeMCInstKind_DbgRangeEnd, // Extends life of local variables/arguments to their lexical scope end BeMCInstKind_LifetimeExtend, BeMCInstKind_LifetimeStart, BeMCInstKind_LifetimeEnd, + BeMCInstKind_LifetimeSoftEnd, BeMCInstKind_ValueScopeSoftEnd, BeMCInstKind_ValueScopeHardEnd, BeMCInstKind_Label, @@ -661,6 +657,7 @@ public: int mBlockIdx; int mMaxDeclBlockId; // If blocks merge, this is the highest index bool mIsLooped; + bool mHasFakeBr; BeVTrackingList* mSuccLiveness; BeVTrackingList* mSuccVRegsInitialized; BeVTrackingList* mPredVRegsInitialized; @@ -673,6 +670,7 @@ public: { mLabelIdx = -1; mIsLooped = false; + mHasFakeBr = false; mBlockIdx = -1; mMaxDeclBlockId = -1; mSuccLiveness = NULL; @@ -768,14 +766,14 @@ class BeMCVRegInfo { public: X64CPURegister mReg; - X64CPURegister mNaturalReg; // From param + X64CPURegister mNaturalReg; // From param BeType* mType; int mAlign; int mFrameOffset; // 0 = 'RBP' (probably first local var or saved RBP), 8 means retAddr bool mRegNumPinned; bool mHasDynLife; bool mDoConservativeLife; // Keep alive through 'init' as well as 'uninit' - bool mIsExpr; // Not an actual value, something like 'mRelTo + mRelOffset' + bool mIsExpr; // Not an actual value, something like 'mRelTo + mRelOffset' bool mWantsExprActualize; bool mWantsExprOffsetActualize; bool mChainLifetimeEnd; // Kill relTo's when we are killed @@ -793,7 +791,7 @@ public: bool mDisableR13; // Special case when this vreg is used in an ModRM scale, which isn't allowed bool mDisableRAX; // Special case when RAX must be preserved (ie: For IDIV) bool mDisableRDX; // Special case when RDX must be preserved (ie: For IDIV) - bool mDisableEx; // Disable any registers that require a REX + bool mDisableEx; // Disable any registers that require a REX int mVRegAffinity; // Try to match the mReg of this vreg BeMCOperand mRelTo; int mRelOffsetScale; @@ -803,7 +801,7 @@ public: bool mFoundLastUse; bool mMustExist; // Regs we must be able to debug - // Must be refreshed with RefreshRefCounts + // Must be refreshed with RefreshRefCounts int mRefCount; int mAssignCount; @@ -960,7 +958,6 @@ enum BeTrackKind BeTrackKind_COUNT = 2 }; - // BeVTrackingEntry is immutable -- the Set/Clear/Merge methods allocate new entries if // the requested change produces a new liveness set class BeVTrackingContext @@ -1475,7 +1472,7 @@ public: void EmitStdInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode_rm_r, uint8 opcode_r_rm, uint8 opcode_rm_imm, uint8 opcode_rm_imm_rx, uint8 opcode_rm_imm8, uint8 opcode_rm_imm8_rx); bool EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode); bool EmitStdXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode, uint8 opcode_dest_frm); - bool EmitPackedXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode); + bool EmitPackedXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode); bool EmitIntXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode); bool EmitIntBitwiseXMMInst(BeMCInstForm instForm, BeMCInst* inst, uint8 opcode); void EmitAggMov(const BeMCOperand& dest, const BeMCOperand& src); diff --git a/IDEHelper/Backend/BeModule.cpp b/IDEHelper/Backend/BeModule.cpp index c396624f..71f7109a 100644 --- a/IDEHelper/Backend/BeModule.cpp +++ b/IDEHelper/Backend/BeModule.cpp @@ -64,16 +64,16 @@ BeValue* BeInliner::Remap(BeValue* srcValue) return itr->second;*/ if (mValueMap.TryGetValue(srcValue, &valuePtr)) return *valuePtr; - - BeMDNode* wrapMDNode = NULL; + + BeMDNode* wrapMDNode = NULL; if (auto dbgFunction = BeValueDynCast(srcValue)) - { - wrapMDNode = dbgFunction; + { + wrapMDNode = dbgFunction; } if (auto dbgLexBlock = BeValueDynCast(srcValue)) { - wrapMDNode = dbgLexBlock; + wrapMDNode = dbgLexBlock; } if (auto callInst = BeValueDynCast(srcValue)) @@ -83,9 +83,9 @@ BeValue* BeInliner::Remap(BeValue* srcValue) } if (wrapMDNode != NULL) - { + { auto destMDNode = mOwnedValueVec->Alloc(); - destMDNode->mScope = wrapMDNode; + destMDNode->mScope = wrapMDNode; mValueMap[srcValue] = destMDNode; return destMDNode; } @@ -107,13 +107,13 @@ BeDbgLoc* BeInliner::ExtendInlineDbgLoc(BeDbgLoc* srcInlineAt) BeDbgLoc** dbgLocPtr = NULL; if (mInlinedAtMap.TryGetValue(srcInlineAt, &dbgLocPtr)) return *dbgLocPtr; - + auto dbgLoc = mModule->mAlloc.Alloc(); dbgLoc->mLine = srcInlineAt->mLine; dbgLoc->mColumn = srcInlineAt->mColumn; dbgLoc->mDbgScope = (BeMDNode*)Remap(srcInlineAt->mDbgScope); dbgLoc->mIdx = mModule->mCurDbgLocIdx++; - dbgLoc->mDbgInlinedAt = ExtendInlineDbgLoc(srcInlineAt->mDbgInlinedAt); + dbgLoc->mDbgInlinedAt = ExtendInlineDbgLoc(srcInlineAt->mDbgInlinedAt); mInlinedAtMap[srcInlineAt] = dbgLoc; return dbgLoc; @@ -130,7 +130,7 @@ void BeInliner::AddInst(BeInst* destInst, BeInst* srcInst) } else { - BeDbgLoc* inlinedAt = ExtendInlineDbgLoc(mSrcDbgLoc->mDbgInlinedAt); + BeDbgLoc* inlinedAt = ExtendInlineDbgLoc(mSrcDbgLoc->mDbgInlinedAt); mModule->SetCurrentDebugLocation(mSrcDbgLoc->mLine, mSrcDbgLoc->mColumn, (BeMDNode*)Remap(mSrcDbgLoc->mDbgScope), inlinedAt); mDestDbgLoc = mModule->mCurDbgLoc; } @@ -138,7 +138,7 @@ void BeInliner::AddInst(BeInst* destInst, BeInst* srcInst) if (srcInst != NULL) destInst->mName = srcInst->mName; - + destInst->mDbgLoc = mDestDbgLoc; destInst->mParentBlock = mDestBlock; mDestBlock->mInstructions.push_back(destInst); @@ -156,7 +156,6 @@ void BeInliner::Visit(BeBlock* beBlock) void BeInliner::Visit(BeArgument* beArgument) { - } void BeInliner::Visit(BeInst* beInst) @@ -166,7 +165,7 @@ void BeInliner::Visit(BeInst* beInst) void BeInliner::Visit(BeNopInst* nopInst) { - auto destNopInst = AllocInst(nopInst); + auto destNopInst = AllocInst(nopInst); } void BeInliner::Visit(BeUnreachableInst* unreachableInst) @@ -188,7 +187,7 @@ void BeInliner::Visit(BeUndefValueInst* undefValue) void BeInliner::Visit(BeExtractValueInst* extractValue) { auto destExtractValue = AllocInst(extractValue); - destExtractValue->mAggVal = Remap(extractValue->mAggVal); + destExtractValue->mAggVal = Remap(extractValue->mAggVal); destExtractValue->mIdx = extractValue->mIdx; } @@ -233,7 +232,7 @@ void BeInliner::Visit(BeBinaryOpInst* binaryOpInst) auto destBinaryOp = AllocInst(binaryOpInst); destBinaryOp->mOpKind = binaryOpInst->mOpKind; destBinaryOp->mLHS = Remap(binaryOpInst->mLHS); - destBinaryOp->mRHS = Remap(binaryOpInst->mRHS); + destBinaryOp->mRHS = Remap(binaryOpInst->mRHS); } void BeInliner::Visit(BeCmpInst* cmpInst) @@ -285,26 +284,32 @@ void BeInliner::Visit(BeAliasValueInst* aliasValueInst) void BeInliner::Visit(BeLifetimeExtendInst* lifetimeExtendInst) { auto destlifetimeExtendInst = AllocInst(lifetimeExtendInst); - destlifetimeExtendInst->mPtr = Remap(lifetimeExtendInst->mPtr); + destlifetimeExtendInst->mPtr = Remap(lifetimeExtendInst->mPtr); } void BeInliner::Visit(BeLifetimeStartInst* lifetimeStartInst) { auto destlifetimeStartInst = AllocInst(lifetimeStartInst); - destlifetimeStartInst->mPtr = Remap(lifetimeStartInst->mPtr); + destlifetimeStartInst->mPtr = Remap(lifetimeStartInst->mPtr); } void BeInliner::Visit(BeLifetimeEndInst* lifetimeEndInst) { auto destlifetimeEndInst = AllocInst(lifetimeEndInst); - destlifetimeEndInst->mPtr = Remap(lifetimeEndInst->mPtr); + destlifetimeEndInst->mPtr = Remap(lifetimeEndInst->mPtr); +} + +void BeInliner::Visit(BeLifetimeSoftEndInst* lifetimeEndInst) +{ + auto destlifetimeEndInst = AllocInst(lifetimeEndInst); + destlifetimeEndInst->mPtr = Remap(lifetimeEndInst->mPtr); } void BeInliner::Visit(BeLifetimeFenceInst* lifetimeFenceInst) { auto destlifetimeFenceInst = AllocInst(lifetimeFenceInst); destlifetimeFenceInst->mFenceBlock = (BeBlock*)Remap(lifetimeFenceInst->mFenceBlock); - destlifetimeFenceInst->mPtr = Remap(lifetimeFenceInst->mPtr); + destlifetimeFenceInst->mPtr = Remap(lifetimeFenceInst->mPtr); } void BeInliner::Visit(BeValueScopeStartInst* valueScopeStartInst) @@ -328,14 +333,14 @@ void BeInliner::Visit(BeValueScopeEndInst* valueScopeEndInst) void BeInliner::Visit(BeLoadInst* loadInst) { auto destLoadInst = AllocInst(loadInst); - destLoadInst->mTarget = Remap(loadInst->mTarget); + destLoadInst->mTarget = Remap(loadInst->mTarget); } void BeInliner::Visit(BeStoreInst* storeInst) { auto destStoreInst = AllocInst(storeInst); destStoreInst->mPtr = Remap(storeInst->mPtr); - destStoreInst->mVal = Remap(storeInst->mVal); + destStoreInst->mVal = Remap(storeInst->mVal); } void BeInliner::Visit(BeSetCanMergeInst* setCanMergeInst) @@ -374,26 +379,24 @@ void BeInliner::Visit(BeCondBrInst* condBrInst) auto destCondBrInst = AllocInst(condBrInst); destCondBrInst->mCond = Remap(condBrInst->mCond); destCondBrInst->mTrueBlock = (BeBlock*)Remap(condBrInst->mTrueBlock); - destCondBrInst->mFalseBlock = (BeBlock*)Remap(condBrInst->mFalseBlock); + destCondBrInst->mFalseBlock = (BeBlock*)Remap(condBrInst->mFalseBlock); } void BeInliner::Visit(BePhiIncoming* phiIncomingInst) { - } void BeInliner::Visit(BePhiInst* phiInst) -{ +{ auto destPhiInst = AllocInst(phiInst); for (auto incoming : phiInst->mIncoming) { auto destPhiIncoming = mAlloc->Alloc(); - destPhiIncoming->mValue = Remap(incoming->mValue); + destPhiIncoming->mValue = Remap(incoming->mValue); destPhiIncoming->mBlock = (BeBlock*)Remap(incoming->mBlock); destPhiInst->mIncoming.push_back(destPhiIncoming); } - destPhiInst->mType = phiInst->mType; } @@ -428,7 +431,7 @@ void BeInliner::Visit(BeCallInst* callInst) destCallInst->mArgs.push_back(copiedArg); } destCallInst->mNoReturn = callInst->mNoReturn; - destCallInst->mTailCall = callInst->mTailCall; + destCallInst->mTailCall = callInst->mTailCall; } void BeInliner::Visit(BeDbgDeclareInst* dbgDeclareInst) @@ -462,7 +465,7 @@ void BeConstant::GetData(BeConstData& data) data.mData.Insert(data.mData.mSize, (uint8*)&f, sizeof(float)); } else - { + { data.mData.Insert(data.mData.mSize, &mUInt8, type->mSize); } } @@ -472,7 +475,7 @@ void BeConstant::HashContent(BeHashContext& hashCtx) hashCtx.Mixin(TypeId); mType->HashReference(hashCtx); if (mType->mTypeCode < BeTypeCode_Struct) - { + { hashCtx.Mixin(mUInt64); } else if (mType->IsPointer()) @@ -504,7 +507,7 @@ BeType* BeGEP1Constant::GetType() } BeType* BeGEP2Constant::GetType() -{ +{ BePointerType* ptrType = (BePointerType*)mTarget->GetType(); BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer); if (ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray) @@ -533,7 +536,7 @@ BeType* BeGEP2Constant::GetType() BeType* BeExtractValueConstant::GetType() { - BeType* type = mTarget->GetType(); + BeType* type = mTarget->GetType(); if (type->mTypeCode == BeTypeCode_SizedArray) { BeSizedArrayType* arrayType = (BeSizedArrayType*)type; @@ -652,10 +655,10 @@ BeModule* BeInst::GetModule() } void BeInst::SetName(const StringImpl& name) -{ +{ char* nameStr = (char*)GetModule()->mAlloc.AllocBytes((int)name.length() + 1); strcpy(nameStr, name.c_str()); - mName = nameStr; + mName = nameStr; } BeType* BeLoadInst::GetType() @@ -686,7 +689,7 @@ BeType* BeExtractValueInst::GetType() } BF_ASSERT(aggType->mTypeCode == BeTypeCode_Struct); BeStructType* structType = (BeStructType*)aggType; - return structType->mMembers[mIdx].mType; + return structType->mMembers[mIdx].mType; } BeType* BeInsertValueInst::GetType() @@ -711,10 +714,9 @@ BeType * BeValueScopeStartInst::GetType() return context->GetPrimitiveType(BeTypeCode_Int32); } - BeType* BeGEPInst::GetType() { - if (mIdx1 == NULL) + if (mIdx1 == NULL) return mPtr->GetType(); BePointerType* ptrType = (BePointerType*)mPtr->GetType(); @@ -757,8 +759,8 @@ BeType* BeCallInst::GetType() auto type = mFunc->GetType(); if (type == NULL) { - if (auto intrin = BeValueDynCast(mFunc)) - return intrin->mReturnType; + if (auto intrin = BeValueDynCast(mFunc)) + return intrin->mReturnType; return type; } while (type->mTypeCode == BeTypeCode_Pointer) @@ -865,7 +867,7 @@ BeDbgFile* BeDbgLoc::GetDbgFile() } else if (auto dbgFunc = BeValueDynCast(checkScope)) { - return dbgFunc->mFile; + return dbgFunc->mFile; } else if (auto dbgLexBlock = BeValueDynCast(checkScope)) { @@ -888,9 +890,9 @@ BeDbgLoc* BeDbgLoc::GetInlinedAt(int idx) } BeDbgLoc* BeDbgLoc::GetRoot() -{ +{ auto checkDbgLoc = this; - while (checkDbgLoc->mDbgInlinedAt != NULL) + while (checkDbgLoc->mDbgInlinedAt != NULL) checkDbgLoc = checkDbgLoc->mDbgInlinedAt; return checkDbgLoc; } @@ -1021,7 +1023,7 @@ void BeDbgEnumType::SetMembers(SizedArrayImpl& members) if (auto enumMember = BeValueDynCast(member)) { mMembers.push_back(enumMember); - } + } else BF_FATAL("bad"); } @@ -1047,7 +1049,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgType = BeValueDynCast(mdNode)) - { + { str += StrFormat("DbgTypeId: %d", dbgType->mTypeId); return; } @@ -1075,7 +1077,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgFunc = BeValueDynCast(mdNode)) - { + { if (auto parentType = BeValueDynCast(dbgFunc->mScope)) { ToString(str, dbgFunc->mScope); @@ -1089,7 +1091,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo str += dbgFunc->mName; if (mdDrillDown) - { + { str += ":"; ToString(str, dbgFunc->mFile, true, true); } @@ -1106,9 +1108,9 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo ToString(str, lexBlock->mScope); return; } - + if (auto dbgType = BeValueDynCast(mdNode)) - { + { if (dbgType->mEncoding == llvm::dwarf::DW_ATE_address) { if (dbgType->mSize == 0) @@ -1181,7 +1183,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgType = BeValueDynCast(mdNode)) - { + { if ((BeValueDynCast(dbgType->mScope) != NULL) || (BeValueDynCast(dbgType->mScope) != NULL)) { @@ -1196,7 +1198,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgType = BeValueDynCast(mdNode)) - { + { if ((BeValueDynCast(dbgType->mScope) != NULL) || (BeValueDynCast(dbgType->mScope) != NULL)) { @@ -1211,7 +1213,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgType = BeValueDynCast(mdNode)) - { + { if ((BeValueDynCast(dbgType->mScope) != NULL) || (BeValueDynCast(dbgType->mScope) != NULL)) { @@ -1226,7 +1228,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgType = BeValueDynCast(mdNode)) - { + { ToString(str, dbgType->mElement); str += "["; str += StrFormat("%d", dbgType->mNumElements); @@ -1256,7 +1258,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto dbgMember = BeValueDynCast(mdNode)) - { + { if (dbgMember->mIsStatic) str += "static "; ToString(str, dbgMember->mType); @@ -1267,14 +1269,14 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo str += " offset:"; str += StrFormat("%d", dbgMember->mOffset); } - + if (dbgMember->mStaticValue != NULL) str += " " + ToString(dbgMember->mStaticValue); return; } if (auto dbgMember = BeValueDynCast(mdNode)) - { + { str += dbgMember->mName; str += " "; str += StrFormat("%lld", dbgMember->mValue); @@ -1302,13 +1304,13 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constantGEP = BeValueDynCast(value)) - { + { str += "ConstGEP2 "; ToString(str, constantGEP->mTarget); str += StrFormat(" %d %d", constantGEP->mIdx0, constantGEP->mIdx1); return; } - + if (auto constantExtract = BeValueDynCast(value)) { str += "ConstExtract "; @@ -1333,10 +1335,10 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo str += "%"; str += param.mName; } - + return; } - + if (auto func = BeValueDynCast(value)) { str += func->mName; @@ -1344,7 +1346,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constant = BeValueDynCast(value)) - { + { if (showType) { BeModule::ToString(str, constant->mType); @@ -1355,7 +1357,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo switch (constant->mType->mTypeCode) { - case BeTypeCode_Struct: + case BeTypeCode_Struct: case BeTypeCode_SizedArray: case BeTypeCode_Vector: for (int valIdx = 0; valIdx < (int)constant->mMemberValues.size(); valIdx++) @@ -1363,7 +1365,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo if (valIdx > 0) str += ", "; ToString(str, constant->mMemberValues[valIdx], false); - } + } break; default: BF_FATAL("NotImpl"); @@ -1386,7 +1388,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constant = BeValueDynCast(value)) - { + { ToString(str, constant->mType); str += " cast "; ToString(str, constant->mTarget); @@ -1403,7 +1405,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constant = BeValueDynCast(value)) - { + { ToString(str, constant->GetType()); str += " gep ("; ToString(str, constant->mTarget); @@ -1421,7 +1423,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constant = BeValueDynCast(value)) - { + { ToString(str, constant->GetType()); str += " ("; for (int i = 0; i < constant->mMemberValues.size(); i++) @@ -1435,7 +1437,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo } if (auto constant = BeValueDynCast(value)) - { + { ToString(str, constant->GetType()); str += " \""; str += SlashString(constant->mString, true, true); @@ -1483,7 +1485,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo case BeTypeCode_Struct: case BeTypeCode_SizedArray: case BeTypeCode_Vector: - str += "zeroinitializer"; + str += "zeroinitializer"; return; case BeTypeCode_Function: BF_FATAL("Notimpl"); @@ -1509,10 +1511,9 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo ToString(str, callInst->mInlineResult); return; } - } + } - - BeType* resultType = NULL; + BeType* resultType = NULL; const char* wantNamePtr = NULL; if (auto instVal = BeValueDynCast(value)) { @@ -1520,7 +1521,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo if ((instVal->mName != NULL) && (instVal->mName[0] != 0)) wantNamePtr = instVal->mName; } - + String* valueNamePtr = NULL; if (mValueNameMap.TryGetValue(value, &valueNamePtr)) { @@ -1534,16 +1535,16 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo str += *valueNamePtr; return; } - + if (auto beBlock = BeValueDynCast(value)) { if (!beBlock->mName.IsEmpty()) wantNamePtr = beBlock->mName.c_str(); } - + StringT<64> useName; if (wantNamePtr != NULL) - useName += wantNamePtr; + useName += wantNamePtr; while (true) { int* idxPtr = NULL; @@ -1551,13 +1552,13 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo break; int checkIdx = (*idxPtr)++; - + char str[32]; - sprintf(str, "%d", checkIdx); + sprintf(str, "%d", checkIdx); useName += str; } - mValueNameMap[value] = useName; + mValueNameMap[value] = useName; if ((showType) && (resultType != NULL)) { BeModule::ToString(str, resultType); @@ -1593,7 +1594,7 @@ void BeDumpContext::ToString(StringImpl& str, BeType* type) } void BeDumpContext::ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool showScope) -{ +{ if (dbgFunction->mIsStaticMethod) str += "static "; if (dbgFunction->mIsLocalToUnit) @@ -1604,7 +1605,7 @@ void BeDumpContext::ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool s str += StrFormat("virtual(%d) ", dbgFunction->mVIndex); str += ToString(dbgFunction->mType->mReturnType); - str += " "; + str += " "; if ((showScope) && (dbgFunction->mScope != NULL)) { @@ -1626,7 +1627,7 @@ void BeDumpContext::ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool s str += dbgFunction->mName; if (needsQuote) str += "\""; - + if (!dbgFunction->mGenericArgs.IsEmpty()) { str += "<"; @@ -1676,7 +1677,7 @@ void BeDumpContext::ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool s { str += " Link:"; str += dbgFunction->mLinkageName; - } + } } String BeDumpContext::ToString(BeDbgFunction* dbgFunction) @@ -1716,7 +1717,7 @@ void BeDumpContext::ToString(StringImpl& str, BeCmpKind cmpKind) case BeCmpKind_NO: str += "no"; return; default: str += "???"; - } + } } String BeDumpContext::ToString(BeCmpKind cmpKind) @@ -1729,7 +1730,7 @@ String BeDumpContext::ToString(BeCmpKind cmpKind) void BeDumpContext::ToString(StringImpl& str, BeBinaryOpKind opKind) { switch (opKind) - { + { case BeBinaryOpKind_Add: str += "+"; return; case BeBinaryOpKind_Subtract: str += "-"; return; case BeBinaryOpKind_Multiply: str += "*"; return; @@ -1745,7 +1746,7 @@ void BeDumpContext::ToString(StringImpl& str, BeBinaryOpKind opKind) case BeBinaryOpKind_ARightShift: str += "A>>"; return; default: str += "???"; - } + } } String BeDumpContext::ToString(BeBinaryOpKind opKind) @@ -1794,11 +1795,11 @@ BeModule::BeModule(const StringImpl& moduleName, BeContext* context) mCeMachine = NULL; mPrevDbgLocInline = NULL; mCurDbgLocIdx = 0; - mCurLexBlockId = 0; + mCurLexBlockId = 0; } void BeModule::Hash(BeHashContext& hashCtx) -{ +{ hashCtx.MixinStr(mTargetTriple); hashCtx.MixinStr(mTargetCPU); @@ -1807,7 +1808,7 @@ void BeModule::Hash(BeHashContext& hashCtx) configConst->HashContent(hashCtx); if (mDbgModule != NULL) - mDbgModule->HashReference(hashCtx); + mDbgModule->HashReference(hashCtx); if (!mFunctions.IsEmpty()) { @@ -1822,26 +1823,26 @@ void BeModule::Hash(BeHashContext& hashCtx) beFunction->HashReference(hashCtx); } } - + if (!mGlobalVariables.IsEmpty()) { std::sort(mGlobalVariables.begin(), mGlobalVariables.end(), [](BeGlobalVariable* lhs, BeGlobalVariable* rhs) { return (lhs->mName < rhs->mName); }); - + for (auto& beGlobalVar : mGlobalVariables) { if (beGlobalVar->mInitializer != NULL) beGlobalVar->HashReference(hashCtx); } - } + } } #define DELETE_ENTRY(i) delete mOwnedValues[i]; mOwnedValues[i] = NULL BeModule::~BeModule() -{ +{ delete mDbgModule; } @@ -1887,23 +1888,23 @@ String BeModule::ToString(BeFunction* wantFunc) Dictionary dbgLocs; StringT<128*1024> str; - + SetAndRestoreValue prevActiveFunc(mActiveFunction, NULL); BeDumpContext dc; - + if (wantFunc == NULL) { str += "Module: "; str += mModuleName; str += "\n"; str += "Target: "; str += mTargetTriple; str += "\n"; if (mDbgModule != NULL) - { + { str += "FileName: "; str += mDbgModule->mFileName; str += "\n"; str += "Directory: "; str += mDbgModule->mDirectory; str += "\n"; - str += "Producer: "; str += mDbgModule->mProducer; str += "\n"; + str += "Producer: "; str += mDbgModule->mProducer; str += "\n"; } - + for (int i = 0; i < (int)mConfigConsts64.size(); i++) { if (i == 0) @@ -1926,7 +1927,7 @@ String BeModule::ToString(BeFunction* wantFunc) } str += "\n"; - str += "; Global variables\n"; + str += "; Global variables\n"; for (int gvIdx = 0; gvIdx < (int)mGlobalVariables.size(); gvIdx++) { auto gv = mGlobalVariables[gvIdx]; @@ -1971,7 +1972,7 @@ String BeModule::ToString(BeFunction* wantFunc) if (dbgGlobalVar->mIsLocalToUnit) str += "internal "; dc.ToString(str, dbgGlobalVar->mType); - + if (dbgGlobalVar->mValue != NULL) { str += " "; @@ -1991,8 +1992,8 @@ String BeModule::ToString(BeFunction* wantFunc) str += dbgGlobalVar->mLinkageName; } str += "\n"; - } - + } + str += "\n"; } @@ -2001,7 +2002,7 @@ String BeModule::ToString(BeFunction* wantFunc) { if (auto dbgStructType = BeValueDynCast(dbgType)) { - dc.ToString(str, dbgStructType); + dc.ToString(str, dbgStructType); str += " = {"; if (dbgStructType->mSize != -1) { @@ -2035,7 +2036,7 @@ String BeModule::ToString(BeFunction* wantFunc) str += ","; str += "\n "; - dc.ToString(str, dbgStructType->mMethods[methodIdx], false); + dc.ToString(str, dbgStructType->mMethods[methodIdx], false); } str += "}"; } @@ -2050,11 +2051,11 @@ String BeModule::ToString(BeFunction* wantFunc) str += "\n Size: "; str += StrFormat("%d", dbgEnumType->mSize); str += "\n Align : "; - str += StrFormat("%d", dbgEnumType->mAlign); + str += StrFormat("%d", dbgEnumType->mAlign); } if (dbgEnumType->mElementType != NULL) { - str += "\n Underlying: "; + str += "\n Underlying: "; dc.ToString(str, dbgEnumType->mElementType); } if (!dbgEnumType->mMembers.IsEmpty()) @@ -2096,7 +2097,7 @@ String BeModule::ToString(BeFunction* wantFunc) continue; mActiveFunction = func; - + Dictionary valueNameMap; HashSet seenNames; @@ -2110,13 +2111,13 @@ String BeModule::ToString(BeFunction* wantFunc) str += func->mName; str += "("; for (int paramIdx = 0; paramIdx < (int)funcType->mParams.size(); paramIdx++) - { + { auto& typeParam = funcType->mParams[paramIdx]; auto& param = func->mParams[paramIdx]; if (paramIdx > 0) str += ", "; ToString(str, typeParam.mType); - + if (param.mStructRet) str += " sret"; if (param.mNoAlias) @@ -2252,7 +2253,7 @@ String BeModule::ToString(BeFunction* wantFunc) str += ":\n"; for (auto inst : beBlock->mInstructions) - { + { if (inst->mDbgLoc != NULL) { if ((inst->mDbgLoc != lastDbgLoc) && (lastDbgLoc != NULL)) @@ -2263,7 +2264,7 @@ String BeModule::ToString(BeFunction* wantFunc) // } if ((inst->mDbgLoc->mDbgInlinedAt != lastDbgLoc->mDbgInlinedAt) && (inst->mDbgLoc->mDbgInlinedAt != NULL)) - { + { prevDbgLocs.Clear(); auto prevInlinedAt = lastDbgLoc->mDbgInlinedAt; while (prevInlinedAt != NULL) @@ -2287,7 +2288,7 @@ String BeModule::ToString(BeFunction* wantFunc) str += " "; if (inst->CanBeReferenced()) - { + { str += dc.ToString(inst, false); str += " = "; } @@ -2325,7 +2326,7 @@ String BeModule::ToString(BeFunction* wantFunc) str += dc.ToString(castedInst->mRHS, false); } break;*/ - DISPLAY_INST3(BeCmpInst, "cmp", mCmpKind, mLHS, mRHS); + DISPLAY_INST3(BeCmpInst, "cmp", mCmpKind, mLHS, mRHS); DISPLAY_INST1(BeObjectAccessCheckInst, "objectAccessCheck", mValue); case BeAllocaInst::TypeId: { @@ -2342,8 +2343,9 @@ String BeModule::ToString(BeFunction* wantFunc) } break; DISPLAY_INST1(BeAliasValueInst, "aliasvalue", mPtr); - DISPLAY_INST1(BeLifetimeStartInst, "lifetime.start", mPtr); + DISPLAY_INST1(BeLifetimeStartInst, "lifetime.start", mPtr); DISPLAY_INST1(BeLifetimeEndInst, "lifetime.end", mPtr); + DISPLAY_INST1(BeLifetimeSoftEndInst, "lifetime.softEnd", mPtr); DISPLAY_INST2(BeLifetimeFenceInst, "lifetime.fence", mFenceBlock, mPtr); DISPLAY_INST0(BeValueScopeStartInst, "valueScope.start"); DISPLAY_INST1(BeValueScopeRetainInst, "valueScope.retain", mValue); @@ -2376,7 +2378,7 @@ String BeModule::ToString(BeFunction* wantFunc) DISPLAY_INST0(BeFenceInst, "fence"); DISPLAY_INST0(BeStackSaveInst, "stackSave"); DISPLAY_INST1(BeStackRestoreInst, "stackRestore", mStackVal); - DISPLAY_INST3(BeGEPInst, "gep", mPtr, mIdx0, mIdx1); + DISPLAY_INST3(BeGEPInst, "gep", mPtr, mIdx0, mIdx1); //DISPLAY_INST1(BeBrInst, "br", mTargetBlock); case BeBrInst::TypeId: { @@ -2392,7 +2394,7 @@ String BeModule::ToString(BeFunction* wantFunc) break; DISPLAY_INST3(BeCondBrInst, "condbr", mCond, mTrueBlock, mFalseBlock); - + case BeRetInst::TypeId: { auto castedInst = (BeRetInst*)inst; @@ -2438,7 +2440,7 @@ String BeModule::ToString(BeFunction* wantFunc) if (arg.mNoAlias) str += " noalias"; if (arg.mNoCapture) - str += " nocapture"; + str += " nocapture"; if (arg.mDereferenceableSize != -1) str += StrFormat(" dereferenceable(%d)", arg.mDereferenceableSize); } @@ -2452,17 +2454,17 @@ String BeModule::ToString(BeFunction* wantFunc) auto castedInst = (BePhiInst*)inst; str += "phi "; dc.ToString(str, castedInst->mType); - str += " "; + str += " "; for (int argIdx = 0; argIdx < (int)castedInst->mIncoming.size(); argIdx++) { if (argIdx > 0) str += ", "; - str += "["; + str += "["; dc.ToString(str, castedInst->mIncoming[argIdx]->mValue); str += ", "; dc.ToString(str, castedInst->mIncoming[argIdx]->mBlock); str += "]"; - } + } } break; case BeSwitchInst::TypeId: @@ -2492,7 +2494,7 @@ String BeModule::ToString(BeFunction* wantFunc) str += " "; if (auto dbgVariable = castedInst->mDbgVar) - { + { switch (dbgVariable->mInitType) { case BfIRInitType_NotNeeded: str += " noinit"; break; @@ -2536,13 +2538,13 @@ String BeModule::ToString(BeFunction* wantFunc) BeDbgLoc* inlinedAt = inst->mDbgLoc->mDbgInlinedAt; while (inlinedAt != NULL) - { + { str += StrFormat("#%d", inlinedAt->mIdx); inlinedAt = inlinedAt->mDbgInlinedAt; } } str += "]"; - } + } } str += "\n"; @@ -2551,7 +2553,6 @@ String BeModule::ToString(BeFunction* wantFunc) str += "}\n"; - if (func->mDbgFunction != NULL) { str += " DbgFunc: "; @@ -2572,14 +2573,14 @@ String BeModule::ToString(BeFunction* wantFunc) str += "\n"; } - + for (auto& dbgLocPair : dbgLocs) { - auto dbgLoc = dbgLocPair.mValue; + auto dbgLoc = dbgLocPair.mValue; dc.ToString(str, dbgLocPair.mValue); str += "\n"; } - str += "\n"; + str += "\n"; return str; } @@ -2596,7 +2597,7 @@ void BeModule::Print(BeFunction* func) void BeModule::PrintValue(BeValue* val) { - BeDumpContext dumpCtx; + BeDumpContext dumpCtx; String str; dumpCtx.ToString(str, val); str += "\n"; @@ -2620,7 +2621,7 @@ void BeModule::DoInlining(BeFunction* func) if (func->mDidInlinePass) return; - // Set this true here so we don't recurse on the same function + // Set this true here so we don't recurse on the same function func->mDidInlinePass = true; int numHeadAllocas = 0; @@ -2630,11 +2631,11 @@ void BeModule::DoInlining(BeFunction* func) // From head to resume std::unordered_multimap inlineResumesMap; - - // From resume to head - std::unordered_multimap inlineHeadMap; - bool hadInlining = false; + // From resume to head + std::unordered_multimap inlineHeadMap; + + bool hadInlining = false; std::function& funcInlined)> _DoInlining; _DoInlining = [&](int& blockIdx, BeBlock* endBlock, std::unordered_set& funcInlined) @@ -2674,14 +2675,14 @@ void BeModule::DoInlining(BeFunction* func) auto _CheckBlock = [&](BeBlock* checkBlock) { for (auto inst : checkBlock->mInstructions) - { + { switch (inst->GetTypeId()) { case BeBrInst::TypeId: { auto castedInst = (BeBrInst*)inst; if (castedInst->mTargetBlock == beBlock) - { + { found = true; } } @@ -2691,7 +2692,7 @@ void BeModule::DoInlining(BeFunction* func) auto castedInst = (BeCondBrInst*)inst; if ((castedInst->mTrueBlock == beBlock) || (castedInst->mFalseBlock == beBlock)) - { + { found = true; } } @@ -2768,7 +2769,7 @@ void BeModule::DoInlining(BeFunction* func) inliner.mModule = this; inliner.mSrcFunc = inlineFunc; inliner.mDestFunc = func; - inliner.mCallInst = callInst; + inliner.mCallInst = callInst; if ((func->mDbgFunction != NULL) && (inlineFunc->mDbgFunction != NULL)) { @@ -2785,7 +2786,7 @@ void BeModule::DoInlining(BeFunction* func) destDbgGlobalVar->mInitType = dbgGlobalVar->mInitType; if (dbgGlobalVar->mValue != NULL) { - BF_ASSERT(BeValueDynCast(dbgGlobalVar->mValue) != NULL); + BF_ASSERT(BeValueDynCast(dbgGlobalVar->mValue) != NULL); destDbgGlobalVar->mValue = dbgGlobalVar->mValue; } else @@ -2827,7 +2828,7 @@ void BeModule::DoInlining(BeFunction* func) inlineResumesMap.insert(std::make_pair(headBlock, returnBlock)); inlineHeadMap.insert(std::make_pair(returnBlock, headBlock)); - std::vector destBlocks; + std::vector destBlocks; for (int argIdx = 0; argIdx < (int)callInst->mArgs.size(); argIdx++) { @@ -2877,7 +2878,7 @@ void BeModule::DoInlining(BeFunction* func) destAlloca->mArraySize = allocaInst->mArraySize; destAlloca->mAlign = allocaInst->mAlign; destAlloca->mNoChkStk = allocaInst->mNoChkStk; - destAlloca->mForceMem = allocaInst->mForceMem; + destAlloca->mForceMem = allocaInst->mForceMem; destAlloca->mName = allocaInst->mName; auto destBlock = func->mBlocks[0]; @@ -2919,7 +2920,7 @@ void BeModule::DoInlining(BeFunction* func) auto brInst = mAlloc.Alloc(); inliner.AddInst(brInst, retInst); - auto fenceInst = mAlloc.Alloc(); + auto fenceInst = mAlloc.Alloc(); fenceInst->mFenceBlock = beBlock; fenceInst->mPtr = callInst->mInlineResult; inliner.AddInst(fenceInst, retInst); @@ -2936,7 +2937,7 @@ void BeModule::DoInlining(BeFunction* func) /*if (callInst->mInlineResult != NULL) { - auto fenceInst = mAlloc.Alloc(); + auto fenceInst = mAlloc.Alloc(); fenceInst->mPtr = callInst->mInlineResult; beBlock->mInstructions.push_back(fenceInst); }*/ @@ -2976,7 +2977,6 @@ void BeModule::DoInlining(BeFunction* func) return lhsInlinePos->mIdx < rhsInlinePos->mIdx; }); }*/ - } void BeModule::DoInlining() @@ -3107,7 +3107,7 @@ void BeModule::ToString(StringImpl& str, BeType* type) return; case BeTypeCode_Function: { - auto funcType = (BeFunctionType*)type; + auto funcType = (BeFunctionType*)type; ToString(str, funcType->mReturnType); str += "("; for (int paramIdx = 0; paramIdx < (int)funcType->mParams.size(); paramIdx++) @@ -3151,19 +3151,19 @@ void BeModule::ToString(StringImpl& str, BeType* type) void BeModule::SetActiveFunction(BeFunction* function) { - mActiveFunction = function; + mActiveFunction = function; } BeArgument* BeModule::GetArgument(int argIdx) { - while ((int)argIdx >= mArgs.size()) + while ((int)argIdx >= mArgs.size()) { auto arg = mAlloc.Alloc(); arg->mModule = this; arg->mArgIdx = (int)mArgs.size(); mArgs.push_back(arg); } - + return mArgs[argIdx]; } @@ -3177,12 +3177,12 @@ BeBlock* BeModule::CreateBlock(const StringImpl& name) void BeModule::AddBlock(BeFunction* function, BeBlock* block) { block->mFunction = function; - function->mBlocks.push_back(block); + function->mBlocks.push_back(block); } void BeModule::RemoveBlock(BeFunction* function, BeBlock* block) { - bool didRemove = function->mBlocks.Remove(block); + bool didRemove = function->mBlocks.Remove(block); BF_ASSERT(didRemove); #ifdef _DEBUG for (auto inst : block->mInstructions) @@ -3216,7 +3216,7 @@ BeFunction* BeModule::CreateFunction(BeFunctionType* funcType, BfIRLinkageType l func->mLinkageType = linkageType; func->mParams.Resize(funcType->mParams.size()); mFunctions.push_back(func); - + #ifdef _DEBUG // It IS possible hit this, especially if we have multiple intrinsics mapping to 'malloc' for example //BF_ASSERT(mFunctionMap.TryAdd(name, func)); @@ -3250,12 +3250,12 @@ void BeModule::SetCurrentDebugLocation(int line, int column, BeMDNode* dbgScope, mCurDbgLoc->mLine = line; mCurDbgLoc->mColumn = column; mCurDbgLoc->mDbgScope = dbgScope; - mCurDbgLoc->mDbgInlinedAt = dbgInlinedAt; + mCurDbgLoc->mDbgInlinedAt = dbgInlinedAt; mCurDbgLoc->mIdx = mCurDbgLocIdx++; if ((dbgInlinedAt != NULL) && (!dbgInlinedAt->mHadInline)) { - dbgInlinedAt->mHadInline = true; + dbgInlinedAt->mHadInline = true; } mLastDbgLoc = mCurDbgLoc; @@ -3265,7 +3265,7 @@ BeDbgLoc* BeModule::DupDebugLocation(BeDbgLoc* dbgLoc) { if (dbgLoc == NULL) return dbgLoc; - + auto newDbgLoc = mAlloc.Alloc(); newDbgLoc->mLine = dbgLoc->mLine; newDbgLoc->mColumn = dbgLoc->mColumn; @@ -3317,7 +3317,7 @@ BeBitCastInst * BeModule::CreateBitCast(BeValue* value, BeType* toType) { auto inst = mAlloc.Alloc(); inst->mValue = value; - inst->mToType = toType; + inst->mToType = toType; AddInst(inst); return inst; } @@ -3357,7 +3357,7 @@ BeAllocaInst* BeModule::CreateAlloca(BeType* type) } BeLoadInst* BeModule::CreateLoad(BeValue* value, bool isVolatile) -{ +{ auto inst = mAlloc.Alloc(); inst->mTarget = value; inst->mIsVolatile = isVolatile; @@ -3401,15 +3401,18 @@ BeStoreInst* BeModule::CreateAlignedStore(BeValue* val, BeValue* ptr, int alignm } BeGEPInst* BeModule::CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1) -{ +{ +#ifdef _DEBUG + BF_ASSERT(ptr->GetType()->IsPointer()); +#endif + auto inst = mAlloc.Alloc(); inst->mPtr = ptr; inst->mIdx0 = idx0; - inst->mIdx1 = idx1; - AddInst(inst); - + inst->mIdx1 = idx1; + AddInst(inst); + #ifdef _DEBUG - BF_ASSERT(ptr->GetType()->IsPointer()); inst->GetType(); #endif @@ -3459,11 +3462,11 @@ BeSetRetInst* BeModule::CreateSetRet(BeValue* value, int returnTypeId) } BeCallInst* BeModule::CreateCall(BeValue* func, const SizedArrayImpl& args) -{ +{ auto inst = mOwnedValues.Alloc(); inst->mFunc = func; if (!args.IsEmpty()) - { + { inst->mArgs.resize(args.size()); for (int i = 0; i < (int)args.size(); i++) inst->mArgs[i].mValue = args[i]; @@ -3499,8 +3502,8 @@ BeConstant* BeModule::GetConstant(BeType* type, int64 intVal) break; default: constant->mInt64 = intVal; - } - + } + return constant; } @@ -3514,16 +3517,16 @@ BeConstant* BeModule::GetConstant(BeType* type, bool boolVal) BeConstant* BeModule::GetConstantNull(BePointerType* type) { - auto constant = mAlloc.Alloc(); + auto constant = mAlloc.Alloc(); if (type == NULL) constant->mType = mContext->GetPrimitiveType(BeTypeCode_NullPtr); else - constant->mType = type; + constant->mType = type; return constant; } BeDbgReferenceType * BeDbgModule::CreateReferenceType(BeDbgType* elementType) -{ +{ BeDbgType* useType = elementType->FindDerivedType(BeDbgReferenceType::TypeId); if (useType == NULL) { @@ -3542,7 +3545,7 @@ void BeDbgModule::HashContent(BeHashContext & hashCtx) hashCtx.MixinStr(mDirectory); hashCtx.MixinStr(mProducer); - BeDumpContext dc; + BeDumpContext dc; String lhsName; String rhsName; @@ -3550,12 +3553,12 @@ void BeDbgModule::HashContent(BeHashContext & hashCtx) { auto _GetName = [&](BeDbgFunction* func, String& str) { - if (!func->mLinkageName.IsEmpty()) - str.Append(func->mLinkageName); - else - dc.ToString(str, func); + if (!func->mLinkageName.IsEmpty()) + str.Append(func->mLinkageName); + else + dc.ToString(str, func); }; - + Array unrefFuncs; for (auto dbgFunc : mFuncs) { @@ -3564,12 +3567,12 @@ void BeDbgModule::HashContent(BeHashContext & hashCtx) } std::sort(unrefFuncs.begin(), unrefFuncs.end(), [&](BeDbgFunction* lhs, BeDbgFunction* rhs) - { + { lhsName.Clear(); _GetName(lhs, lhsName); rhsName.Clear(); - _GetName(rhs, rhsName); + _GetName(rhs, rhsName); int cmp = String::Compare(lhsName, rhsName, false); if (cmp != 0) @@ -3590,7 +3593,7 @@ void BeDbgModule::HashContent(BeHashContext & hashCtx) if (lhs->mLine != rhs->mLine) return lhs->mLine < rhs->mLine; - + return lhs->mIdx < rhs->mIdx; }); @@ -3626,4 +3629,4 @@ void BeDbgModule::HashContent(BeHashContext & hashCtx) for (auto globalVar : mGlobalVariables) globalVar->HashReference(hashCtx); } -} +} \ No newline at end of file diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index b5925b82..637e527d 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -36,6 +36,7 @@ class BeLifetimeExtendInst; class BeAliasValueInst; class BeLifetimeStartInst; class BeLifetimeEndInst; +class BeLifetimeSoftEndInst; class BeLifetimeFenceInst; class BeValueScopeStartInst; class BeValueScopeRetainInst; @@ -67,7 +68,7 @@ public: virtual void Visit(BeValue* beValue) {} virtual void Visit(BeBlock* beBlock) {} - virtual void Visit(BeArgument* beArgument) {} + virtual void Visit(BeArgument* beArgument) {} virtual void Visit(BeInst* beInst) {} virtual void Visit(BeNopInst* nopInst) {} virtual void Visit(BeUnreachableInst* unreachableInst) {} @@ -75,10 +76,10 @@ public: virtual void Visit(BeUndefValueInst* undefValue) {} virtual void Visit(BeExtractValueInst* extractValue) {} virtual void Visit(BeInsertValueInst* insertValue) {} - virtual void Visit(BeNumericCastInst* castInst) {} - virtual void Visit(BeBitCastInst* castInst) {} - virtual void Visit(BeNegInst* negInst) {} - virtual void Visit(BeNotInst* notInst) {} + virtual void Visit(BeNumericCastInst* castInst) {} + virtual void Visit(BeBitCastInst* castInst) {} + virtual void Visit(BeNegInst* negInst) {} + virtual void Visit(BeNotInst* notInst) {} virtual void Visit(BeBinaryOpInst* binaryOpInst) {} virtual void Visit(BeFenceInst* fenceInst) {} virtual void Visit(BeStackSaveInst* stackSaveInst) {} @@ -90,6 +91,7 @@ public: virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) {} virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) {} virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) {} + virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) {} virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) {} virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) {} virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) {} @@ -106,8 +108,8 @@ public: virtual void Visit(BeSwitchInst* switchInst) {} virtual void Visit(BeRetInst* retInst) {} virtual void Visit(BeCallInst* callInst) {} - - //virtual void Visit(BeDbgVariable* dbgVariable) {} + + //virtual void Visit(BeDbgVariable* dbgVariable) {} virtual void Visit(BeDbgDeclareInst* dbgDeclareInst) {} }; @@ -120,15 +122,15 @@ class BeInliner : public BeValueVisitor public: BumpAllocator* mAlloc; OwnedVector* mOwnedValueVec; - Dictionary mValueMap; + Dictionary mValueMap; Dictionary mInlinedAtMap; - + BeModule* mModule; BeFunction* mSrcFunc; BeFunction* mDestFunc; - BeCallInst* mCallInst; - BeBlock* mDestBlock; - BeDbgLoc* mSrcDbgLoc; + BeCallInst* mCallInst; + BeBlock* mDestBlock; + BeDbgLoc* mSrcDbgLoc; BeDbgLoc* mDestDbgLoc; public: @@ -156,7 +158,7 @@ public: auto inst = mOwnedValueVec->Alloc(); AddInst(inst, srcInst); return inst; - } + } virtual void Visit(BeValue* beValue) override; virtual void Visit(BeBlock* beBlock) override; @@ -183,6 +185,7 @@ public: virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) override; virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) override; virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) override; + virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) override; virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) override; virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) override; virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) override; @@ -199,7 +202,7 @@ public: virtual void Visit(BeSwitchInst* switchInst) override; virtual void Visit(BeRetInst* retInst) override; virtual void Visit(BeCallInst* callInst) override; - + virtual void Visit(BeDbgDeclareInst* dbgDeclareInst) override; }; @@ -209,7 +212,7 @@ public: int mRefCount; #ifdef _DEBUG bool mLifetimeEnded; - bool mWasRemoved; + bool mWasRemoved; BeValue() { mLifetimeEnded = false; @@ -225,12 +228,11 @@ public: virtual ~BeValue() { - } static const int TypeId = 0; virtual void Accept(BeValueVisitor* beVisitor) = 0; - virtual bool TypeIdIsA(int typeId) = 0; + virtual bool TypeIdIsA(int typeId) = 0; virtual BeValue* DynCast(int typeId) { if (TypeIdIsA(typeId)) @@ -243,7 +245,6 @@ public: } virtual int GetTypeId() { return TypeId; } - public: virtual BeType* GetType() { @@ -252,7 +253,6 @@ public: virtual void SetName(const StringImpl& name) { - } }; @@ -307,8 +307,8 @@ class BeConstant : public BeValue { public: BE_VALUE_TYPE(BeConstant, BeValue); - - BeType* mType; + + BeType* mType; union { bool mBool; @@ -322,7 +322,7 @@ public: uint8 mUInt8; uint8 mChar; uint32 mChar32; - double mDouble; + double mDouble; //BeType* mTypeParam; //BeGlobalVariable* mGlobalVar; BeConstant* mTarget; @@ -335,7 +335,7 @@ public: return false; } - virtual BeType* GetType(); + virtual BeType* GetType(); virtual void GetData(BeConstData& data); virtual void HashContent(BeHashContext& hashCtx) override; }; @@ -362,7 +362,7 @@ class BeGEP1Constant : public BeConstant { public: BE_VALUE_TYPE(BeGEP1Constant, BeConstant); - int mIdx0; + int mIdx0; virtual BeType* GetType(); @@ -370,14 +370,14 @@ public: { hashCtx.Mixin(TypeId); mTarget->HashReference(hashCtx); - hashCtx.Mixin(mIdx0); + hashCtx.Mixin(mIdx0); } }; class BeGEP2Constant : public BeConstant { public: - BE_VALUE_TYPE(BeGEP2Constant, BeConstant); + BE_VALUE_TYPE(BeGEP2Constant, BeConstant); int mIdx0; int mIdx1; @@ -385,7 +385,7 @@ public: virtual void HashContent(BeHashContext& hashCtx) override { - hashCtx.Mixin(TypeId); + hashCtx.Mixin(TypeId); mTarget->HashReference(hashCtx); hashCtx.Mixin(mIdx0); hashCtx.Mixin(mIdx1); @@ -396,7 +396,7 @@ class BeExtractValueConstant : public BeConstant { public: BE_VALUE_TYPE(BeExtractValueConstant, BeConstant); - int mIdx0; + int mIdx0; virtual BeType* GetType(); @@ -404,14 +404,14 @@ public: { hashCtx.Mixin(TypeId); mTarget->HashReference(hashCtx); - hashCtx.Mixin(mIdx0); + hashCtx.Mixin(mIdx0); } }; class BeStructConstant : public BeConstant { public: - BE_VALUE_TYPE(BeStructConstant, BeConstant); + BE_VALUE_TYPE(BeStructConstant, BeConstant); SizedArray mMemberValues; @@ -431,25 +431,25 @@ class BeUndefConstant : public BeConstant { public: BE_VALUE_TYPE(BeUndefConstant, BeConstant); - + virtual void HashContent(BeHashContext& hashCtx) override { hashCtx.Mixin(mType); - hashCtx.Mixin(TypeId); + hashCtx.Mixin(TypeId); } }; class BeStringConstant : public BeConstant { public: - BE_VALUE_TYPE(BeStringConstant, BeConstant); + BE_VALUE_TYPE(BeStringConstant, BeConstant); String mString; virtual void HashContent(BeHashContext& hashCtx) override { hashCtx.Mixin(TypeId); - hashCtx.MixinStr(mString); + hashCtx.MixinStr(mString); } }; @@ -468,8 +468,8 @@ public: int mAlign; bool mUnnamedAddr; - virtual BeType* GetType(); - + virtual BeType* GetType(); + virtual void HashContent(BeHashContext& hashCtx) override { hashCtx.Mixin(TypeId); @@ -482,12 +482,12 @@ public: hashCtx.Mixin(mIsTLS); hashCtx.Mixin(mAlign); hashCtx.Mixin(mUnnamedAddr); - } + } virtual void GetData(BeConstData& data) override { data.mConsts.Add({ (int)data.mData.size(), this }); - data.mData.Insert(data.mData.size(), (uint8)0, 8); + data.mData.Insert(data.mData.size(), (uint8)0, 8); } }; @@ -519,13 +519,13 @@ class BeIntrinsic : public BeValue { public: BE_VALUE_TYPE(BeIntrinsic, BeValue); - + String mName; BfIRIntrinsic mKind; BeType* mReturnType; BeIntrinsic() - { + { mReturnType = NULL; } @@ -533,7 +533,7 @@ public: { hashCtx.Mixin(TypeId); hashCtx.Mixin(mKind); - } + } }; class BeFunction : public BeConstant @@ -541,15 +541,15 @@ class BeFunction : public BeConstant public: BE_VALUE_TYPE(BeFunction, BeConstant); - BeModule* mModule; + BeModule* mModule; #ifdef _DEBUG StringT<256> mName; #else String mName; #endif - BfIRLinkageType mLinkageType; + BfIRLinkageType mLinkageType; bool mIsVarReturn; - bool mAlwaysInline; + bool mAlwaysInline; bool mNoUnwind; bool mUWTable; bool mNoReturn; @@ -558,10 +558,10 @@ public: bool mIsDLLExport; bool mIsDLLImport; BfIRCallingConv mCallingConv; - Array mBlocks; + Array mBlocks; Array mParams; BeDbgFunction* mDbgFunction; - BeGlobalVariable* mRemapBindVar; + BeGlobalVariable* mRemapBindVar; public: BeFunction() @@ -572,15 +572,15 @@ public: mDbgFunction = NULL; mIsVarReturn = false; mAlwaysInline = false; - mDidInlinePass = false; + mDidInlinePass = false; mNoUnwind = false; mUWTable = false; mNoReturn = false; mNoFramePointerElim = false; mIsDLLExport = false; mIsDLLImport = false; - mRemapBindVar = NULL; - } + mRemapBindVar = NULL; + } BeFunctionType* GetFuncType() { @@ -597,7 +597,7 @@ public: { return (!mParams.IsEmpty()) && (mParams[0].mStructRet); } - + virtual void HashContent(BeHashContext& hashCtx) override; }; @@ -611,12 +611,11 @@ public: BeFunction* mFunction; public: - bool IsEmpty(); + bool IsEmpty(); virtual void HashContent(BeHashContext& hashCtx) override; }; - ////////////////////////////////////////////////////////////////////////// class BeInst : public BeValue @@ -627,8 +626,8 @@ public: BeBlock* mParentBlock; const char* mName; BeDbgLoc* mDbgLoc; - -public: + +public: BeContext* GetContext(); BeModule* GetModule(); @@ -637,7 +636,7 @@ public: return GetType() != NULL; } - virtual void SetName(const StringImpl& name) override; + virtual void SetName(const StringImpl& name) override; BeInst() { @@ -647,7 +646,7 @@ public: } virtual void HashInst(BeHashContext& hashCtx) = 0; - virtual void HashContent(BeHashContext& hashCtx) override; + virtual void HashContent(BeHashContext& hashCtx) override; }; class BeNopInst : public BeInst @@ -704,7 +703,7 @@ class BeExtractValueInst : public BeInst public: BE_VALUE_TYPE(BeExtractValueInst, BeInst); - BeValue* mAggVal; + BeValue* mAggVal; int mIdx; virtual BeType* GetType() override; @@ -766,7 +765,7 @@ public: BeValue* mValue; BeType* mToType; - + virtual BeType* GetType() override; virtual void HashInst(BeHashContext& hashCtx) override @@ -774,7 +773,7 @@ public: hashCtx.Mixin(TypeId); mValue->HashReference(hashCtx); mToType->HashReference(hashCtx); - } + } }; class BeNegInst : public BeInst @@ -782,7 +781,7 @@ class BeNegInst : public BeInst public: BE_VALUE_TYPE(BeNegInst, BeInst); - BeValue* mValue; + BeValue* mValue; virtual BeType* GetType() override; virtual void HashInst(BeHashContext& hashCtx) override @@ -820,15 +819,15 @@ enum BeBinaryOpKind BeBinaryOpKind_BitwiseAnd, BeBinaryOpKind_BitwiseOr, BeBinaryOpKind_ExclusiveOr, - BeBinaryOpKind_LeftShift, - BeBinaryOpKind_RightShift, + BeBinaryOpKind_LeftShift, + BeBinaryOpKind_RightShift, BeBinaryOpKind_ARightShift, BeBinaryOpKind_Equality, BeBinaryOpKind_InEquality, BeBinaryOpKind_GreaterThan, BeBinaryOpKind_LessThan, BeBinaryOpKind_GreaterThanOrEqual, - BeBinaryOpKind_LessThanOrEqual, + BeBinaryOpKind_LessThanOrEqual, }; class BeBinaryOpInst : public BeInst @@ -841,7 +840,7 @@ public: BeValue* mLHS; BeValue* mRHS; - virtual BeType* GetType() override; + virtual BeType* GetType() override; virtual void HashInst(BeHashContext& hashCtx) override { @@ -917,7 +916,7 @@ public: bool mForceMem; public: - virtual BeType* GetType() override; + virtual BeType* GetType() override; virtual void HashInst(BeHashContext& hashCtx) override { @@ -978,6 +977,20 @@ public: } }; +class BeLifetimeSoftEndInst : public BeInst +{ +public: + BE_VALUE_TYPE(BeLifetimeSoftEndInst, BeInst); + + BeValue* mPtr; + + virtual void HashInst(BeHashContext& hashCtx) override + { + hashCtx.Mixin(TypeId); + mPtr->HashReference(hashCtx); + } +}; + class BeLifetimeFenceInst : public BeInst { public: @@ -1017,7 +1030,7 @@ public: virtual void HashInst(BeHashContext& hashCtx) override { - hashCtx.Mixin(TypeId); + hashCtx.Mixin(TypeId); } }; @@ -1026,7 +1039,7 @@ class BeValueScopeRetainInst : public BeInst public: BE_VALUE_TYPE(BeValueScopeRetainInst, BeInst); - BeValue* mValue; + BeValue* mValue; virtual void HashInst(BeHashContext& hashCtx) override { @@ -1037,7 +1050,7 @@ public: class BeValueScopeEndInst : public BeInst { -public: +public: BE_VALUE_TYPE(BeValueScopeEndInst, BeInst); BeValueScopeStartInst* mScopeStart; @@ -1060,7 +1073,7 @@ public: bool mIsVolatile; public: - virtual BeType* GetType() override; + virtual BeType* GetType() override; virtual void HashInst(BeHashContext& hashCtx) override { @@ -1127,7 +1140,7 @@ public: virtual void HashInst(BeHashContext& hashCtx) override { - hashCtx.Mixin(TypeId); + hashCtx.Mixin(TypeId); } }; @@ -1138,7 +1151,7 @@ public: virtual void HashInst(BeHashContext& hashCtx) override { - hashCtx.Mixin(TypeId); + hashCtx.Mixin(TypeId); } virtual BeType* GetType() override @@ -1261,7 +1274,7 @@ class BeSwitchCase { public: BeConstant* mValue; - BeBlock* mBlock; + BeBlock* mBlock; }; class BeSwitchInst : public BeInst @@ -1321,7 +1334,7 @@ public: bool mStructRet; bool mZExt; bool mNoAlias; - bool mNoCapture; + bool mNoCapture; Arg() { mValue = NULL; @@ -1335,14 +1348,14 @@ public: }; public: - BE_VALUE_TYPE(BeCallInst, BeInst); + BE_VALUE_TYPE(BeCallInst, BeInst); BeValue* mInlineResult; BeValue* mFunc; SizedArray mArgs; BfIRCallingConv mCallingConv; bool mNoReturn; - bool mTailCall; + bool mTailCall; virtual BeType* GetType() override; @@ -1352,7 +1365,7 @@ public: mFunc = NULL; mCallingConv = BfIRCallingConv_CDecl; mNoReturn = false; - mTailCall = false; + mTailCall = false; } virtual void HashInst(BeHashContext& hashCtx) override @@ -1362,7 +1375,7 @@ public: mInlineResult->HashReference(hashCtx); mFunc->HashReference(hashCtx); for (auto& arg : mArgs) - { + { arg.mValue->HashReference(hashCtx); hashCtx.Mixin(arg.mStructRet); hashCtx.Mixin(arg.mZExt); @@ -1371,7 +1384,7 @@ public: } hashCtx.Mixin(mCallingConv); hashCtx.Mixin(mNoReturn); - hashCtx.Mixin(mTailCall); + hashCtx.Mixin(mTailCall); } bool HasStructRet() @@ -1388,9 +1401,9 @@ public: BE_VALUE_TYPE(BeComptimeError, BeInst); public: - int mError; + int mError; -public: +public: virtual void HashInst(BeHashContext& hashCtx) override { hashCtx.Mixin(TypeId); @@ -1407,7 +1420,7 @@ public: int mTypeId; BeType* mResultType; -public: +public: virtual BeType* GetType() override { return mResultType; @@ -1459,7 +1472,7 @@ public: } virtual void HashInst(BeHashContext& hashCtx) override - { + { hashCtx.Mixin(TypeId); mValue->HashReference(hashCtx); hashCtx.Mixin(mTypeId); @@ -1537,7 +1550,7 @@ public: struct BeDumpContext { -public: +public: Dictionary mValueNameMap; Dictionary mSeenNames; @@ -1571,7 +1584,6 @@ public: bool mIsValue; virtual void HashInst(BeHashContext& hashCtx) override; - }; class BeMDNode : public BeValue @@ -1582,7 +1594,6 @@ public: public: virtual ~BeMDNode() { - } virtual void HashContent(BeHashContext& hashCtx) override @@ -1603,20 +1614,20 @@ public: int mColumn; BeMDNode* mDbgScope; BeDbgLoc* mDbgInlinedAt; - int mIdx; + int mIdx; bool mHadInline; public: BeDbgLoc() - { + { } - int GetInlineDepth(); + int GetInlineDepth(); int GetInlineMatchDepth(BeDbgLoc* other); BeDbgLoc* GetInlinedAt(int idx = 0); BeDbgLoc* GetRoot(); BeDbgFunction* GetDbgFunc(); - BeDbgFile* GetDbgFile(); + BeDbgFile* GetDbgFile(); virtual void HashContent(BeHashContext& hashCtx) override { @@ -1628,7 +1639,7 @@ public: else hashCtx.Mixin(-1); if (mDbgInlinedAt != NULL) - mDbgInlinedAt->HashReference(hashCtx); + mDbgInlinedAt->HashReference(hashCtx); } }; @@ -1643,7 +1654,7 @@ public: BeBlock* mLastBeBlock; int mId; - virtual void HashContent(BeHashContext& hashCtx) override; + virtual void HashContent(BeHashContext& hashCtx) override; }; class BeDbgNamespace : public BeMDNode @@ -1670,16 +1681,16 @@ public: public: int mTypeId; - + BeDbgTypeId() { mTypeId = -1; } - + virtual void HashContent(BeHashContext& hashCtx) override { hashCtx.Mixin(TypeId); - hashCtx.Mixin(mTypeId); + hashCtx.Mixin(mTypeId); } }; @@ -1687,7 +1698,7 @@ class BeDbgType : public BeMDNode { public: BE_VALUE_TYPE(BeDbgType, BeMDNode); - + public: int mSize; int mAlign; @@ -1727,7 +1738,7 @@ public: BE_VALUE_TYPE(BeDbgBasicType, BeDbgType); public: - String mName; + String mName; int mEncoding; virtual void HashContent(BeHashContext& hashCtx) override @@ -1746,7 +1757,7 @@ public: BE_VALUE_TYPE(BeDbgArrayType, BeDbgType); public: - BeDbgType* mElement; + BeDbgType* mElement; int mNumElements; virtual void HashContent(BeHashContext& hashCtx) override @@ -1755,7 +1766,7 @@ public: hashCtx.Mixin(mSize); hashCtx.Mixin(mAlign); hashCtx.Mixin(mNumElements); - mElement->HashReference(hashCtx); + mElement->HashReference(hashCtx); } }; @@ -1807,10 +1818,10 @@ public: class BeDbgPointerType : public BeDbgType { public: - BE_VALUE_TYPE(BeDbgPointerType, BeDbgType); + BE_VALUE_TYPE(BeDbgPointerType, BeDbgType); public: - BeDbgType* mElement; + BeDbgType* mElement; virtual void HashContent(BeHashContext& hashCtx) override { @@ -1845,7 +1856,7 @@ public: int mFlags; int mOffset; bool mIsStatic; - BeValue* mStaticValue; + BeValue* mStaticValue; public: BeDbgStructMember() @@ -1878,7 +1889,7 @@ public: public: BeDbgType* mReturnType; Array mParams; - + public: virtual void HashContent(BeHashContext& hashCtx) override { @@ -1937,9 +1948,9 @@ public: Kind_SymbolAddr }; - Kind mKind; - X64CPURegister mReg; - int mOfs; + Kind mKind; + X64CPURegister mReg; + int mOfs; public: BeDbgVariableLoc() @@ -1957,7 +1968,7 @@ public: public: String mName; - BeMDNode* mType; + BeMDNode* mType; BeValue* mValue; int mParamNum; BfIRInitType mInitType; @@ -1967,13 +1978,13 @@ public: BeDbgLoc* mDeclDbgLoc; BeDbgVariableLoc mPrimaryLoc; - BeDbgVariableLoc mSavedLoc; + BeDbgVariableLoc mSavedLoc; int mDeclStart; - int mDeclEnd; - int mDeclMCBlockId; + int mDeclEnd; + int mDeclMCBlockId; bool mDeclLifetimeExtend; bool mDbgLifeEnded; - bool mIsValue; // Value vs Addr + bool mIsValue; // Value vs Addr Array mSavedRanges; Array mGaps; @@ -2010,7 +2021,7 @@ public: if (mScope != NULL) mScope->HashReference(hashCtx); if (mDeclDbgLoc != NULL) - mDeclDbgLoc->HashReference(hashCtx); + mDeclDbgLoc->HashReference(hashCtx); // The others only get filled in after generation -- not part of hash } @@ -2048,8 +2059,8 @@ public: bool mIncludedAsMember; int mFlags; int mVK; - int mVIndex; - + int mVIndex; + Array mVariables; int mPrologSize; int mCodeLen; @@ -2072,9 +2083,9 @@ public: mIsLocalToUnit = false; mVK = -1; mVIndex = -1; - mIsStaticMethod = true; + mIsStaticMethod = true; mIncludedAsMember = false; - mPrologSize = 0; + mPrologSize = 0; mCodeLen = -1; mCvTypeId = -1; mCvFuncId = -1; @@ -2111,7 +2122,7 @@ public: return ((mVariables.size() > 0) && (mVariables[0]->mName == "this")); }*/ } - + virtual void HashContent(BeHashContext& hashCtx) override; }; @@ -2149,7 +2160,7 @@ public: public: BeDbgStructType() { - mScope = NULL; + mScope = NULL; mDerivedFrom = NULL; mIsStatic = false; mIsFullyDefined = false; @@ -2219,12 +2230,12 @@ public: BE_VALUE_TYPE(BeDbgFile, BeMDNode); public: - String mFileName; + String mFileName; String mDirectory; Val128 mMD5Hash; - int mIdx; + int mIdx; - void ToString(String& str); + void ToString(String& str); void GetFilePath(String& outStr); virtual void HashContent(BeHashContext& hashCtx) override @@ -2278,7 +2289,7 @@ public: String mFileName; String mDirectory; String mProducer; - + OwnedVector mFiles; OwnedVector mNamespaces; OwnedVector mGlobalVariables; @@ -2286,7 +2297,7 @@ public: OwnedVector mTypes; Array mFuncs; // Does not include methods in structs - virtual void HashContent(BeHashContext& hashCtx) override; + virtual void HashContent(BeHashContext& hashCtx) override; BeDbgReferenceType* CreateReferenceType(BeDbgType* dbgType); }; @@ -2313,18 +2324,18 @@ public: int mInsertPos; BeDbgLoc* mCurDbgLoc; BeDbgLoc* mPrevDbgLocInline; - BeDbgLoc* mLastDbgLoc; - Array mArgs; - Array mFunctions; + BeDbgLoc* mLastDbgLoc; + Array mArgs; + Array mFunctions; Dictionary mFunctionMap; int mCurDbgLocIdx; - int mCurLexBlockId; + int mCurLexBlockId; BeDbgModule* mDbgModule; CeMachine* mCeMachine; -public: - void AddInst(BeInst* inst); +public: + void AddInst(BeInst* inst); static void ToString(StringImpl& str, BeType* type); static void StructToString(StringImpl& str, BeStructType* type); @@ -2345,7 +2356,7 @@ public: } public: - BeModule(const StringImpl& moduleName, BeContext* context); + BeModule(const StringImpl& moduleName, BeContext* context); ~BeModule(); void Hash(BeHashContext& hashCtx); @@ -2358,11 +2369,11 @@ public: void DoInlining(BeFunction* func); void DoInlining(); - static BeCmpKind InvertCmp(BeCmpKind cmpKind); - static BeCmpKind SwapCmpSides(BeCmpKind cmpKind); + static BeCmpKind InvertCmp(BeCmpKind cmpKind); + static BeCmpKind SwapCmpSides(BeCmpKind cmpKind); void SetActiveFunction(BeFunction* function); BeArgument* GetArgument(int arg); - BeBlock* CreateBlock(const StringImpl& name); + BeBlock* CreateBlock(const StringImpl& name); void AddBlock(BeFunction* function, BeBlock* block); void RemoveBlock(BeFunction* function, BeBlock* block); BeBlock* GetInsertBlock(); @@ -2378,9 +2389,9 @@ public: /// BeNopInst* CreateNop(); BeUndefValueInst* CreateUndefValue(BeType* type); - BeNumericCastInst* CreateNumericCast(BeValue* value, BeType* toType, bool valSigned, bool toSigned); + BeNumericCastInst* CreateNumericCast(BeValue* value, BeType* toType, bool valSigned, bool toSigned); BeBitCastInst* CreateBitCast(BeValue* value, BeType* toType);; - BeCmpInst* CreateCmp(BeCmpKind cmpKind, BeValue* lhs, BeValue* rhs); + BeCmpInst* CreateCmp(BeCmpKind cmpKind, BeValue* lhs, BeValue* rhs); BeBinaryOpInst* CreateBinaryOp(BeBinaryOpKind opKind, BeValue* lhs, BeValue* rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None); BeAllocaInst* CreateAlloca(BeType* type); @@ -2390,19 +2401,17 @@ public: BeStoreInst* CreateAlignedStore(BeValue* val, BeValue* ptr, int alignment, bool isVolatile); BeGEPInst* CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1); - BeBrInst* CreateBr(BeBlock* block); + BeBrInst* CreateBr(BeBlock* block); BeCondBrInst* CreateCondBr(BeValue* cond, BeBlock* trueBlock, BeBlock* falseBlock); BeRetInst* CreateRetVoid(); - BeRetInst* CreateRet(BeValue* value); + BeRetInst* CreateRet(BeValue* value); BeSetRetInst* CreateSetRet(BeValue* value, int returnTypeId); BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl& args); - - BeConstant* GetConstant(BeType* type, double floatVal); BeConstant* GetConstant(BeType* type, int64 intVal); BeConstant* GetConstant(BeType* type, bool boolVal); - BeConstant* GetConstantNull(BePointerType* type); + BeConstant* GetConstantNull(BePointerType* type); }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/BumpList.h b/IDEHelper/BumpList.h index e17a2965..66b1d49c 100644 --- a/IDEHelper/BumpList.h +++ b/IDEHelper/BumpList.h @@ -10,7 +10,7 @@ class BumpList { public: struct Node - { + { T mValue; Node* mNext; }; @@ -18,14 +18,14 @@ public: struct Iterator { public: - Node* mNode; + Node* mNode; public: Iterator(Node* node) { mNode = node; } - + Iterator& operator++() { mNode = mNode->mNext; @@ -50,20 +50,20 @@ public: struct RemovableIterator { - public: + public: Node** mPrevNextPtr; public: RemovableIterator(Node** headPtr) - { + { mPrevNextPtr = headPtr; } RemovableIterator& operator++() { - Node* newNode = *mPrevNextPtr; - if (newNode != NULL) - mPrevNextPtr = &newNode->mNext; + Node* newNode = *mPrevNextPtr; + if (newNode != NULL) + mPrevNextPtr = &newNode->mNext; return *this; } @@ -96,7 +96,7 @@ public: } void PushFront(T value, BumpAllocator* bumpAllocator) - { + { auto newHead = bumpAllocator->Alloc(); newHead->mValue = value; newHead->mNext = mHead; @@ -152,7 +152,7 @@ public: mVals[2] = NULL; mNextBlock = NULL; } - }; + }; struct Iterator { @@ -163,7 +163,7 @@ public: public: Iterator(NodeBlock* nodeBlock) { - SetNodeBlock(nodeBlock); + SetNodeBlock(nodeBlock); } void SetNodeBlock(NodeBlock* nodeBlock) @@ -183,7 +183,7 @@ public: { mMemberIdx--; if (mMemberIdx < 0) - SetNodeBlock(mNodeBlock->mNextBlock); + SetNodeBlock(mNodeBlock->mNextBlock); return *this; } @@ -209,11 +209,11 @@ public: BlockBumpList() { mHeadBlock = NULL; - } + } void Add(T value, BumpAllocator* bumpAllocator) { - if (mHeadBlock == NULL) + if (mHeadBlock == NULL) mHeadBlock = bumpAllocator->Alloc(); else if (mHeadBlock->mVals[NodeBlock::NodeCount - 1]) { diff --git a/IDEHelper/CMakeLists.txt b/IDEHelper/CMakeLists.txt index 32068a31..dc41ea2d 100644 --- a/IDEHelper/CMakeLists.txt +++ b/IDEHelper/CMakeLists.txt @@ -24,8 +24,8 @@ endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros add_definitions( - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -39,17 +39,17 @@ set (CMAKE_CXX_STANDARD 14) INCLUDE(CheckIncludeFiles) CHECK_INCLUDE_FILES(backtrace.h HAVE_BACKTRACE_HEADERS) if (HAVE_BACKTRACE_HEADERS) - add_definitions(-DBFP_HAS_BACKTRACE) + add_definitions(-DBFP_HAS_BACKTRACE) endif () if (${APPLE}) include_directories( . ../ - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party - ../BeefySysLib/third_party/freetype/include - ../extern/llvm-project_13_0_1/llvm/include + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include ../extern/llvm-project_13_0_1/llvm/lib/Target ../BeefySysLib/platform/osx @@ -58,13 +58,13 @@ else() include_directories( . ../ - ../BeefySysLib/ + ../BeefySysLib/ ../BeefySysLib/third_party - ../BeefySysLib/third_party/freetype/include - ../extern/llvm-project_13_0_1/llvm/include + ../BeefySysLib/third_party/freetype/include + ../extern/llvm-project_13_0_1/llvm/include ../extern/llvm-project_13_0_1/llvm/lib/Target - ../BeefySysLib/platform/linux + ../BeefySysLib/platform/linux ) endif() @@ -101,16 +101,16 @@ endif() # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -130,7 +130,7 @@ endif(NOT MSVC) ####################################### file(GLOB SRC_FILES - BfDiff.cpp + BfDiff.cpp Debugger.cpp DebugManager.cpp DebugVisualizers.cpp @@ -143,8 +143,8 @@ file(GLOB SRC_FILES X86XmmInfo.cpp LinuxDebugger.cpp - - Beef/BfCommon.cpp + + Beef/BfCommon.cpp Clang/CDepChecker.cpp Clang/ClangHelper.cpp Compiler/BfAst.cpp @@ -181,7 +181,7 @@ file(GLOB SRC_FILES Compiler/CeMachine.cpp Compiler/CeDebugger.cpp Compiler/MemReporter.cpp - + Backend/BeContext.cpp Backend/BeIRCodeGen.cpp Backend/BeModule.cpp @@ -195,9 +195,18 @@ add_library(${PROJECT_NAME} SHARED execute_process( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_13_0_1/bin/llvm-config --system-libs --link-static OUTPUT_VARIABLE LLVM_SYSTEM_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE EXEC_RESULT ) +if (EXEC_RESULT AND NOT EXEC_RESULT EQUAL 0) + if (EXEC_RESULT MATCHES "^[0-9]+$") + message(FATAL_ERROR "llvm-config exited with code ${EXEC_RESULT}.") + else() + message(FATAL_ERROR "llvm-config couldn't be executed: ${EXEC_RESULT}") + endif() +endif() + set(TARGET_LIBS_OS "${LLVM_SYSTEM_LIBS}") if (HAVE_BACKTRACE_HEADERS) @@ -209,18 +218,18 @@ list(APPEND LLVM_LIBS ${LLVM_LIB}/libLLVMCore.a ${LLVM_LIB}/libLLVMCodeGen.a ${LLVM_LIB}/libLLVMMC.a - ${LLVM_LIB}/libLLVMMCParser.a - ${LLVM_LIB}/libLLVMMCDisassembler.a + ${LLVM_LIB}/libLLVMMCParser.a + ${LLVM_LIB}/libLLVMMCDisassembler.a ${LLVM_LIB}/libLLVMObject.a ${LLVM_LIB}/libLLVMBitReader.a - ${LLVM_LIB}/libLLVMAsmParser.a - ${LLVM_LIB}/libLLVMTarget.a + ${LLVM_LIB}/libLLVMAsmParser.a + ${LLVM_LIB}/libLLVMTarget.a ${LLVM_LIB}/libLLVMScalarOpts.a ${LLVM_LIB}/libLLVMInstCombine.a ${LLVM_LIB}/libLLVMSelectionDAG.a ${LLVM_LIB}/libLLVMProfileData.a - - ${LLVM_LIB}/libLLVMAnalysis.a + + ${LLVM_LIB}/libLLVMAnalysis.a ${LLVM_LIB}/libLLVMAsmPrinter.a ${LLVM_LIB}/libLLVMBitWriter.a ${LLVM_LIB}/libLLVMVectorize.a @@ -228,21 +237,21 @@ list(APPEND LLVM_LIBS ${LLVM_LIB}/libLLVMInstrumentation.a ${LLVM_LIB}/libLLVMDebugInfoDWARF.a ${LLVM_LIB}/libLLVMDebugInfoPDB.a - ${LLVM_LIB}/libLLVMDebugInfoCodeView.a + ${LLVM_LIB}/libLLVMDebugInfoCodeView.a ${LLVM_LIB}/libLLVMGlobalISel.a ${LLVM_LIB}/libLLVMTransformUtils.a - ${LLVM_LIB}/libLLVMBinaryFormat.a + ${LLVM_LIB}/libLLVMBinaryFormat.a ${LLVM_LIB}/libLLVMIRReader.a - ${LLVM_LIB}/libLLVMLinker.a + ${LLVM_LIB}/libLLVMLinker.a ${LLVM_LIB}/libLLVMAggressiveInstCombine.a - ${LLVM_LIB}/libLLVMBitstreamReader.a + ${LLVM_LIB}/libLLVMBitstreamReader.a ${LLVM_LIB}/libLLVMCFGuard.a ${LLVM_LIB}/libLLVMTextAPI.a ${LLVM_LIB}/libLLVMRemarks.a - ${LLVM_LIB}/libLLVMX86Info.a - ${LLVM_LIB}/libLLVMX86Desc.a + ${LLVM_LIB}/libLLVMX86Info.a + ${LLVM_LIB}/libLLVMX86Desc.a ${LLVM_LIB}/libLLVMX86CodeGen.a ${LLVM_LIB}/libLLVMX86AsmParser.a ${LLVM_LIB}/libLLVMX86Disassembler.a @@ -273,7 +282,7 @@ list(APPEND LLVM_LIBS FOREACH (lib ${LLVM_LIBS}) string(APPEND TARGET_LIBS_OS " " ${lib}) -ENDFOREACH() +ENDFOREACH() if (CMAKE_BUILD_TYPE STREQUAL "Debug" ) FILE(WRITE "${CMAKE_CURRENT_SOURCE_DIR}/../IDE/dist/IDEHelper_libs_d.txt" ${TARGET_LIBS_OS}) @@ -285,7 +294,7 @@ endif() if(MSVC) target_link_libraries(${PROJECT_NAME} BeefySysLib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib LLVMX86Disassembler.lib LLVMMCDisassembler.lib LLVMSupport.lib LLVMX86Info.lib LLVMX86Desc.lib %(AdditionalDependencies) LLVMMC.lib LLVMObject.lib LLVMCore.lib LLVMBitReader.lib LLVMAsmParser.lib LLVMMCParser.lib LLVMCodeGen.lib LLVMTarget.lib LLVMX86CodeGen.lib LLVMScalarOpts.lib LLVMInstCombine.lib LLVMSelectionDAG.lib LLVMProfileData.lib LLVMTransformUtils.lib LLVMAnalysis.lib LLVMX86AsmParser.lib LLVMAsmPrinter.lib LLVMBitWriter.lib LLVMVectorize.lib LLVMipo.lib LLVMInstrumentation.lib LLVMDebugInfoDWARF.lib LLVMDebugInfoPDB.lib LLVMDebugInfoCodeView.lib LLVMGlobalISel.lib LLVMBinaryFormat.lib LLVMAggressiveInstCombine.lib libcurl_a.lib) else() - target_link_libraries(${PROJECT_NAME} BeefySysLib hunspell pthread dl ${TARGET_LIBS_OS} - + target_link_libraries(${PROJECT_NAME} BeefySysLib hunspell pthread dl ${TARGET_LIBS_OS} + ) endif() diff --git a/IDEHelper/COFF.cpp b/IDEHelper/COFF.cpp index 065c9eb5..116f7871 100644 --- a/IDEHelper/COFF.cpp +++ b/IDEHelper/COFF.cpp @@ -21,7 +21,6 @@ #include "BeefySysLib/util/AllocDebug.h" - #define LF_CLASS_EX 0x1608 #define LF_STRUCTURE_EX 0x1609 @@ -109,7 +108,7 @@ static const char* GetNamespaceEnd(const char* name) if ((c == '<') || (c == ' ')) return NULL; if ((c == ':') && (checkPtr[1] == ':')) - lastDblColon = checkPtr; + lastDblColon = checkPtr; } return lastDblColon; } @@ -163,7 +162,7 @@ uint8* CvStreamReader::GetTempPtr(int offset, int size, bool mayRecurse, bool* m if (pageStart >= pageEnd) return mStreamPtrs.mVals[pageStart] + (offset & ((1< 0) { @@ -193,7 +192,7 @@ uint8* CvStreamReader::GetTempPtr(int offset, int size, bool mayRecurse, bool* m memcpy(destPtr, mStreamPtrs.mVals[copyPage] + pageOffset, copyBytes); destPtr += copyBytes; offset += copyBytes; - size -= copyBytes; + size -= copyBytes; } return dest; } @@ -203,15 +202,15 @@ uint8* CvStreamReader::GetPermanentPtr(int offset, int size, bool* madeCopy) int pageStart = offset >> mPageBits; int pageEnd = (offset + size - 1) >> mPageBits; - if (pageStart == pageEnd) - return mStreamPtrs.mVals[pageStart] + (offset & ((1 << mPageBits) - 1)); - - // Handle the relatively-rare case of spanning multiple pages + if (pageStart == pageEnd) + return mStreamPtrs.mVals[pageStart] + (offset & ((1 << mPageBits) - 1)); + + // Handle the relatively-rare case of spanning multiple pages BP_ALLOC("GetPermanentPtr", size); uint8* destData = mCOFF->mAlloc.AllocBytes(size, "GetPermanentPtr"); if (madeCopy != NULL) *madeCopy = true; - + uint8* destPtr = destData; while (size > 0) { @@ -231,13 +230,13 @@ uint8* CvStreamReader::GetPermanentPtr(int offset, int size, bool* madeCopy) COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget) { mParseKind = ParseKind_Full; - memset(mWantPDBGuid, 0, 16); - memset(mPDBGuid, 0, 16); + memset(mWantPDBGuid, 0, 16); + memset(mPDBGuid, 0, 16); mWantAge = -1; mDebugAge = -1; mFileAge = -1; mCvMinTag = -1; - mCvMaxTag = -1; + mCvMaxTag = -1; mCvIPIMinTag = -1; mCvIPIMaxTag = -1; mMasterCompileUnit = NULL; @@ -247,8 +246,8 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget) mCvPageSize = 0; mCvPageBits = 31; mCvDataStream = NULL; - mCvHeaderData = NULL; - mCvStrTableData = NULL; + mCvHeaderData = NULL; + mCvStrTableData = NULL; mCvPublicSymbolData = NULL; mCvGlobalSymbolData = NULL; mNewFPOData = NULL; @@ -261,10 +260,10 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget) mCvMappedViewOfFile = NULL; mCvMappedFileSize = 0; //mParsedProcRecs = false; - + mGlobalsTargetType = NULL; mPrevScanName = NULL; - mProcSymCount = 0; + mProcSymCount = 0; mCvSrcSrvStream = -1; mCvEmitStream = -1; mIsFastLink = false; @@ -272,8 +271,8 @@ COFF::COFF(DebugTarget* debugTarget) : DbgModule(debugTarget) mHotThunkDataLeft = 0; mTriedSymSrv = false; - mDbgSymRequest = NULL; - mWantsAutoLoadDebugInfo = false; + mDbgSymRequest = NULL; + mWantsAutoLoadDebugInfo = false; mPDBLoaded = false; mEmitSourceFile = NULL; } @@ -282,7 +281,7 @@ COFF::~COFF() { BF_ASSERT(mTempBufIdx == 0); ClosePDB(); - mDebugger->mDbgSymSrv.ReleaseRequest(mDbgSymRequest); + mDebugger->mDbgSymSrv.ReleaseRequest(mDbgSymRequest); } const char* COFF::CvCheckTargetMatch(const char* name, bool& wasBeef) @@ -359,7 +358,7 @@ const char* COFF::CvCheckTargetMatch(const char* name, bool& wasBeef) } int COFF::CvGetStringHash(const char* str) -{ +{ if (str == NULL) return 0; @@ -367,7 +366,7 @@ int COFF::CvGetStringHash(const char* str) const char* curHashPtr = str; while (*curHashPtr != 0) { - char c = *curHashPtr; + char c = *curHashPtr; curHash = ((curHash ^ *curHashPtr) << 5) - curHash; curHashPtr++; } @@ -395,8 +394,8 @@ void COFF::CvFixupName(char* name) } } - if (cPtrOut != NULL) - *(cPtrOut++) = '\0'; + if (cPtrOut != NULL) + *(cPtrOut++) = '\0'; } void COFF::InitCvTypes() @@ -418,18 +417,18 @@ void COFF::InitCvTypes() #else const int ptrMask = 0x0600; // T_64* #endif - mMasterCompileUnit = new DbgCompileUnit(this); - mMasterCompileUnit->mDbgModule = this; + mMasterCompileUnit = new DbgCompileUnit(this); + mMasterCompileUnit->mDbgModule = this; mMasterCompileUnit->mIsMaster = true; mCompileUnits.push_back(mMasterCompileUnit); - + CREATE_PRIMITIVE(T_NOTTRANS, DbgType_Void, "void", void*); mCvSystemTypes[T_NOTTRANS]->mSize = 0; mCvSystemTypes[T_NOTTRANS]->mAlign = 0; CREATE_PRIMITIVE(T_NOTYPE, DbgType_Void, "void", void*); mCvSystemTypes[T_NOTYPE]->mSize = 0; mCvSystemTypes[T_NOTYPE]->mAlign = 0; - CREATE_PRIMITIVE(T_VOID, DbgType_Void, "void", void*); + CREATE_PRIMITIVE(T_VOID, DbgType_Void, "void", void*); mCvSystemTypes[T_VOID]->mSize = 0; mCvSystemTypes[T_VOID]->mAlign = 0; mCvSystemTypes[T_PVOID] = ptrType; @@ -444,7 +443,7 @@ void COFF::InitCvTypes() ptrType->mTypeParam = dbgType; dbgType->mPtrType = ptrType; mCvSystemTypes[(int)T_VOID | 0x0600] = ptrType; -#endif +#endif #ifdef BF_DBG_32 CREATE_PRIMITIVE(T_HRESULT, DbgType_u32, "HRESULT", addr_target); @@ -502,7 +501,7 @@ addr_target COFF::GetSectionAddr(uint16 section, uint32 offset) } DbgType* COFF::CvGetType(int typeId) -{ +{ //TODO: How do we handle types that have the high bit set? if (typeId < 0) return NULL; @@ -510,7 +509,7 @@ DbgType* COFF::CvGetType(int typeId) /*if (typeId == 0) return NULL;*/ if (typeId < 0x1000) - { + { TYPE_ENUM_e typeEnum = (TYPE_ENUM_e)typeId; DbgType* type = mCvSystemTypes[typeId]; BF_ASSERT(type != NULL); @@ -521,7 +520,7 @@ DbgType* COFF::CvGetType(int typeId) if (type == NULL) type = CvParseType(typeId); - /*if ((!allowNull) || (type != NULL)) + /*if ((!allowNull) || (type != NULL)) { BF_ASSERT(type->mCompileUnit->mDbgModule == this); }*/ @@ -577,7 +576,7 @@ uint8* COFF::CvGetTagData(int tagIdx, bool ipi, int* outDataSize) auto& reader = ipi ? mCvIPIReader : mCvTypeSectionReader; int offset = ipi ? mCvIPITagStartMap[tagIdx - mCvIPIMinTag] : mCvTagStartMap[tagIdx - mCvMinTag]; - + uint8* data = reader.GetTempPtr(offset, 4); uint16 trLength = *(uint16*)data; data = reader.GetTempPtr(offset + 2, trLength, true); @@ -616,16 +615,16 @@ int64 COFF::CvParseConstant(uint16 constVal, uint8*& data) int64 COFF::CvParseConstant(uint8*& data) { - uint16 val = GET(uint16); - return CvParseConstant(val, data); + uint16 val = GET(uint16); + return CvParseConstant(val, data); } const char* COFF::CvParseString(uint8*& data) -{ +{ const char* strStart = (const char*)data; int strLen = strlen((const char*)data); if (strLen == 0) - return NULL; + return NULL; data += strLen + 1; return strStart; } @@ -647,7 +646,7 @@ const char* COFF::CvParseAndDupString(uint8*& data) } const char* COFF::CvDupString(const char* str, int strLen) -{ +{ BP_ALLOC("CvDupString", strLen + 1); char* dupStr = (char*)mAlloc.AllocBytes(strLen + 1, "CvParseAndDupString"); memcpy(dupStr, str, strLen); @@ -660,18 +659,18 @@ void COFF::CvParseArgList(DbgSubprogram* subprogram, int tagIdx, bool ipi) uint8* data = CvGetTagData(tagIdx, ipi); CvAutoReleaseTempData releaseTempData(this, data); - int16 trLeafType = GET(int16); + int16 trLeafType = GET(int16); BF_ASSERT(trLeafType == LF_ARGLIST); - int argCount = GET(int32); + int argCount = GET(int32); for (int argIdx = 0; argIdx < argCount; argIdx++) { CV_typ_t argTypeId = GET(CV_typ_t); DbgType* argType = CvGetType(argTypeId); BP_ALLOC_T(DbgVariable); - DbgVariable* arg = mAlloc.Alloc(); + DbgVariable* arg = mAlloc.Alloc(); arg->mType = argType; arg->mIsParam = true; subprogram->mParams.PushBack(arg); @@ -693,10 +692,10 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, uint8* dataStart = data; int16 trLeafType = GET(int16); - + if (trLeafType == LF_FUNC_ID) { - lfFuncId* funcData = (lfFuncId*)dataStart; + lfFuncId* funcData = (lfFuncId*)dataStart; subprogram = CvParseMethod(NULL, (const char*)funcData->name, funcData->type, false, subprogram); return subprogram; } @@ -704,7 +703,7 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, if (trLeafType == LF_MFUNC_ID) { lfMFuncId* funcData = (lfMFuncId*)dataStart; - auto parentType = CvGetType(funcData->parentType); + auto parentType = CvGetType(funcData->parentType); //subprogram = CvParseMethod(parentType, (const char*)funcData->name, funcData->type, false, subprogram); // We shouldn't pass parentType in there, because that would be the declType and not the actual primary type (ie: definition type) @@ -712,7 +711,7 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, return subprogram; } - //DbgSubprogram* subprogram = mAlloc.Alloc(); + //DbgSubprogram* subprogram = mAlloc.Alloc(); if (subprogram == NULL) { BP_ALLOC_T(DbgSubprogram); @@ -720,13 +719,13 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, } subprogram->mName = methodName; - + int argListId = 0; if (trLeafType == LF_MFUNCTION) { static int gMFuncIdx = 0; gMFuncIdx++; - + lfMFunc* funcData = (lfMFunc*)dataStart; argListId = funcData->arglist; subprogram->mReturnType = CvGetType(funcData->rvtype); @@ -737,9 +736,9 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, DbgType* thisType = CvGetType(funcData->thistype); if ((thisType != NULL) && (!thisType->IsVoid())) - { + { BP_ALLOC_T(DbgVariable); - DbgVariable* arg = mAlloc.Alloc(); + DbgVariable* arg = mAlloc.Alloc(); arg->mType = thisType; arg->mIsParam = true; arg->mTagIdx = gMFuncIdx; @@ -769,20 +768,18 @@ DbgSubprogram* COFF::CvParseMethod(DbgType* parentType, const char* methodName, else if (trLeafType == LF_MFUNC_ID) { // - } else { - SoftFail(StrFormat("Unhandled func type at tagId %d ipi %d", tagIdx, ipi)); + SoftFail(StrFormat("Unhandled func type at tagId %d ipi %d", tagIdx, ipi)); } - if ((parentType != NULL) && (!IsObjectFile())) - { + { subprogram->mCompileUnit = parentType->mCompileUnit; parentType->mMethodList.PushBack(subprogram); } - + mSubprograms.push_back(subprogram); CvParseArgList(subprogram, argListId, ipi); return subprogram; @@ -796,7 +793,7 @@ void COFF::CvParseMethodList(DbgType* parentType, const char* methodName, int ta uint8* dataEnd = data + dataSize; int16 trLeafType = GET(int16); - + BF_ASSERT(trLeafType == LF_METHODLIST); while (data < dataEnd) @@ -820,10 +817,10 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) offset += 2; data = reader.GetTempPtr(offset, trLength, true); CvAutoReleaseTempData releaseTempData(this, data); - - uint8* dataStart = data; + + uint8* dataStart = data; uint8* dataEnd = data + trLength; - int16 trLeafType = GET(int16); + int16 trLeafType = GET(int16); bool strMadeCopy; auto _ParseString = [&]() @@ -840,7 +837,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) return; switch (trLeafType) { - case LF_FIELDLIST: + case LF_FIELDLIST: { uint8* sectionStart = data; @@ -853,7 +850,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) case LF_VFUNCTAB: { lfVFuncTab& vfuncTab = *(lfVFuncTab*)leafDataStart; - + DbgType* vtableType = CvGetType(vfuncTab.type); BP_ALLOC_T(DbgVariable); @@ -865,15 +862,15 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) } break; case LF_BCLASS: - { - lfBClass& baseClassInfo = *(lfBClass*)leafDataStart; + { + lfBClass& baseClassInfo = *(lfBClass*)leafDataStart; BP_ALLOC_T(DbgBaseTypeEntry); DbgBaseTypeEntry* baseTypeEntry = mAlloc.Alloc(); data = (uint8*)&baseClassInfo.offset; baseTypeEntry->mThisOffset = (int)CvParseConstant(data); if (baseClassInfo.index != 0) - { + { baseTypeEntry->mBaseType = CvGetType(baseClassInfo.index); // if (parentType->mLanguage == DbgLanguage_Beef) @@ -881,12 +878,12 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) // if (!parentType->mBaseTypes.IsEmpty()) // parentType->mTypeParam = baseTypeEntry->mBaseType; // } - + parentType->mBaseTypes.PushBack(baseTypeEntry); - parentType->mAlign = std::max(parentType->mAlign, baseTypeEntry->mBaseType->GetAlign()); - + parentType->mAlign = std::max(parentType->mAlign, baseTypeEntry->mBaseType->GetAlign()); + if (!parentType->mSizeCalculated) - { + { if ((baseTypeEntry->mBaseType->GetByteCount() == 0) && (baseTypeEntry->mBaseType->IsBfObject())) { parentType->mExtType = DbgExtType_Interface; @@ -899,9 +896,9 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) break; case LF_VBCLASS: case LF_IVBCLASS: - { + { lfVBClass& baseClassInfo = *(lfVBClass*)leafDataStart; - + BP_ALLOC_T(DbgBaseTypeEntry); DbgBaseTypeEntry* baseTypeEntry = mAlloc.Alloc(); baseTypeEntry->mBaseType = CvGetType(baseClassInfo.index); @@ -916,14 +913,14 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) { CV_fldattr_t fieldAttr = GET(CV_fldattr_t); int64 fieldVal = CvParseConstant(data); - - const char* fieldName = _ParseString(); - + + const char* fieldName = _ParseString(); + BP_ALLOC_T(DbgVariable); DbgVariable* member = mAlloc.Alloc(); member->mCompileUnit = parentType->mCompileUnit; member->mConstValue = fieldVal; - member->mName = fieldName; + member->mName = fieldName; member->mIsStatic = true; member->mIsConst = true; member->mType = parentType->mTypeParam; @@ -950,16 +947,16 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) nestedType->mTypeParam = CvGetType(nestedTypeId); nestedType->mTypeCode = DbgType_TypeDef; nestedType->mName = typeName; - nestedType->mTypeName = typeName; + nestedType->mTypeName = typeName; nestedType->mParent = parentType; parentType->mSubTypeList.PushBack(nestedType); }*/ int16 pad = GET(int16); int32 nestedTypeId = GET(int32); - + const char* typeName = _ParseString(); - + DbgType* nestedType = CvCreateType(); nestedType->mTypeParam = CvGetType(nestedTypeId); nestedType->mTypeCode = DbgType_TypeDef; @@ -967,20 +964,20 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) { nestedType->mName = typeName; nestedType->mTypeName = typeName; - } + } nestedType->mParent = parentType; - parentType->mSubTypeList.PushBack(nestedType); + parentType->mSubTypeList.PushBack(nestedType); } break; case LF_ONEMETHOD: { CV_fldattr_t attr = GET(CV_fldattr_t); CV_typ_t methodTypeId = GET(CV_typ_t); - + int virtOffset = -1; if ((attr.mprop == CV_MTintro) || (attr.mprop == CV_MTpureintro)) virtOffset = GET(int32); - const char* methodName = _ParseString(); + const char* methodName = _ParseString(); DbgSubprogram* subProgram = CvParseMethod(parentType, methodName, methodTypeId, ipi); subProgram->mVirtual = (attr.mprop == CV_MTintro) || (attr.mprop == CV_MTpureintro) || (attr.mprop == CV_MTvirtual); subProgram->mVTableLoc = virtOffset; @@ -1006,19 +1003,19 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) for (int methodIdx = 0; methodIdx < count; methodIdx++) { - CV_fldattr_t attr = GET_FROM(listData, CV_fldattr_t); + CV_fldattr_t attr = GET_FROM(listData, CV_fldattr_t); int16 unused = GET_FROM(listData, int16); CV_typ_t methodTypeId = GET_FROM(listData, CV_typ_t); int virtOffset = -1; if ((attr.mprop == CV_MTintro) || (attr.mprop == CV_MTpureintro)) virtOffset = GET_FROM(listData, int32); - DbgSubprogram* subProgram = CvParseMethod(parentType, methodName, methodTypeId, ipi); + DbgSubprogram* subProgram = CvParseMethod(parentType, methodName, methodTypeId, ipi); subProgram->mVirtual = (attr.mprop == CV_MTintro) || (attr.mprop == CV_MTpureintro) || (attr.mprop == CV_MTvirtual); subProgram->mVTableLoc = virtOffset; } } - break; + break; case LF_MEMBER: case LF_STMEMBER: { @@ -1026,7 +1023,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) bool isConst = false; CV_fldattr_t attr = GET(CV_fldattr_t); CV_typ_t fieldTypeId = GET(CV_typ_t); - + if (parentType->mTagIdx == 29184) { NOP; @@ -1035,7 +1032,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) int memberOffset = -1; if (isStatic) { - //? + //? } else { @@ -1049,18 +1046,23 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) { parentType->mTypeParam = CvGetType(fieldTypeId); parentType->mTypeParam = GetPrimitiveType(parentType->mTypeParam->mTypeCode, DbgLanguage_Beef); - + parentType->mSize = parentType->mTypeParam->mSize; parentType->mAlign = parentType->mTypeParam->mAlign; if ((parentType->mBaseTypes.mHead != NULL) && (strcmp(parentType->mBaseTypes.mHead->mBaseType->mName, "System.Enum") == 0)) parentType->mTypeCode = DbgType_Enum; break; } + + if (strncmp(fieldName, "$using$", 7) == 0) + { + fieldName = NULL; + } } int64 constVal = 0; - if ((parentType->mLanguage == DbgLanguage_Beef) && (isStatic)) - { + if ((fieldName != NULL) && (parentType->mLanguage == DbgLanguage_Beef) && (isStatic)) + { for (char* cPtr = fieldName; true; cPtr++) { char c = *cPtr; @@ -1087,52 +1089,52 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) break; } } - } + } if ((isStatic) && (!isConst) && (IsObjectFile())) { // Already has statics filled in break; - } + } BP_ALLOC_T(DbgVariable); DbgVariable* member = mAlloc.Alloc(); - member->mIsStatic = isStatic; + member->mIsStatic = isStatic; DbgType* fieldType = CvGetType(fieldTypeId); // if (fieldType == NULL) -// { +// { // uint8* fieldTypeData = CvGetTagData(fieldTypeId, ipi); // CvAutoReleaseTempData releaseTempData(this, fieldTypeData); -// +// // // It's a section data ptr // int16 memberLeafType = *((int16*)fieldTypeData); // switch (memberLeafType) // { // case LF_BITFIELD: -// { +// { // lfBitfield& bitfield = *(lfBitfield*)fieldTypeData; // fieldType = CvGetType(bitfield.type); -// -// // Bit offset is expressed in MSB form +// +// // Bit offset is expressed in MSB form // member->mBitOffset = (fieldType->mSize * 8) - bitfield.position - bitfield.length; // member->mBitSize = bitfield.length; // } // break; // default: // BF_FATAL("Unhandled"); -// } -// } +// } +// } if (fieldType == NULL) fieldType = CvGetType(fieldTypeId); - + if ((fieldType->mTypeCode == DbgType_Enum) && (fieldType->GetByteCount() == 0)) fieldType = fieldType->GetPrimaryType(); // if (fieldType->mTypeCode == DbgType_Bitfield) // { -// auto bitfieldType = (DbgBitfieldType*)fieldType; +// auto bitfieldType = (DbgBitfieldType*)fieldType; // member->mBitOffset = bitfieldType->mPosition; // member->mBitSize = bitfieldType->mLength; // fieldType = fieldType->mTypeParam; @@ -1145,13 +1147,13 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) } else if (isStatic) { - // NOP + // NOP } else member->mMemberOffset = memberOffset; member->mType = fieldType; - member->mCompileUnit = parentType->mCompileUnit; - member->mName = fieldName; + member->mCompileUnit = parentType->mCompileUnit; + member->mName = fieldName; // Size should already be set, right? It gets set on 'dataSize' in the LF_STRUCT/LF_CLASS //parentType->mSize = std::max(memberOffset + fieldType->mSize, parentType->mSize); @@ -1161,7 +1163,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) parentType->mAlign = std::max(parentType->mAlign, fieldType->GetAlign()); if (!parentType->mSizeCalculated) - { + { parentType->mSize = std::max(memberOffset + fieldType->GetByteCount(), parentType->mSize); } } @@ -1175,7 +1177,7 @@ void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) if (isStatic) parentType->mNeedsGlobalsPopulated = true; } - break; + break; case LF_INDEX: { int _pad = (int)GET(uint16); @@ -1257,7 +1259,7 @@ int COFF::CvConvRegNum(int regNum, int* outBits) case CV_AMD64_DIL: if (outBits != NULL) *outBits = 8; return X64Reg_RDI; case CV_REG_DI: if (outBits != NULL) *outBits = 16; return X64Reg_RDI; case CV_REG_EDI: if (outBits != NULL) *outBits = 32; return X64Reg_RDI; - + case CV_AMD64_R8B: *outBits = 8; return X64Reg_R8; case CV_AMD64_R8W: *outBits = 16; return X64Reg_R8; case CV_AMD64_R8D: *outBits = 32; return X64Reg_R8; @@ -1378,7 +1380,7 @@ int COFF::CvConvRegNum(int regNum, int* outBits) // case CV_REG_XMM5: return X86Reg_XMM05; // case CV_REG_XMM6: return X86Reg_XMM06; // case CV_REG_XMM7: return X86Reg_XMM07; -#endif +#endif } return 0; // Nope @@ -1394,7 +1396,7 @@ DbgType* COFF::CvCreateType() DbgType* dbgType = mAlloc.Alloc(); dbgType->mCompileUnit = mMasterCompileUnit; dbgType->mTypeIdx = (int)linkedModule->mTypes.size(); - linkedModule->mTypes.push_back(dbgType); + linkedModule->mTypes.push_back(dbgType); return dbgType; } @@ -1436,21 +1438,21 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) int underlyingType = GET(int32); int typeIndex = GET(int32); const char* name = _ParseString(); - + dbgType = CvCreateType(); dbgType->mCompileUnit = mMasterCompileUnit; dbgType->mName = name; dbgType->mTypeName = name; - //SplitName(dbgType->mName, dbgType->mTypeName, dbgType->mTemplateParams); + //SplitName(dbgType->mName, dbgType->mTypeName, dbgType->mTemplateParams); dbgType->mTypeCode = DbgType_Enum; - dbgType->mTypeParam = CvGetTypeSafe(underlyingType); + dbgType->mTypeParam = CvGetTypeSafe(underlyingType); dbgType->mIsIncomplete = true; if (dbgType->mTypeParam->GetByteCount() == 0) dbgType->mIsDeclaration = true; dbgType->mSize = dbgType->mTypeParam->mSize; - dbgType->mAlign = dbgType->mTypeParam->mAlign; + dbgType->mAlign = dbgType->mTypeParam->mAlign; /*if (dbgType->mTypeParam->GetByteCount() == 0) { @@ -1485,19 +1487,19 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) dbgType->mTypeCode = DbgType_Bitfield; //bitfieldType->mPosition = (dbgType->mTypeParam->mSize * 8) - bitfield.position - bitfield.length; bitfieldType->mPosition = bitfield.position; - bitfieldType->mLength = bitfield.length; + bitfieldType->mLength = bitfield.length; bitfieldType->mSize = dbgType->mTypeParam->mSize; bitfieldType->mAlign = dbgType->mTypeParam->mAlign; dbgType->mSizeCalculated = true; dbgType->mPriority = DbgTypePriority_Unique; } break; - + case LF_CLASS: - case LF_STRUCTURE: + case LF_STRUCTURE: case LF_CLASS_EX: case LF_STRUCTURE_EX: - { + { unsigned short count; // count of number of elements in class CV_prop_t property; // property attribute field (prop_t) CV_typ_t field; // type index of LF_FIELD descriptor list @@ -1507,14 +1509,14 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) int16 extra = 0; if ((trLeafType == 0x1608) || (trLeafType == 0x1609)) - { + { property = GET(CV_prop_t); extra = GET(int16); field = GET(CV_typ_t); derived = GET(CV_typ_t); vshape = GET(CV_typ_t); count = GET(unsigned short); - dataSize = (int)CvParseConstant(data); + dataSize = (int)CvParseConstant(data); } else { @@ -1532,7 +1534,7 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) // { // NOP; // } - + // if ((strstr(name, "`") != NULL) || (strstr(name, "::__l") != NULL)) // { // OutputDebugStrF("Local type: %s\n", name); @@ -1545,17 +1547,25 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) for (int i = 0; true; i++) { char c = name[i]; + if (c == 0) + break; + + if (c == '$') { - if ((i >= 4) && (strcmp(&name[i - 5], "$part") == 0)) + if ((i >= 5) && (strncmp(&name[i - 5], "$part$", 6) == 0)) { if (!strMadeCopy) name = DbgDupString(name, "CvParseType.LF_CLASS"); - ((char*)name)[i - 5] = '\0'; - isPartialDef = true; + strcpy((char*)&name[i - 5], &name[i + 1]); + if (name[i - 5] == '\0') + { + isPartialDef = true; + break; + } } - break; } + if ((c == ' ') && (i >= 5)) { if ((name[i - 4] == 'e') && @@ -1590,15 +1600,13 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) else dbgType->mTypeCode = DbgType_Struct; - - DbgType* baseType = NULL; if (derived != 0) { baseType = CvGetTypeSafe(derived); BP_ALLOC_T(DbgBaseTypeEntry); DbgBaseTypeEntry* baseTypeEntry = mAlloc.Alloc(); - baseTypeEntry->mBaseType = baseType; + baseTypeEntry->mBaseType = baseType; dbgType->mBaseTypes.PushBack(baseTypeEntry); } @@ -1606,10 +1614,10 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) { dbgType->mAlign = 1; dbgType->mIsPacked = true; - } + } if (!dbgType->mIsDeclaration) - { + { dbgType->mSizeCalculated = true; dbgType->mSize = dataSize; @@ -1619,26 +1627,26 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) // some BF_MAX calculations we perform on it dbgType->mSizeCalculated = false; dbgType->mSize = 0; - } + } } - - if (vshape != 0) + + if (vshape != 0) { CvGetTypeSafe(vshape); - dbgType->mHasVTable = true; + dbgType->mHasVTable = true; } dbgType->mIsIncomplete = true; -// if (classInfo.field != 0) -// dbgType->mDefinedMembersSize = CvGetTagSize(classInfo.field, ipi); - +// if (classInfo.field != 0) +// dbgType->mDefinedMembersSize = CvGetTagSize(classInfo.field, ipi); + //CvParseMembers(dbgType, classInfo.field, sectionData); } break; case LF_UNION: - { - lfUnion& classInfo = *(lfUnion*)dataStart; + { + lfUnion& classInfo = *(lfUnion*)dataStart; data = (uint8*)&classInfo.data; int dataSize = (int)CvParseConstant(data); const char* name = _ParseString(); @@ -1649,8 +1657,8 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) dbgType->mName = name; dbgType->mTypeName = name; //SplitName(dbgType->mName, dbgType->mTypeName, dbgType->mTemplateParams); - dbgType->mTypeCode = DbgType_Union; - dbgType->mSize = dataSize; + dbgType->mTypeCode = DbgType_Union; + dbgType->mSize = dataSize; dbgType->mAlign = 1; dbgType->mSizeCalculated = !dbgType->mIsDeclaration; @@ -1660,7 +1668,7 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) break; case LF_MODIFIER: - { + { lfModifier& modifier = *(lfModifier*)dataStart; DbgType* outerType = CvGetTypeSafe(modifier.type); dbgType = outerType; @@ -1668,7 +1676,7 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) if (modifier.attr.MOD_const) { DbgType* innerType = dbgType; - dbgType = CvCreateType(); + dbgType = CvCreateType(); dbgType->mTypeParam = innerType; dbgType->mTypeCode = DbgType_Const; dbgType->mLanguage = innerType->mLanguage; @@ -1690,14 +1698,14 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) dbgType->mTypeParam = innerType; dbgType->mTypeCode = DbgType_Unaligned; dbgType->mLanguage = innerType->mLanguage; - } + } } break; case LF_POINTER: { lfPointer* pointerInfo = (lfPointer*)dataStart; - dbgType = CvCreateType(); + dbgType = CvCreateType(); dbgType->mTypeParam = CvGetTypeSafe(pointerInfo->utype); if (pointerInfo->attr.ptrmode == CV_PTR_MODE_RVREF) dbgType->mTypeCode = DbgType_RValueReference; @@ -1709,27 +1717,26 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) if ((dbgType->mTypeParam != NULL) && (dbgType->mTypeParam->mPtrType == NULL)) dbgType->mTypeParam->mPtrType = dbgType; } - //dbgType->mSize = pointerInfo->attr.size; + //dbgType->mSize = pointerInfo->attr.size; dbgType->mSize = sizeof(addr_target); dbgType->mAlign = dbgType->mSize; dbgType->mSizeCalculated = true; dbgType->mLanguage = dbgType->mTypeParam->mLanguage; - + /*if (prop.isconst) { DbgType* innerType = dbgType; - dbgType = CvCreateType(); + dbgType = CvCreateType(); dbgType->mTypeParam = innerType; dbgType->mTypeCode = DbgType_Const; dbgType->mSize = innerType->mSize; }*/ - //TODO: Handle const, volatile, ref, restrict, etc + //TODO: Handle const, volatile, ref, restrict, etc } break; case LF_DIMARRAY: { - } break; case LF_ARRAY: @@ -1740,7 +1747,7 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) dbgType = CvCreateType(); dbgType->mTypeParam = CvGetTypeSafe(array->elemtype); - dbgType->mTypeCode = DbgType_SizedArray; + dbgType->mTypeCode = DbgType_SizedArray; dbgType->mLanguage = dbgType->mTypeParam->mLanguage; data = (uint8*)&array->data; @@ -1770,14 +1777,14 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) uint8* argData = CvGetTagData(proc->arglist, ipi); CvAutoReleaseTempData releaseTempData(this, argData); - int16 argLeafType = GET_FROM(argData, int16); + int16 argLeafType = GET_FROM(argData, int16); BF_ASSERT(argLeafType == LF_ARGLIST); int argCount = GET_FROM(argData, int32); CV_typ_t* argTypes = (CV_typ_t*)argData; for (int paramIdx = 0; paramIdx < proc->parmcount; paramIdx++) { BP_ALLOC_T(DbgVariable); - DbgVariable* arg = mAlloc.Alloc(); + DbgVariable* arg = mAlloc.Alloc(); arg->mIsParam = true; arg->mType = CvGetTypeSafe(argTypes[paramIdx]); arg->mName = "$arg"; @@ -1801,14 +1808,14 @@ DbgType* COFF::CvParseType(int tagIdx, bool ipi) uint8* argData = CvGetTagData(proc->arglist, ipi); CvAutoReleaseTempData releaseTempData(this, argData); - int16 argLeafType = GET_FROM(argData, int16); + int16 argLeafType = GET_FROM(argData, int16); BF_ASSERT(argLeafType == LF_ARGLIST); int argCount = GET_FROM(argData, int32); CV_typ_t* argTypes = (CV_typ_t*)argData; for (int paramIdx = 0; paramIdx < proc->parmcount; paramIdx++) { BP_ALLOC_T(DbgVariable); - DbgVariable* arg = mAlloc.Alloc(); + DbgVariable* arg = mAlloc.Alloc(); arg->mIsParam = true; arg->mType = CvGetTypeSafe(argTypes[paramIdx]); arg->mName = "$arg"; @@ -1857,7 +1864,7 @@ void COFF::ParseTypeData(CvStreamReader& reader, int dataOffset) break; if (offset >= reader.mSize) break; - + //OutputDebugStrF("%X %X\n", tagIdx, (int)(data - sectionData)); BF_ASSERT(((offset) & 3) == 0); @@ -1865,8 +1872,8 @@ void COFF::ParseTypeData(CvStreamReader& reader, int dataOffset) //PTR_ALIGN(data, sectionData, 4); uint8* data = reader.GetTempPtr(offset, 4); - uint16 trLength = *(uint16*)data; - uint16 trLeafType = *(uint16*)(data + 2); + uint16 trLength = *(uint16*)data; + uint16 trLeafType = *(uint16*)(data + 2); // uint16 trLength = GET(uint16); // uint8* dataStart = data; @@ -1907,7 +1914,7 @@ void COFF::ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSiz // sectionData = CvReadStream(sectionNum, §ionSize); // if (sectionData == NULL) // return; -// uint8* data = sectionData; +// uint8* data = sectionData; CvReadStream(sectionNum, reader); uint8* data = reader.GetTempPtr(0, 0); @@ -1948,7 +1955,7 @@ void COFF::ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSiz //////// Validate Type indices int typeIndexCount = hashTypeIndexSize / 8; - // We expect a TypeIndexOffset for every 8k of data, plus the zero at the start + // We expect a TypeIndexOffset for every 8k of data, plus the zero at the start int expectedTypeIndices = (sectionSize - (int)(data - sectionData)) / 8192 + 1; // Assert it's in some acceptable range... @@ -2069,11 +2076,11 @@ void COFF::ParseTypeData() int hashAdjOffset = 0; int32 hashStream = -1; int32 hashAdjSize = 0; - int32 dataOffset = 0; - + int32 dataOffset = 0; + ParseTypeData(2, mCvTypeSectionReader, sectionSize, dataOffset, hashStream, hashAdjOffset, hashAdjSize, mCvMinTag, mCvMaxTag); //mCvTypeSectionData = sectionData; - + mCvTypeMap.Clear(); mCvTagStartMap.Clear(); mCvTypeMap.Resize(mCvMaxTag - mCvMinTag); @@ -2105,7 +2112,7 @@ void COFF::ParseTypeData() GET_INTO(int32, unk3); } - // Types listed in the adjustment table are always primary types, + // Types listed in the adjustment table are always primary types, // they should override any "old types" with the same name for (int adjIdx = 0; adjIdx < adjustCount; adjIdx++) { @@ -2113,12 +2120,12 @@ void COFF::ParseTypeData() GET_INTO(CV_typ_t, typeId); DbgType* dbgType = CvGetType(typeId); if (dbgType != NULL) - { + { dbgType->mPriority = DbgTypePriority_Primary_Explicit; } } - delete [] sectionData; + delete [] sectionData; } FixTypes(startingTypeIdx); @@ -2140,14 +2147,14 @@ void COFF::FixConstant(DbgVariable* constVar) void COFF::MapRanges(DbgVariable* variable, CV_LVAR_ADDR_RANGE* range, CV_LVAR_ADDR_GAP* gaps) { auto rangeStart = GetSectionAddr(range->isectStart, range->offStart); - + if (variable->mRangeStart == 0) { - variable->mRangeStart = rangeStart; + variable->mRangeStart = rangeStart; variable->mRangeLen = (rangeStart + range->cbRange) - variable->mRangeStart; } else - { + { addr_target maxEnd = BF_MAX(variable->mRangeStart + variable->mRangeLen, rangeStart + range->cbRange); variable->mRangeStart = BF_MIN(variable->mRangeStart, rangeStart); variable->mRangeLen = maxEnd - variable->mRangeStart; @@ -2177,7 +2184,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD CvCompileUnit* cvCompileUnit = (CvCompileUnit*)compileUnit; uint8* symDataStart = data; - DbgSubprogram* curSubprogram = NULL; + DbgSubprogram* curSubprogram = NULL; DbgVariable* curRegRelVariable = NULL; DbgVariable* curParam = NULL; DbgVariable* localVar = NULL; @@ -2202,10 +2209,10 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { mVariable = NULL; mRangedStart = NULL; - mRangedLength = 0; + mRangedLength = 0; } }; - SizedArray<_DeferredVariableLocation, 16> deferredVariableLocations; + SizedArray<_DeferredVariableLocation, 16> deferredVariableLocations; int unrangedIdx = -1; auto _NextUnrangedLocalVar = [&](const char* name, DbgType* varType) @@ -2213,7 +2220,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD inLocalVarRanged = false; localVar = NULL; - + unrangedIdx++; while (unrangedIdx < deferredVariableLocations.size()) { @@ -2222,7 +2229,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; localVar = NULL; unrangedIdx++; - } + } bool isParam = false; if (localVar == NULL) @@ -2252,7 +2259,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD blockStack.back()->mVariables.PushBack(localVar); //return; } - + localVar->mName = name; if (isParam) localVar->mIsParam = true; @@ -2311,7 +2318,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD deferredVariableLocation.mRangedLength = -1; // Mark as 'handled' } } - + locationDataStart = NULL; locationDataEnd = NULL; locationDataCount = 0; @@ -2322,7 +2329,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD for (auto& deferredVariableLocation : deferredVariableLocations) { if (deferredVariableLocation.mRangedLength == -1) - continue; + continue; auto deferredVar = deferredVariableLocation.mVariable; if (deferredVar->mLocationData != NULL) { @@ -2338,12 +2345,12 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD }; bool inlineDebugDump = false; - + if (useSubprogram != NULL) { curSubprogram = useSubprogram; blockStack.push_back(&curSubprogram->mBlock); - + curParam = curSubprogram->mParams.mHead; curRegRelVariable = curParam; } @@ -2382,7 +2389,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD } break; } - + /*if (handled) { data = dataEnd; @@ -2401,7 +2408,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD DbgType* typeDefType = CvCreateType(); typeDefType->mTypeCode = DbgType_TypeDef; typeDefType->mTypeParam = CvGetTypeSafe(udtSym.typind); - typeDefType->mName = DbgDupString((const char*)udtSym.name, "DbgDupString.S_UDT"); + typeDefType->mName = DbgDupString((const char*)udtSym.name, "DbgDupString.S_UDT"); if (strncmp(typeDefType->mName, "_bf::", 5) == 0) { typeDefType->mLanguage = DbgLanguage_Beef; @@ -2417,7 +2424,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD case S_OBJNAME: { GET_INTO(int32, objSig); - const char* objName = CvParseAndDupString(data); + const char* objName = CvParseAndDupString(data); } break; case S_CONSTANT: @@ -2435,7 +2442,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD data = constSym.name + strlen((const char*)constSym.name) + 1; constVar->mConstValue = CvParseConstant(constSym.value, data); FixConstant(constVar); - + if (constVar->mName != NULL) blockStack.back()->mVariables.PushBack(constVar); } @@ -2454,7 +2461,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD unsigned short reserved : 10; // Reserved. Must be zero. }; GET_INTO(ExpFlags, flags); - const char* symName = CvParseAndDupString(data); + const char* symName = CvParseAndDupString(data); } break; case S_GDATA32: @@ -2464,8 +2471,8 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { auto linkedModule = GetLinkedModule(); DATASYM32& dataSym = *(DATASYM32*)dataStart; - - char* name = (char*)dataSym.name; + + char* name = (char*)dataSym.name; char* targetName = NULL; DbgType* targetType = mMasterCompileUnit->mGlobalType; bool overrideBeef = false; @@ -2475,7 +2482,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD targetName = name; name = lastDblColon + 2; *lastDblColon = 0; - + if (strcmp(targetName, "_bf") == 0) { overrideBeef = true; @@ -2485,12 +2492,12 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD targetType = CvGetTypeOrNamespace(targetName); } } - + DbgType* dbgType = CvGetTypeSafe(dataSym.typind); BP_ALLOC_T(DbgVariable); DbgVariable* variable = mAlloc.Alloc(); - variable->mType = dbgType; + variable->mType = dbgType; variable->mLocationData = dataStart; variable->mLocationLen = 1; variable->mIsStatic = true; @@ -2510,25 +2517,25 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD auto newPtr = mAlloc.Alloc(); memcpy(newPtr, variable->mLocationData, sizeof(DATASYM32)); variable->mLocationData = (uint8*)newPtr; - } + } if (variable->mName != NULL) blockStack.back()->mVariables.PushBack(variable); break; } - //variable->mCompileUnit = m; + //variable->mCompileUnit = m; // Push front so we will find before the original static declaration (that has no memory associated with it) if (targetType != NULL) targetType->mMemberList.PushFront(variable); - + if ((variable->mIsExtern) && (variable->mLinkName != NULL)) - mStaticVariables.push_back(variable); - } - break; + mStaticVariables.push_back(variable); + } + break; case S_GTHREAD32: case S_LTHREAD32: { - if ((IsObjectFile()) || (curSubprogram != NULL)) + if ((IsObjectFile()) || (curSubprogram != NULL)) { auto linkedModule = GetLinkedModule(); THREADSYM32& dataSym = *(THREADSYM32*)dataStart; @@ -2563,7 +2570,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD variable->mLocationLen = 1; variable->mIsStatic = true; variable->mCompileUnit = mMasterCompileUnit; - variable->mName = name; + variable->mName = name; if (targetType == mMasterCompileUnit->mGlobalType) variable->mLinkName = name; variable->mIsExtern = symType == S_GTHREAD32; @@ -2578,19 +2585,19 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD auto newPtr = mAlloc.Alloc(); memcpy(newPtr, variable->mLocationData, sizeof(DATASYM32)); variable->mLocationData = (uint8*)newPtr; - } + } if (variable->mName != NULL) blockStack.back()->mVariables.PushBack(variable); break; } - //variable->mCompileUnit = m; + //variable->mCompileUnit = m; // Push front so we will find before the original static declaration (that has no memory associated with it) targetType->mMemberList.PushFront(variable); if ((variable->mIsExtern) && (variable->mLinkName != NULL)) mStaticVariables.push_back(variable); - } + } } break; case S_GPROC32: @@ -2600,24 +2607,24 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { BF_ASSERT(curSubprogram == NULL); - PROCSYM32* procSym = (PROCSYM32*)dataStart; + PROCSYM32* procSym = (PROCSYM32*)dataStart; DbgType* parentType = NULL; auto addr = GetSectionAddr(procSym->seg, procSym->off); - + DbgSubprogram* subprogram = NULL; - if (procSym->typind != 0) - { + if (procSym->typind != 0) + { bool ipi = false; - if ((!IsObjectFile()) && + if ((!IsObjectFile()) && ((symType == S_GPROC32_ID) || (symType == S_LPROC32_ID))) { if (!mCvIPIReader.IsSetup()) CvParseIPI(); ipi = true; - } - subprogram = CvParseMethod(parentType, NULL, procSym->typind, ipi); + } + subprogram = CvParseMethod(parentType, NULL, procSym->typind, ipi); } if (subprogram == NULL) @@ -2628,9 +2635,9 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD subprogram->mTagIdx = (int)(dataEnd - sectionData); // Position for method data subprogram->mIsOptimized = isOptimized; - subprogram->mCompileUnit = compileUnit; + subprogram->mCompileUnit = compileUnit; char* name = DbgDupString((const char*)procSym->name, "DbgDupString.S_GPROC32"); - + if (procSym->flags.CV_PFLAG_OPTDBGINFO) { subprogram->mIsOptimized = true; @@ -2666,23 +2673,23 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD subprogram->mCheckedKind = BfCheckedKind_Unchecked; *cPtr = NULL; break; - } + } } } - + subprogram->mPrologueSize = procSym->DbgStart; subprogram->mBlock.mLowPC = addr; subprogram->mBlock.mHighPC = subprogram->mBlock.mLowPC + (int32)procSym->len; BF_ASSERT(procSym->len >= 0); MapSubprogram(subprogram); - + curSubprogram = subprogram; curParam = subprogram->mParams.mHead; curRegRelVariable = curParam; blockStack.push_back(&subprogram->mBlock); //OutputDebugStrF("Func: %s\n", subprogram->mName); - + if (hasColon) { subprogram->mName = name; @@ -2694,7 +2701,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD subprogram->mName = name; compileUnit->mGlobalType->mMethodList.PushBack(curSubprogram); } - + BF_ASSERT(unrangedIdx == -1); } break; @@ -2704,9 +2711,9 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD DbgType* parentType = NULL; - DbgSubprogram* subprogram; + DbgSubprogram* subprogram; BP_ALLOC_T(DbgSubprogram); - subprogram = mAlloc.Alloc(); + subprogram = mAlloc.Alloc(); subprogram->mCompileUnit = compileUnit; subprogram->mHasQualifiedName = true; subprogram->mName = DbgDupString((const char*)thunkSym.name, "DbgDupString.S_THUNK32"); @@ -2717,7 +2724,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD BF_ASSERT(thunkSym.len >= 0); MapSubprogram(subprogram); - + curSubprogram = subprogram; curParam = subprogram->mParams.mHead; blockStack.push_back(&subprogram->mBlock); @@ -2734,7 +2741,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD deferBlockDepth++; break; } - + BP_ALLOC_T(DbgBlock); DbgBlock* block = mAlloc.Alloc(); blockStack.back()->mSubBlocks.PushBack(block); @@ -2748,7 +2755,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; case S_FRAMEPROC: { - FRAMEPROCSYM* frameProc = (FRAMEPROCSYM*)dataStart; + FRAMEPROCSYM* frameProc = (FRAMEPROCSYM*)dataStart; if (curSubprogram != NULL) { // if ((curSubprogram->mName != NULL) && (strcmp(curSubprogram->mName, "_bf::IDETest::HotTester::TestFuncs") == 0)) @@ -2774,7 +2781,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD _NextUnrangedLocalVar(name, varType); localVar->mName = name; - localVar->mCompileUnit = compileUnit; + localVar->mCompileUnit = compileUnit; localVar->mType = varType; // This is location data now, not just a S_LOCAL opener //prevLocalVar = localVar; @@ -2785,14 +2792,14 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { if (deferInternals) break; - REGSYM* regSym = (REGSYM*)dataStart; + REGSYM* regSym = (REGSYM*)dataStart; const char* name = DbgDupString((const char*)regSym->name); DbgType* varType = CvGetTypeSafe(regSym->typind); _NextUnrangedLocalVar(name, varType); localVar->mName = name; - localVar->mCompileUnit = compileUnit; + localVar->mCompileUnit = compileUnit; localVar->mType = varType; // This is location data now, not just a S_LOCAL opener //prevLocalVar = localVar; @@ -2805,12 +2812,12 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; REGREL32* regRel32 = (REGREL32*)dataStart; const char* name = DbgDupString((const char*)regRel32->name); - DbgType* varType = CvGetTypeSafe(regRel32->typind); + DbgType* varType = CvGetTypeSafe(regRel32->typind); _NextUnrangedLocalVar(name, varType); localVar->mName = name; - localVar->mCompileUnit = compileUnit; + localVar->mCompileUnit = compileUnit; if ((localVar->mType != NULL) && (!localVar->mType->IsPointer()) && (varType != NULL) && (varType->IsPointer())) localVar->mSigNoPointer = true; localVar->mType = varType; @@ -2819,7 +2826,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD newLocalVarHasLocData = true; } break; - case S_LOCAL: + case S_LOCAL: { if (deferInternals) break; @@ -2828,7 +2835,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD LOCALSYM& localSym = *(LOCALSYM*)dataStart; char* name = DbgDupString((const char*)localSym.name); - + bool isConst = false; int64 constVal = 0; if ((compileUnit->mLanguage == DbgLanguage_Beef) && (name != NULL) && (name[0] != '$')) @@ -2844,7 +2851,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { cPtr[1] = '-'; isConst = true; - constVal = atoll(cPtr + 1); + constVal = atoll(cPtr + 1); *cPtr = 0; } else if ((cPtr[1] >= '0') && (cPtr[1] <= '9')) @@ -2853,22 +2860,22 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD constVal = atoll(cPtr + 1); *cPtr = 0; } - } + } } } - + if ((name != NULL) && (name[0] == '#')) { if (strcmp(name + 1, "StepOver") == 0) { curSubprogram->mIsStepFilteredDefault = true; - } + } localVar = NULL; break; - } + } - DbgType* varType = CvGetType(localSym.typind, cvCompileUnit); + DbgType* varType = CvGetType(localSym.typind, cvCompileUnit); if (varType == NULL) varType = CvGetType(T_VOID); @@ -2891,11 +2898,11 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD bool handledLocalVar = false; if (curParam != NULL) - { + { if ((name != NULL) && (name[0] == '$')) { int strLen = strlen(name); - + // Splat head const char* dollarPos = strchr(name + 1, '$'); const char* nameStr = name + 1; @@ -2919,7 +2926,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { // Type was different, probably from a 'ref' being added when we are passing composites curParam->mName = name; - curParam = curParam->mNext; + curParam = curParam->mNext; } else { @@ -2932,13 +2939,13 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD if (!handledLocalVar) { BP_ALLOC_T(DbgVariable); - localVar = mAlloc.Alloc(); + localVar = mAlloc.Alloc(); if (name != NULL) blockStack.back()->mVariables.PushBack(localVar); } localVar->mName = name; - localVar->mCompileUnit = compileUnit; + localVar->mCompileUnit = compileUnit; localVar->mType = varType; localVar->mIsConst = isConst; localVar->mConstValue = constVal; @@ -2954,22 +2961,22 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; DEFRANGESYMREGISTER& defRangeReg = *(DEFRANGESYMREGISTER*)dataStart; if (localVar != NULL) - MapRanges(localVar, &defRangeReg.range, defRangeReg.gaps); + MapRanges(localVar, &defRangeReg.range, defRangeReg.gaps); } - break; + break; case S_DEFRANGE_FRAMEPOINTER_REL: { if (deferInternals) break; - DEFRANGESYMFRAMEPOINTERREL& defRangeFPRel = *(DEFRANGESYMFRAMEPOINTERREL*)dataStart; - MapRanges(localVar, &defRangeFPRel.range, defRangeFPRel.gaps); + DEFRANGESYMFRAMEPOINTERREL& defRangeFPRel = *(DEFRANGESYMFRAMEPOINTERREL*)dataStart; + MapRanges(localVar, &defRangeFPRel.range, defRangeFPRel.gaps); } break; case S_DEFRANGE_SUBFIELD_REGISTER: { if (deferInternals) break; - DEFRANGESYMSUBFIELDREGISTER& defRangeSubFieldReg = *(DEFRANGESYMSUBFIELDREGISTER*)dataStart; + DEFRANGESYMSUBFIELDREGISTER& defRangeSubFieldReg = *(DEFRANGESYMSUBFIELDREGISTER*)dataStart; } break; case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: @@ -2985,7 +2992,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; DEFRANGESYMREGISTERREL& defRangeRegRel = *(DEFRANGESYMREGISTERREL*)dataStart; if (localVar != NULL) - MapRanges(localVar, &defRangeRegRel.range, defRangeRegRel.gaps); + MapRanges(localVar, &defRangeRegRel.range, defRangeRegRel.gaps); } break; case S_ENDARG: @@ -2995,8 +3002,8 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; case S_END: case S_PROC_ID_END: - if (deferBlockDepth > 0) - --deferBlockDepth; + if (deferBlockDepth > 0) + --deferBlockDepth; else blockStack.pop_back(); BF_ASSERT(blockStack.size() > 0); @@ -3021,18 +3028,17 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD inlineDebugDump = false; curSubprogram = NULL; - curParam = NULL; - + curParam = NULL; } break; case S_COMPILE2: { - COMPILESYM* compileSym = (COMPILESYM*)dataStart; + COMPILESYM* compileSym = (COMPILESYM*)dataStart; } break; case S_COMPILE3: { - COMPILESYM3* compileSym = (COMPILESYM3*)dataStart; + COMPILESYM3* compileSym = (COMPILESYM3*)dataStart; } break; case S_ENVBLOCK: @@ -3049,7 +3055,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; case S_BUILDINFO: { - CV_ItemId buildInfoId = GET(CV_ItemId); + CV_ItemId buildInfoId = GET(CV_ItemId); } break; case S_TRAMPOLINE: @@ -3060,48 +3066,48 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; case S_FRAMECOOKIE: { - FRAMECOOKIE& frameCookie = *(FRAMECOOKIE*)dataStart; + FRAMECOOKIE& frameCookie = *(FRAMECOOKIE*)dataStart; } break; case S_LABEL32: { - LABELSYM32& labelSym = *(LABELSYM32*)dataStart; + LABELSYM32& labelSym = *(LABELSYM32*)dataStart; } break; case S_CALLSITEINFO: { - CALLSITEINFO& callSiteInfo = *(CALLSITEINFO*)dataStart; + CALLSITEINFO& callSiteInfo = *(CALLSITEINFO*)dataStart; } break; case S_HEAPALLOCSITE: { - HEAPALLOCSITE& heapAllocSite = *(HEAPALLOCSITE*)dataStart; + HEAPALLOCSITE& heapAllocSite = *(HEAPALLOCSITE*)dataStart; } break; case S_FILESTATIC: { - FILESTATICSYM& fileStaticSym = *(FILESTATICSYM*)dataStart; + FILESTATICSYM& fileStaticSym = *(FILESTATICSYM*)dataStart; } break; case S_CALLEES: { - FUNCTIONLIST& calleeList = *(FUNCTIONLIST*)dataStart; + FUNCTIONLIST& calleeList = *(FUNCTIONLIST*)dataStart; } break; case S_CALLERS: { - FUNCTIONLIST& calleeList = *(FUNCTIONLIST*)dataStart; + FUNCTIONLIST& calleeList = *(FUNCTIONLIST*)dataStart; } break; case S_POGODATA: { - POGOINFO& pogoInfo = *(POGOINFO*)dataStart; + POGOINFO& pogoInfo = *(POGOINFO*)dataStart; } break; - + case S_INLINESITE: case S_INLINESITE2: - { + { if (useSubprogram != NULL) { deferInlineDepth++; @@ -3110,7 +3116,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD uint32 inlinee; uint8* binaryAnnotations; - + if (symType == S_INLINESITE) { INLINESITESYM& inlineSite = *(INLINESITESYM*)dataStart; @@ -3123,13 +3129,13 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD inlinee = inlineSite.inlinee; binaryAnnotations = (uint8*)&inlineSite.binaryAnnotations; } - + DbgSubprogram* inlineParent = curSubprogram; DbgSubprogram* subprogram = NULL; if (IsObjectFile()) { subprogram = CvParseMethod(NULL, NULL, inlinee, false); - subprogram->mCompileUnit = compileUnit; + subprogram->mCompileUnit = compileUnit; curSubprogram = subprogram; } else if ((inlinee & 0x80000000) != 0) @@ -3137,7 +3143,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD BP_ALLOC_T(DbgSubprogram); subprogram = mAlloc.Alloc(); // ?? subprogram->mCompileUnit = compileUnit; - + if (!mCvIPIReader.IsSetup()) CvParseIPI(); @@ -3148,7 +3154,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD BP_ALLOC_T(DbgSubprogram); subprogram = mAlloc.Alloc(); - subprogram->mCompileUnit = compileUnit; + subprogram->mCompileUnit = compileUnit; curSubprogram = subprogram; FixupInlinee(curSubprogram, inlinee); @@ -3176,7 +3182,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD String name = StrFormat("@%@", curSubprogram); curSubprogram->mName = DbgDupString(name.c_str());*/ - + String name = StrFormat("@%@", curSubprogram); curSubprogram->mName = DbgDupString(name.c_str()); @@ -3185,12 +3191,12 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD if (inlineDebugDump) { - int depth = curSubprogram->GetInlineDepth(); - BfLogCv("S_INLINESITE Ofs:%d Depth:%d Inlinee:%X Subprogram:%@ %s\n Parent:%@ %s\n", (dataStart - symDataStart), depth, inlinee, + int depth = curSubprogram->GetInlineDepth(); + BfLogCv("S_INLINESITE Ofs:%d Depth:%d Inlinee:%X Subprogram:%@ %s\n Parent:%@ %s\n", (dataStart - symDataStart), depth, inlinee, curSubprogram, curSubprogram->mName, curSubprogram->mInlineeInfo->mInlineParent, curSubprogram->mInlineeInfo->mInlineParent->mName); } - CvInlineInfo inlineInfo; + CvInlineInfo inlineInfo; inlineInfo.mNext = NULL; inlineInfo.mTail = NULL; inlineInfo.mInlinee = inlinee; @@ -3220,17 +3226,17 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD curSubprogram->mDeferredInternalsSize = endOffset - curSubprogram->mTagIdx; } - curSubprogram = curSubprogram->mInlineeInfo->mInlineParent; + curSubprogram = curSubprogram->mInlineeInfo->mInlineParent; blockStack.pop_back(); } } break; case S_SSEARCH: { - SEARCHSYM* searchSym = (SEARCHSYM*)dataStart; + SEARCHSYM* searchSym = (SEARCHSYM*)dataStart; } break; - case S_SEPCODE: + case S_SEPCODE: { BP_ALLOC_T(DbgSubprogram); curSubprogram = mAlloc.Alloc(); @@ -3258,11 +3264,11 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD break; case S_UNAMESPACE: break; - case /*S_FASTLINK*/0x1167: + case /*S_FASTLINK*/0x1167: break; - case /*S_INLINEES*/0x1168: + case /*S_INLINEES*/0x1168: break; - case 0x1176: + case 0x1176: break; case 0x1178: break; @@ -3278,7 +3284,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD bool hasNewLocalVar = (localVar != prevLocalVar) && (localVar != NULL); if (newLocalVarHasLocData) - { + { prevLocalVar = localVar; } @@ -3297,9 +3303,9 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { if (prevLocalVar != NULL) { - /*if (localVar->mLocationData == NULL) + /*if (localVar->mLocationData == NULL) localVar->mLocationData = dataStart; - localVar->mLocationLen++;*/ + localVar->mLocationLen++;*/ if (locationDataStart == NULL) locationDataStart = dataStart; locationDataEnd = dataEnd; @@ -3322,7 +3328,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD // to the same memory location, which can happen during mixin injection. The result is that the mixin gets // some premature instructions attributed to it from the variable declaration. This fixes that. if ((aliasPos != NULL) && (aliasPos > localVar->mName)) - { + { String findName = String(aliasPos + 7); localVar->mName = CvDupString(localVar->mName + 1, aliasPos - localVar->mName - 1); @@ -3334,7 +3340,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD /*bool found = false; auto _CheckBlock = [&](DbgBlock* block) - { + { for (auto checkVar : block->mVariables) { if (checkVar->mName == NULL) @@ -3352,15 +3358,14 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD } return false; - }; for (int blockIdx = (int)blockStack.size() - 1; blockIdx >= 0; blockIdx--) { - DbgBlock* block = blockStack[blockIdx]; - if (_CheckBlock(block)) - break; - } + DbgBlock* block = blockStack[blockIdx]; + if (_CheckBlock(block)) + break; + } if (!found) { @@ -3379,7 +3384,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD if ((checkAddr < block->mLowPC) || (checkAddr >= block->mHighPC)) return; - if (_CheckBlock(block)) + if (_CheckBlock(block)) return; for (auto block : block->mSubBlocks) @@ -3389,7 +3394,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD _RecurseBlock(&checkSubprogram->mBlock); } }*/ - } + } } if ((compileUnit->mLanguage != DbgLanguage_Beef) && (localVar->mName != NULL)) @@ -3409,10 +3414,9 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD { BF_ASSERT(locationDataCount == prevLocalVar->mLocationLen); }*/ - data = dataEnd; - //PTR_ALIGN(data, sectionData, 4); + //PTR_ALIGN(data, sectionData, 4); } if (localVar != NULL) @@ -3460,8 +3464,8 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c { compileUnit->mModuleIdx = NULL; compileUnit->mName = mFilePath.c_str(); - } - + } + uint8* data = sectionData; uint8* dataEnd = NULL; @@ -3472,15 +3476,15 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c uint8* debugSubSectionsStart = data; if (moduleInfo != NULL) - { - taggedSize = moduleInfo->mLinesBytes; + { + taggedSize = moduleInfo->mLinesBytes; debugSubSectionsStart = data + moduleInfo->mSymbolBytes - sizeof(uint32); } else { taggedSize = sectionSize - sizeof(uint32); - } - + } + if (mStringTable.mStrTable == NULL) { data = debugSubSectionsStart; @@ -3496,7 +3500,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c { if (mStringTable.mStrTable == NULL) mStringTable.mStrTable = (const char*)data; - } + } data = dataEnd; } } @@ -3527,7 +3531,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c crossScopeImport.mScopeName = fileName; // - /*for (int checkIdx = 0; checkIdx < (int)mCvModuleInfo.size(); checkIdx++) + /*for (int checkIdx = 0; checkIdx < (int)mCvModuleInfo.size(); checkIdx++) { auto checkModuleInfo = mCvModuleInfo[checkIdx]; if ((checkModuleInfo != NULL) && (checkModuleInfo->mModuleName != NULL) && (stricmp(checkModuleInfo->mModuleName, fileName) == 0)) @@ -3568,7 +3572,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c else if (lineInfoType == DEBUG_S_FRAMEDATA) { uint8* dataPtr = data; - addr_target baseAddr = 0; + addr_target baseAddr = 0; int relAddr = GET_FROM(dataPtr, int32); ParseFrameDescriptors(dataPtr, dataEnd - dataPtr, GetLinkedModule()->mImageBase + relAddr); } @@ -3584,7 +3588,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c ParseCompileUnit_Symbols(compileUnit, sectionData, data, dataEnd, inlineDataVec, wantsDeferInternals, NULL); //ParseCompileUnit_Symbols(compileUnit, sectionData, data, dataEnd, inlineDataVec, false, NULL); data = dataEnd; - } + } // Scan debug subsections to find file checksum table, and to load symbol data for hotloads Dictionary checksumFileRefs; @@ -3610,7 +3614,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c else if (lineInfoType == DEBUG_S_SYMBOLS) { ParseCompileUnit_Symbols(compileUnit, sectionData, data, dataEnd, inlineDataVec, false, NULL); - } + } else if (lineInfoType == DEBUG_S_FILECHKSMS) { BF_ASSERT(checksumFileRefs.size() == 0); @@ -3620,7 +3624,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c int dataOfs = (int)(data - dataStart); GET_INTO(uint, fileTableOfs); - + const char* fileName = mStringTable.mStrTable + fileTableOfs; if ((fileName[0] == '\\') && (fileName[1] == '$')) @@ -3631,9 +3635,9 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c if (fileName[0] == '$') { srcFile = AddSrcFile(compileUnit, fileName); - } + } else if ((fileName[0] == '/') || (fileName[0] == '\\') || - ((fileName[0] != 0) && (fileName[1] == ':'))) + ((fileName[0] != 0) && (fileName[1] == ':'))) { srcFile = AddSrcFile(compileUnit, fileName); } @@ -3659,12 +3663,12 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c srcFile->mHashKind = DbgHashKind_SHA256; memcpy(srcFile->mHash, data, 32); } - + data += hashLen; checksumFileRefs.TryAdd(dataOfs, (int)compileUnit->mSrcFileRefs.size() - 1); PTR_ALIGN(data, sectionData, 4); } - } + } else { BF_ASSERT((lineInfoType >= DEBUG_S_SYMBOLS) && (lineInfoType <= DEBUG_S_COFF_SYMBOL_RVA)); @@ -3693,12 +3697,12 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c } } int inlineDataIdx = 0; - + DbgLineDataBuilder lineBuilder(this); // { - BP_ZONE("ParseCompileUnit_LineInfo"); + BP_ZONE("ParseCompileUnit_LineInfo"); //int totalLineCount = 0; //int targetLineCount = 0; @@ -3710,16 +3714,16 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c // bool mWantSummaryDump; // Array mInlinees; // Array mInlineLineData; -// +// // _InlinerData() // { // mWantSummaryDump = false; // } // }; -// +// // Dictionary deferredInlinerDatas; - // Line info + // Line info data = debugSubSectionsStart; dataEnd = data + taggedSize; while (data < dataEnd) @@ -3739,13 +3743,13 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c CV_DebugSLinesHeader_t& lineSec = GET(CV_DebugSLinesHeader_t); Array lineDataVec; - + addr_target contribStartAddr = GetSectionAddr(lineSec.segCon, lineSec.offCon); while (data < dataEnd) { lineDataVec.Clear(); - + CV_DebugSLinesFileBlockHeader_t& linesFileHeader = GET(CV_DebugSLinesFileBlockHeader_t); DbgSrcFileReference* srcFileRef = &compileUnit->mSrcFileRefs[checksumFileRefs[linesFileHeader.offFile]]; bool isBeef = srcFileRef->mSrcFile->IsBeef(); @@ -3761,7 +3765,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c CV_Line_t& srcLineData = GET(CV_Line_t); DbgLineData& lineData = lineDataVec[lineIdx]; - lineData.mRelAddress = (uint32)((contribStartAddr + srcLineData.offset) - mImageBase); + lineData.mRelAddress = (uint32)((contribStartAddr + srcLineData.offset) - mImageBase); if (srcLineData.linenumStart == 0xf00f00) // Never step into { @@ -3777,7 +3781,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c } else lineData.mLine = srcLineData.linenumStart - 1; - + // In Beef we always set the column, so a section without CV_LINES_HAVE_COLUMNS indicates a block of invalid // positions that we want to skip over if (isBeef) @@ -3798,16 +3802,16 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c DbgLineData* lastLineData = NULL; for (int lineIdx = 0; lineIdx < linesFileHeader.nLines; lineIdx++) { - DbgLineData& lineData = lineDataVec[lineIdx]; + DbgLineData& lineData = lineDataVec[lineIdx]; lastLineData = lineBuilder.Add(compileUnit, lineData, srcFileRef->mSrcFile, NULL); - } + } } } else if (lineInfoType == DEBUG_S_INLINEELINES) - { + { int linesType = GET(int); while (data < dataEnd) - { + { int inlinee = 0; int srcFileIdx = -1; int startLine; @@ -3819,7 +3823,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c srcFileIdx = checksumFileRefs[lineInfo.fileId]; startSrcFileRef = &compileUnit->mSrcFileRefs[srcFileIdx]; startLine = lineInfo.sourceLineNum; - inlinee = lineInfo.inlinee; + inlinee = lineInfo.inlinee; } else if (linesType == 1) { @@ -3834,12 +3838,12 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c } else BF_FATAL("Invalid DEBUG_S_INLINEELINES lines type"); - + CvInlineInfo* inlineData = NULL; inlineDataDict.TryGetValue(inlinee, &inlineData); - + while (inlineData != NULL) - { + { bool inlineDebugDump = inlineData->mDebugDump; if (inlineData->mInlinee == -1) @@ -3852,30 +3856,29 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c // Mark as done inlineData->mInlinee = -1; - int chunkNum = 0; - int curLine = startLine; - int curValidLine = curLine; + int chunkNum = 0; + int curLine = startLine; + int curValidLine = curLine; bool flushOnLineOffset = false; addr_target lastLineAddr = 0; - DbgSrcFileReference* srcFileRef = startSrcFileRef; DbgSubprogram* curSubprogram = inlineData->mSubprogram; - + DbgSubprogram* inlineParent = inlineData->mSubprogram->GetRootInlineParent(); - + addr_target curAddr = inlineParent->mBlock.mLowPC; lastLineAddr = 0; if (inlineDebugDump) { //inlinerData->mWantSummaryDump = true; - BfLogCv("------------------------------------------------\nINLINE DATA:%X Idx:%d CurAddr:%@ Line:%d\n SubProgram:%@ %s\n File:%s\n", inlinee, inlineIdx, curAddr, curLine, + BfLogCv("------------------------------------------------\nINLINE DATA:%X Idx:%d CurAddr:%@ Line:%d\n SubProgram:%@ %s\n File:%s\n", inlinee, inlineIdx, curAddr, curLine, curSubprogram, curSubprogram->mName, srcFileRef->mSrcFile->mFilePath.c_str()); } uint8* annData = inlineData->mData; - uint8* annDataEnd = inlineData->mData + inlineData->mDataLen; + uint8* annDataEnd = inlineData->mData + inlineData->mDataLen; DbgLineData* curLineData = NULL; @@ -3887,34 +3890,33 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c return; } - DbgLineData lineData; - lineData.mLine = curValidLine - 1; + DbgLineData lineData; + lineData.mLine = curValidLine - 1; lineData.mRelAddress = (uint32)(curAddr - mImageBase); lineData.mColumn = 0; if (curLine <= 0) // Negative lines mean "invalid position" for inlining - lineData.mColumn = -1; + lineData.mColumn = -1; lineData.mContribSize = 0; - + if ((curSubprogram->mBlock.mLowPC == 0) && (curLineData != NULL)) - curSubprogram->mBlock.mLowPC = mImageBase + curLineData->mRelAddress; + curSubprogram->mBlock.mLowPC = mImageBase + curLineData->mRelAddress; if (inlineDebugDump) BfLogCv(" Adding Line:%d Addr:%@\n", lineData.mLine + 1, lineData.mRelAddress + mImageBase); curLineData = lineBuilder.Add(compileUnit, lineData, srcFileRef->mSrcFile, curSubprogram); - }; int codeIdx = 0; while (annData < annDataEnd) - { + { auto annVal = CodeViewInfo::CVUncompressData(annData); - + switch (annVal) { case CodeViewInfo::BA_OP_Invalid: // link time pdb contains PADDINGs break; - case CodeViewInfo::BA_OP_CodeOffset: // param : start offset + case CodeViewInfo::BA_OP_CodeOffset: // param : start offset { int32 offset = (int32)CodeViewInfo::CVUncompressData(annData); curAddr = inlineParent->mBlock.mLowPC + offset; @@ -3924,17 +3926,17 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c break; case CodeViewInfo::BA_OP_ChangeCodeOffsetBase: // param : nth separated code chunk (main code chunk == 0) { - chunkNum = (int32)CodeViewInfo::CVUncompressData(annData); + chunkNum = (int32)CodeViewInfo::CVUncompressData(annData); if (inlineDebugDump) - BfLogCv("xxxxxxxxx BA_OP_ChangeCodeOffsetBase(%d) CurAddr:%@ Line:%d\n", chunkNum, curAddr, curLine); + BfLogCv("xxxxxxxxx BA_OP_ChangeCodeOffsetBase(%d) CurAddr:%@ Line:%d\n", chunkNum, curAddr, curLine); } break; case CodeViewInfo::BA_OP_ChangeCodeOffset: // param : delta of offset { int32 offset = (int32)CodeViewInfo::CVUncompressData(annData); - - curAddr += offset; + + curAddr += offset; if (inlineDebugDump) BfLogCv(" BA_OP_ChangeCodeOffset(%d) CurAddr:%@ Line:%d\n", offset, curAddr, curLine); @@ -3946,7 +3948,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c } else _AddLine(); - + flushOnLineOffset = true; } break; @@ -3959,10 +3961,10 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c curLineData->mContribSize = newCodeLen; if (inlineDebugDump) - BfLogCv(" BA_OP_ChangeCodeLength(%d) Addr:%@ EndAddr:%@\n", newCodeLen, curLineData->mRelAddress + mImageBase, curLineData->mRelAddress + mImageBase + curLineData->mContribSize); + BfLogCv(" BA_OP_ChangeCodeLength(%d) Addr:%@ EndAddr:%@\n", newCodeLen, curLineData->mRelAddress + mImageBase, curLineData->mRelAddress + mImageBase + curLineData->mContribSize); } break; - case CodeViewInfo::BA_OP_ChangeFile: // param : fileId + case CodeViewInfo::BA_OP_ChangeFile: // param : fileId { uint32 newFileId = CodeViewInfo::CVUncompressData(annData); srcFileRef = &compileUnit->mSrcFileRefs[checksumFileRefs[newFileId]]; @@ -3976,7 +3978,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c int32 lineOfs = (int32)CodeViewInfo::DecodeSignedInt32(CodeViewInfo::CVUncompressData(annData)); curLine += lineOfs; if (curLine > 0) - curValidLine = curLine; + curValidLine = curLine; if (inlineDebugDump) BfLogCv(" BA_OP_ChangeLineOffset(%d) CurAddr:%@ Line:%d\n", lineOfs, curAddr, curLine); @@ -3992,7 +3994,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c BfLogCv(" BA_OP_ChangeLineEndDelta(%d) CurAddr:%@ Line:%d\n", numLines, curAddr, curLine); } break; - case CodeViewInfo::BA_OP_ChangeRangeKind: // param : either 1 (default, for statement) or 0 (for expression) + case CodeViewInfo::BA_OP_ChangeRangeKind: // param : either 1 (default, for statement) or 0 (for expression) { int32 readKind = (int32)CodeViewInfo::CVUncompressData(annData); if (inlineDebugDump) @@ -4021,11 +4023,11 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c int offsetData = (int32)CodeViewInfo::CVUncompressData(annData); int codeDelta = offsetData & 0xF; int sourceDelta = CodeViewInfo::DecodeSignedInt32(offsetData >> 4); - + curAddr += codeDelta; curLine += sourceDelta; if (curLine > 0) - curValidLine = curLine; + curValidLine = curLine; if (inlineDebugDump) BfLogCv(" BA_OP_ChangeCodeOffsetAndLineOffset(%d, %d) CurAddr:%@ Line:%d\n", codeDelta, sourceDelta, curAddr, curLine); @@ -4040,7 +4042,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c int codeOffset = (int32)CodeViewInfo::CVUncompressData(annData); curAddr += codeOffset; - + if (inlineDebugDump) BfLogCv(" BA_OP_ChangeCodeLengthAndCodeOffset(%d, %d) CurAddr:%@ Line:%d\n", codeLen, codeOffset, curAddr, curLine); @@ -4085,19 +4087,19 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c // { // auto inlinerParent = deferredInlinerDataKV.mKey; // auto deferredInlinerData = &deferredInlinerDataKV.mValue; -// +// // inlinerParent->mInlinerData = mAlloc.Alloc(); // inlinerParent->mInlinerData->mInlinees.CopyFrom(deferredInlinerData->mInlinees.mVals, deferredInlinerData->mInlinees.mSize, mAlloc); // inlinerParent->mInlinerData->mInlineLineData.CopyFrom(deferredInlinerData->mInlineLineData.mVals, deferredInlinerData->mInlineLineData.mSize, mAlloc); // //deferredInlinerData-> -// +// // if (deferredInlinerData->mWantSummaryDump) // { // BfLogCv("------------------------------\nSUMMARY FOR: %s\n", inlinerParent->mName); -// +// // for (auto& inlineLine : inlinerParent->mInlinerData->mInlineLineData) -// { -// BfLogCv("Addr:%@ EndAddr:%@ Line:%d Column:%d Inlinee:%d\n", inlineLine.mAddress, inlineLine.mAddress + inlineLine.mContribSize, +// { +// BfLogCv("Addr:%@ EndAddr:%@ Line:%d Column:%d Inlinee:%d\n", inlineLine.mAddress, inlineLine.mAddress + inlineLine.mContribSize, // inlineLine.mLine + 1, inlineLine.mColumn + 1, inlineLine.mInlineIdx); // } // } @@ -4106,8 +4108,7 @@ CvCompileUnit* COFF::ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* c lineBuilder.Commit(); - - //OutputDebugStrF("Module loaded, AllocSize added: %d\n", (mAlloc.GetAllocSize() - allocSizeStart) / 1024); + //OutputDebugStrF("Module loaded, AllocSize added: %d\n", (mAlloc.GetAllocSize() - allocSizeStart) / 1024); return compileUnit; } @@ -4118,7 +4119,7 @@ CvCompileUnit* COFF::ParseCompileUnit(int compileUnitId) return moduleInfo->mCompileUnit; BP_ZONE("ParseCompileUnit"); - + ParseTypeData(); if (moduleInfo->mStream == -1) @@ -4151,7 +4152,7 @@ DbgType* COFF::CvGetTypeOrNamespace(char* name, DbgLanguage language) language = DbgLanguage_Beef; } else - { + { language = DbgLanguage_C; // Check for a primitive array type like 'double[]' @@ -4176,7 +4177,7 @@ DbgType* COFF::CvGetTypeOrNamespace(char* name, DbgLanguage language) return dbgType->mHotNewType; return dbgType; } - + // It's possible that we get a reference to a template name that isn't actually in our type database // These may indicate VS compiler bugs or anonymous namespaces bool isValidName = true; @@ -4189,12 +4190,12 @@ DbgType* COFF::CvGetTypeOrNamespace(char* name, DbgLanguage language) //OutputDebugStrF("CvGetTypeOrNamespace Creating: %s\n", name); char* lastDblColon = (char*)GetLastDoubleColon(name); - + DbgType* dbgType = CvCreateType(); DbgType* parentType = mMasterCompileUnit->mGlobalType; if (lastDblColon != NULL) - { + { *lastDblColon = 0; parentType = CvGetTypeOrNamespace(name, language); dbgType->mTypeName = DbgDupString(lastDblColon + 2, "DbgDupString.TypeOrNamespace0"); @@ -4204,9 +4205,9 @@ DbgType* COFF::CvGetTypeOrNamespace(char* name, DbgLanguage language) else { dbgType->mTypeName = DbgDupString(name, "DbgDupString.TypeOrNamespace2"); - dbgType->mName = dbgType->mTypeName; - } - + dbgType->mName = dbgType->mTypeName; + } + parentType->mSubTypeList.PushBack(dbgType); dbgType->mTypeCode = DbgType_Namespace; dbgType->mLanguage = language; @@ -4222,14 +4223,14 @@ void COFF::MapCompileUnitMethods(DbgCompileUnit* compileUnit) DbgSubprogram* prevDbgMethod = NULL; DbgSubprogram* dbgMethod = compileUnit->mOrphanMethods.mHead; while (dbgMethod != NULL) - { - auto nextDbgMethod = dbgMethod->mNext; + { + auto nextDbgMethod = dbgMethod->mNext; bool movedMethod = false; if (dbgMethod->mHasQualifiedName) { char* name = (char*)dbgMethod->mName; char* lastDblColon = (char*)GetLastDoubleColon(name); - + if (lastDblColon != NULL) { dbgMethod->mName = lastDblColon + 2; @@ -4244,7 +4245,7 @@ void COFF::MapCompileUnitMethods(DbgCompileUnit* compileUnit) { mHotPrimaryTypes.Add(parentType); } - + compileUnit->mOrphanMethods.Remove(dbgMethod, prevDbgMethod); parentType->mMethodList.PushBack(dbgMethod); dbgMethod->mParentType = parentType; @@ -4280,7 +4281,7 @@ void COFF::PopulateType(DbgType* dbgType) CvAutoReleaseTempData releaseTempData(this, data); uint8* dataStart = data; - uint16 trLeafType = GET(uint16); + uint16 trLeafType = GET(uint16); switch (trLeafType) { @@ -4291,7 +4292,7 @@ void COFF::PopulateType(DbgType* dbgType) } break; case LF_CLASS: - case LF_STRUCTURE: + case LF_STRUCTURE: { lfClass& classInfo = *(lfClass*)dataStart; CvParseMembers(dbgType, classInfo.field, false); @@ -4307,10 +4308,10 @@ void COFF::PopulateType(DbgType* dbgType) CvParseMembers(dbgType, field, false); } break; - + case LF_UNION: { - lfUnion& classInfo = *(lfUnion*)dataStart; + lfUnion& classInfo = *(lfUnion*)dataStart; CvParseMembers(dbgType, classInfo.field, false); } break; @@ -4320,7 +4321,7 @@ void COFF::PopulateType(DbgType* dbgType) } void COFF::PopulateTypeGlobals(DbgType* dbgType) -{ +{ //gDbgPerfManager->StartRecording(); { @@ -4345,13 +4346,13 @@ void COFF::PopulateSubprogram(DbgSubprogram* dbgSubprogram) BP_ZONE("COFF::PopulateSubprogram"); auto compileUnit = (CvCompileUnit*)dbgSubprogram->mCompileUnit; - CvModuleInfo* moduleInfo = mCvModuleInfo[compileUnit->mModuleIdx]; - + CvModuleInfo* moduleInfo = mCvModuleInfo[compileUnit->mModuleIdx]; + int sectionSize = 0; uint8* sectionData = CvReadStreamSegment(moduleInfo->mStream, dbgSubprogram->mTagIdx, dbgSubprogram->mDeferredInternalsSize); CvInlineInfoVec inlineDataVec; ParseCompileUnit_Symbols(compileUnit, NULL, sectionData, sectionData + dbgSubprogram->mDeferredInternalsSize, inlineDataVec, false, dbgSubprogram); - delete sectionData; + delete sectionData; dbgSubprogram->mDeferredInternalsSize = 0; } @@ -4362,7 +4363,7 @@ void COFF::FixSubprogramName(DbgSubprogram* dbgSubprogram) for (const char* cPtr = name; *cPtr != 0; cPtr++) { - char c = *cPtr; + char c = *cPtr; if (c == '$') { bool isChecked = strcmp(cPtr, "$CHK") == 0; @@ -4372,7 +4373,7 @@ void COFF::FixSubprogramName(DbgSubprogram* dbgSubprogram) dbgSubprogram->mCheckedKind = isChecked ? BfCheckedKind_Checked : BfCheckedKind_Unchecked; dbgSubprogram->mName = CvDupString(name, cPtr - name); return; - } + } } } } @@ -4436,7 +4437,7 @@ void COFF::FixupInlinee(DbgSubprogram* dbgSubprogram, uint32 ipiTag) case LF_MFUNC_ID: { lfMFuncId* funcData = (lfMFuncId*)dataStart; - CvParseMethod(NULL, NULL, funcData->type, false, dbgSubprogram); + CvParseMethod(NULL, NULL, funcData->type, false, dbgSubprogram); dbgSubprogram->mName = (const char*)funcData->name; if (dbgSubprogram->mName != NULL) @@ -4480,7 +4481,7 @@ int COFF::MapImport(CvCompileUnit* compileUnit, int id) { String name = moduleInfo->mModuleName; name = ToUpper(name); - + CvModuleInfoNameEntry entry; entry.mModuleInfo = moduleInfo; mModuleNameSet.Add(entry); @@ -4549,7 +4550,7 @@ int COFF::MapImport(CvCompileUnit* compileUnit, int id) { return exportId; } - } + } } } } @@ -4561,7 +4562,7 @@ void COFF::FixupInlinee(DbgSubprogram* dbgSubprogram) { BF_ASSERT(dbgSubprogram->mInlineeInfo != NULL); BF_ASSERT((dbgSubprogram->mInlineeInfo->mInlineeId & 0x80000000) != 0); - + int scopeIdx = (dbgSubprogram->mInlineeInfo->mInlineeId & 0x7FFF0000) >> 20; int itemId = (dbgSubprogram->mInlineeInfo->mInlineeId & 0x0000FFFF); @@ -4613,7 +4614,7 @@ void COFF::FixupInlinee(DbgSubprogram* dbgSubprogram) } void COFF::PopulateStaticVariableMap() -{ +{ if (mPopulatedStaticVariables) return; @@ -4623,7 +4624,7 @@ void COFF::PopulateStaticVariableMap() { PopulateTypeGlobals(mMasterCompileUnit->mGlobalType); for (auto variable : mMasterCompileUnit->mGlobalType->mMemberList) - { + { if ((variable->mIsExtern) && (variable->mLinkName != NULL)) mStaticVariables.push_back(variable); } @@ -4637,25 +4638,25 @@ void COFF::ScanCompileUnit(int compileUnitId) BP_ZONE("COFF::ScanCompileUnit"); CvModuleInfo* moduleInfo = mCvModuleInfo[compileUnitId]; - + if (moduleInfo->mStream < 0) return; BF_ASSERT(moduleInfo->mSymbolBytes % 4 == 0); - uint8* sectionData = CvReadStreamSegment(moduleInfo->mStream, moduleInfo->mSymbolBytes, moduleInfo->mLinesBytes); + uint8* sectionData = CvReadStreamSegment(moduleInfo->mStream, moduleInfo->mSymbolBytes, moduleInfo->mLinesBytes); uint8* data = sectionData; - uint8* dataEnd = sectionData + moduleInfo->mLinesBytes; + uint8* dataEnd = sectionData + moduleInfo->mLinesBytes; while (data < dataEnd) - { + { GET_INTO(int32, lineInfoType); - GET_INTO(int32, lineInfoLength); + GET_INTO(int32, lineInfoLength); uint8* dataEnd = data + lineInfoLength; if (lineInfoType == DEBUG_S_FILECHKSMS) - { + { while (data < dataEnd) - { + { GET_INTO(uint, fileTableOfs); DbgSrcFile* srcFile; @@ -4689,10 +4690,9 @@ void COFF::ScanCompileUnit(int compileUnitId) PTR_ALIGN(data, sectionData, 4); } - break; // Stop once we handle the file checksums } - + data = dataEnd; } @@ -4711,7 +4711,7 @@ void COFF::FixTypes(int startingIdx) for (int typeIdx = startingIdx; typeIdx < (int)linkedModule->mTypes.size(); typeIdx++) { DbgType* dbgType = linkedModule->mTypes[typeIdx]; - + DbgType* prevNamespaceType = NULL; if (dbgType->mName == NULL) { @@ -4761,17 +4761,17 @@ void COFF::FixTypes(int startingIdx) } // This never happens anymore - nested types are always handled as "internal typedefs" - //TODO: Check the 'isnested' flag on the leaf instead of counting on parent to be specified? + //TODO: Check the 'isnested' flag on the leaf instead of counting on parent to be specified? bool hadParent = dbgType->mParent != NULL; int chevronDepth = 0; - if ((dbgType->mTypeCode == DbgType_Class) || (dbgType->mTypeCode == DbgType_Struct) || (dbgType->mTypeCode == DbgType_Union) || + if ((dbgType->mTypeCode == DbgType_Class) || (dbgType->mTypeCode == DbgType_Struct) || (dbgType->mTypeCode == DbgType_Union) || (dbgType->mTypeCode == DbgType_Enum) || (dbgType->mTypeCode == DbgType_TypeDef)) - { + { int startIdx = -1; const char* name = dbgType->mTypeName; - + for (int i = 0; true; i++) { char c = name[i]; @@ -4779,15 +4779,15 @@ void COFF::FixTypes(int startingIdx) chevronDepth++; else if (c == '>') chevronDepth--; - + if ((chevronDepth == 0) && ((c == ':') || (c == '.'))) { if ((!hadParent) && (i - startIdx > 1)) - { + { //String wholeNamespace = String(name, name + i); wholeNamespace.clear(); wholeNamespace.Insert(0, name, i); - + auto entry = linkedModule->mTypeMap.Find(wholeNamespace.c_str(), dbgType->mLanguage); if (entry == NULL) { @@ -4817,7 +4817,7 @@ void COFF::FixTypes(int startingIdx) } else if ((c == 0) /*|| (c == '<')*/ || (c == '(')) break; - } + } if (prevNamespaceType != NULL) { @@ -4878,7 +4878,7 @@ uint8* COFF::CvReadStream(int streamIdx, int* outSize) *outSize = streamSize; if (streamSize <= 0) return NULL; - int streamPageCount = (streamSize + mCvPageSize - 1) / mCvPageSize; + int streamPageCount = (streamSize + mCvPageSize - 1) / mCvPageSize; uint8* sectionData = new uint8[streamSize]; bool deferDeleteSectionData = false; @@ -4900,7 +4900,7 @@ uint8* COFF::CvReadStreamSegment(int streamIdx, int offset, int size) //int streamSize = mCvStreamSizes[streamIdx]; //int streamPageCount = (streamSize + mCvPageSize - 1) / mCvPageSize; - + uint8* sectionData = new uint8[size]; //delete [] sectionData; @@ -4911,7 +4911,7 @@ uint8* COFF::CvReadStreamSegment(int streamIdx, int offset, int size) int curOffset = offset; int sizeLeft = size; - int streamPtrIdx = mCvStreamPtrStartIdxs[streamIdx]; + int streamPtrIdx = mCvStreamPtrStartIdxs[streamIdx]; streamPtrIdx += offset / mCvPageSize; curOffset = offset - (offset / mCvPageSize) * mCvPageSize; @@ -4931,9 +4931,9 @@ uint8* COFF::CvReadStreamSegment(int streamIdx, int offset, int size) } void COFF::ReleaseTempBuf(uint8* buf) -{ +{ if ((mTempBufIdx > 0) && (mTempBufs.mVals[mTempBufIdx - 1].mVals == buf)) - mTempBufIdx--; + mTempBufIdx--; } bool COFF::CvParseHeader(uint8 wantGuid[16], int32 wantAge) @@ -4941,13 +4941,13 @@ bool COFF::CvParseHeader(uint8 wantGuid[16], int32 wantAge) int streamSize = 0; uint8* data = CvReadStream(1, &streamSize); mCvHeaderData = data; - + int32 pdbVersion = GET(int32); int32 timestamp = GET(int32); - int32 pdbAge = GET(int32); + int32 pdbAge = GET(int32); for (int i = 0; i < 16; i++) mPDBGuid[i] = GET(int8); - + if ((wantAge != -1) && (/*(pdbAge != wantAge) ||*/ (memcmp(mPDBGuid, wantGuid, 16) != 0))) { @@ -4962,11 +4962,11 @@ bool COFF::CvParseHeader(uint8 wantGuid[16], int32 wantAge) msg += StrFormat(" PDB GUID : "); for (int i = 0; i < 16; i++) - msg += StrFormat("%02X", (uint8)mPDBGuid[i]); + msg += StrFormat("%02X", (uint8)mPDBGuid[i]); Fail(msg); } return false; - } + } if (mParseKind == ParseKind_Header) return true; @@ -5011,8 +5011,8 @@ bool COFF::CvParseHeader(uint8 wantGuid[16], int32 wantAge) bool COFF::CvParseDBI(int wantAge) { BP_ZONE("CvParseDBI"); - - uint8* data = CvReadStream(3); + + uint8* data = CvReadStream(3); if (data == NULL) return false; @@ -5065,7 +5065,7 @@ bool COFF::CvParseDBI(int wantAge) else if (machine == 0x014C) mIs64Bit = false; else // Unknown machine - return false; + return false; uint8* headerEnd = data; @@ -5163,7 +5163,7 @@ bool COFF::CvParseDBI(int wantAge) contribEntry->mDbgModule = this; contribEntry->mCompileUnitId = contrib.mModule; mDebugTarget->mContribMap.Insert(contribEntry); - } + } } } @@ -5183,7 +5183,7 @@ bool COFF::CvParseDBI(int wantAge) GET_INTO(int32, unknownData2); // Value added to the address offset when calculating the RVA. GET_INTO(uint32, rva_offset); - GET_INTO(uint32, section_length); + GET_INTO(uint32, section_length); } // Dbi File info @@ -5193,12 +5193,12 @@ bool COFF::CvParseDBI(int wantAge) int fileInfoNumSourceFiles = 0; - uint16* modIndices = (uint16*)data; + uint16* modIndices = (uint16*)data; data += fileInfoNumModules * sizeof(uint16); uint16* modFileCounts = (uint16*)data; data += fileInfoNumModules * sizeof(uint16); - for (int moduleIdx = 0; moduleIdx < fileInfoNumModules; moduleIdx++) + for (int moduleIdx = 0; moduleIdx < fileInfoNumModules; moduleIdx++) fileInfoNumSourceFiles += modFileCounts[moduleIdx]; int32* fileNameOffsets = (int32*)data; @@ -5215,14 +5215,14 @@ bool COFF::CvParseDBI(int wantAge) for (int fileIdx = 0; fileIdx < modFileCounts[moduleIdx]; fileIdx++) { - char* fileName = namePtr + *fileNameOffsets; + char* fileName = namePtr + *fileNameOffsets; curFileOfs++; fileNameOffsets++; - } + } //int blockStart = fileBlockTable[i]; //int blockLength = fileBlockTable[fileInfoNumModules + i]; - //int offset = offsetTable[blockStart]; through blockLength... + //int offset = offsetTable[blockStart]; through blockLength... } // File name table @@ -5230,7 +5230,7 @@ bool COFF::CvParseDBI(int wantAge) while (data < dataEnd) { int offset = (int)(data - dataStart); - const char* fileName = DataGetString(data); + const char* fileName = DataGetString(data); //DbgSrcFile* srcFile = AddSrcFile(mMasterCompileUnit, fileName); //fileTable.insert(std::make_pair(offset, srcFile)); }*/ @@ -5253,8 +5253,8 @@ bool COFF::CvParseDBI(int wantAge) for (int entryIdx = 0; entryIdx < strTabEntryCount; entryIdx++) { GET_INTO(int32, strOffset); - const char* str = (const char*)strTabData + strOffset; - } + const char* str = (const char*)strTabData + strOffset; + } return true; } @@ -5266,7 +5266,7 @@ void COFF::ParseSectionHeader(int sectionIdx) int sectionSize = 0; uint8* sectionData = CvReadStream(sectionIdx, §ionSize); uint8* data = sectionData; - + uint8* dataEnd = data + sectionSize; while (data < dataEnd) { @@ -5292,24 +5292,24 @@ void COFF::CvParseIPI() int hashAdjOffset = 0; int32 hashStream = -1; int32 hashAdjSize = 0; - int32 dataOffset = 0; + int32 dataOffset = 0; ParseTypeData(4, mCvIPIReader, sectionSize, dataOffset, hashStream, hashAdjOffset, hashAdjSize, mCvIPIMinTag, mCvIPIMaxTag); //mCvIPIData = sectionData; - + int recordCount = mCvIPIMaxTag - mCvIPIMinTag; mCvIPITagStartMap.Resize(recordCount + 1); //uint8* data = sectionData + dataOffset; int offset = dataOffset; for (int idx = 0; idx < recordCount; idx++) - { + { //BF_ASSERT(((offset) & 3) == 0); - uint8* data = mCvIPIReader.GetTempPtr(offset, 4); + uint8* data = mCvIPIReader.GetTempPtr(offset, 4); uint16 trLength = GET(uint16); int offsetStart = offset; offset += 2; data = mCvIPIReader.GetTempPtr(offset, trLength); - uint8* dataStart = data; + uint8* dataStart = data; uint16 trLeafType = GET(uint16); //uint8* dataEnd = dataStart + trLength; offset += trLength; @@ -5322,18 +5322,18 @@ void COFF::CvParseIPI() { case LF_FUNC_ID: { - lfFuncId* funcData = (lfFuncId*)dataStart; + lfFuncId* funcData = (lfFuncId*)dataStart; //subprogram->mName = (const char*)funcData->name; bool doScope = true; /*if (strcmp(curSubprogram->mName, "DispatchToMethod") == 0) { - doScope = true; + doScope = true; }*/ if ((funcData->scopeId != 0) && (doScope)) - { + { uint8* data = CvGetTagData(funcData->scopeId, true); CvAutoReleaseTempData releaseTempData(this, data); @@ -5344,7 +5344,6 @@ void COFF::CvParseIPI() { lfStringId& str = *(lfStringId*)data; const char* parentStr = (const char*)str.name; - } break; case LF_UDT_MOD_SRC_LINE: @@ -5362,27 +5361,26 @@ void COFF::CvParseIPI() { lfMFuncId* funcData = (lfMFuncId*)dataStart; auto parentType = CvGetType(funcData->parentType); - } break; - } + } mCvIPITagStartMap[idx] = offsetStart; } - + mCvIPITagStartMap[recordCount] = offset; } const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_target& outAddr) { const char* retName = NULL; - + int offsetStart = offset; - uint8* data = mCvSymbolRecordReader.GetTempPtr(offset, 4); + uint8* data = mCvSymbolRecordReader.GetTempPtr(offset, 4); uint16 symLen = *(uint16*)data; bool madeCopy = false; data = mCvSymbolRecordReader.GetTempPtr(offset, symLen + 2, false, &madeCopy); - uint8* dataStart = data; + uint8* dataStart = data; uint16 symType = *(uint16*)(data + 2); BF_ASSERT(symLen % 4 == 2); @@ -5399,23 +5397,23 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ #ifdef _DEBUG ParseTypeData(); - auto type = CvGetType(udt.typind); -#endif + auto type = CvGetType(udt.typind); +#endif retName = name; } break; case S_PUB32: { PUBSYM32& pubSym = *(PUBSYM32*)dataStart; - + if (symStreamType != CvSymStreamType_Symbols) - break; + break; BP_ALLOC_T(DbgSymbol); DbgSymbol* dbgSymbol = mAlloc.Alloc(); const char* name = (const char*)mCvSymbolRecordReader.GetPermanentPtr(offsetStart + offsetof(PUBSYM32, name), symLen - offsetof(PUBSYM32, name) + 2); // pubSym.name; - //OutputDebugStrF("Sym: %s\n", name); + //OutputDebugStrF("Sym: %s\n", name); #ifdef BF_DBG_32 if ((name != NULL) && (name[0] == '_')) name++; @@ -5424,7 +5422,7 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ dbgSymbol->mName = name; dbgSymbol->mAddress = GetSectionAddr(pubSym.seg, pubSym.off); dbgSymbol->mDbgModule = this; - + if ((dbgSymbol->mAddress >= mImageBase) && (dbgSymbol->mAddress < mImageBase + mImageSize)) { if ((dbgSymbol->mAddress & 0xFFFF'0000'0000'0000) == 0) @@ -5442,7 +5440,7 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ break; case S_CONSTANT: { - CONSTSYM& constSym = *(CONSTSYM*)dataStart; + CONSTSYM& constSym = *(CONSTSYM*)dataStart; } break; case S_GDATA32: @@ -5455,41 +5453,41 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ { mTLSIndexAddr = GetSectionAddr(dataSym.seg, dataSym.off); } - + char* name = (char*)dataSym.name; retName = name; - + if (symStreamType == CvSymStreamType_Globals_Scan) { scanName = (char*)dataSym.name; - break; + break; } - + bool wasBeef = false; const char* memberName = CvCheckTargetMatch(name, wasBeef); if (memberName == NULL) break; - + DbgType* dbgType = CvGetType(dataSym.typind); BP_ALLOC_T(DbgVariable); DbgVariable* variable = mAlloc.Alloc(); - variable->mType = dbgType; + variable->mType = dbgType; variable->mLocationData = permDataPtr; variable->mLocationLen = 1; variable->mIsStatic = true; variable->mCompileUnit = mMasterCompileUnit; - variable->mName = memberName; + variable->mName = memberName; variable->mLinkName = name; if (strcmp((const char*)dataSym.name, "__ImageBase") == 0) variable->mLinkName = NULL; // Avoid adding to map variable->mIsExtern = symType == S_GDATA32; - variable->mCompileUnit = mGlobalsTargetType->mCompileUnit; + variable->mCompileUnit = mGlobalsTargetType->mCompileUnit; // Push front so we will find before the original static declaration (that has no memory associated with it) - mGlobalsTargetType->mMemberList.PushFront(variable); + mGlobalsTargetType->mMemberList.PushFront(variable); if (IsObjectFile()) { @@ -5503,7 +5501,7 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ { uint8* permDataPtr = madeCopy ? mCvSymbolRecordReader.GetPermanentPtr(offsetStart, symLen + 2) : dataStart; THREADSYM32& threadSym = *(THREADSYM32*)permDataPtr; - + if (symStreamType == CvSymStreamType_Globals_Scan) { scanName = (char*)threadSym.name; @@ -5522,7 +5520,7 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ BP_ALLOC_T(DbgVariable); DbgVariable* variable = mAlloc.Alloc(); - variable->mType = dbgType; + variable->mType = dbgType; variable->mLocationData = permDataPtr; variable->mLocationLen = 1; variable->mIsStatic = true; @@ -5543,20 +5541,20 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ char* name = (char*)refSym.name; retName = name; - + if (symStreamType == CvSymStreamType_Globals_Scan) { scanName = (char*)refSym.name; break; - } + } + + int moduleId = refSym.imod - 1; - int moduleId = refSym.imod - 1; - bool wasBeef = false; char* memberName = (char*)CvCheckTargetMatch(name, wasBeef); - if (memberName == NULL) + if (memberName == NULL) break; - + bool wantsCopy = madeCopy; bool isIllegal = false; @@ -5572,23 +5570,23 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ memberName[cPtr - prevName] = 0; wantsCopy = false; break; - } + } else isIllegal = true; } if ((c == '<') || (c == '`')) isIllegal = true; - } + } if (!isIllegal) - { + { BP_ALLOC_T(DbgMethodNameEntry); auto methodNameEntry = mAlloc.Alloc(); methodNameEntry->mCompileUnitId = moduleId; methodNameEntry->mName = wantsCopy ? DbgDupString(memberName) : memberName; mGlobalsTargetType->mMethodNameList.PushBack(methodNameEntry); - } + } } break; default: @@ -5597,30 +5595,30 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ } if (scanName != NULL) - { + { //TODO: Remove //String origName = name; //CvFixupName(name); char* lastDblColon = (char*)GetNamespaceEnd(scanName); if (lastDblColon != NULL) - { + { if (mPrevScanName != NULL) { int namespaceLen = lastDblColon - scanName; if (strncmp(scanName, mPrevScanName, namespaceLen + 2) == 0) // +2 includes the ending '::' { // We've already inserted this namespace - return retName; + return retName; } } StringT<256> tempName; - tempName = String(scanName, lastDblColon - scanName); + tempName = String(scanName, lastDblColon - scanName); DbgType* dbgType = CvGetTypeOrNamespace((char*)tempName.c_str()); -// *lastDblColon = '\0'; +// *lastDblColon = '\0'; // DbgType* dbgType = CvGetTypeOrNamespace(scanName); // *lastDblColon = ':'; @@ -5656,13 +5654,13 @@ const char* COFF::CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_ methodNameEntry->mCompileUnitId = moduleId; methodNameEntry->mName = methodName; dbgParent->mMethodNameList.PushBack(methodNameEntry); - }*/ + }*/ } else { mMasterCompileUnit->mGlobalType->mNeedsGlobalsPopulated = true; } - } + } return retName; } @@ -5682,7 +5680,7 @@ uint8* COFF::HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, uint8* dataEnd = data + sizeHr; uint8* refDataHead = data; int entryIdxMax = sizeHr / 8; - + data = dataEnd; dataEnd = data + sizeBuckets ; @@ -5703,7 +5701,7 @@ uint8* COFF::HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, return dataEnd; // No hash std::multimap checkAddrMap; - + int bitCount = 0; for (int blockIdx = 0; blockIdx < 0x81; blockIdx++) { @@ -5729,7 +5727,7 @@ uint8* COFF::HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, continue; addr_target addr = 0; - const char* symName = CvParseSymbol(symDataPtr - 1, symStreamType, addr); + const char* symName = CvParseSymbol(symDataPtr - 1, symStreamType, addr); #ifdef _DEBUG if ((verify) && (addrMap != NULL)) { @@ -5757,15 +5755,15 @@ uint8* COFF::HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, data = addrMap; for (int entryIdx = 0; entryIdx < numRecordsRead; entryIdx++) { - int verifyIdx = GET(int32); + int verifyIdx = GET(int32); int actualIdx = itr->second; if (actualIdx != verifyIdx) { OutputDebugStrF("Mismatch #%X %X %X %08X\n", entryIdx, verifyIdx, actualIdx, itr->first); } ++itr; - } - } + } + } #endif BF_ASSERT(numRecordsRead == entryIdxMax); @@ -5777,8 +5775,8 @@ uint8* COFF::HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, void COFF::ParseSymbolStream(CvSymStreamType symStreamType) { - if (mCvSymbolRecordStream == 0) - return; + if (mCvSymbolRecordStream == 0) + return; BP_ZONE("COFF::ParseSymbolStream"); @@ -5801,14 +5799,14 @@ void COFF::ParseSymbolStream(CvSymStreamType symStreamType) uint8* data; if (mCvPublicSymbolData == NULL) mCvPublicSymbolData = CvReadStream(mCvPublicSymbolInfoStream, &streamSize); // psgsi - data = mCvPublicSymbolData; - uint8* sectionData = data; + data = mCvPublicSymbolData; + uint8* sectionData = data; GET_INTO(int32, symHashSize); - GET_INTO(int32, addrMapSize); + GET_INTO(int32, addrMapSize); GET_INTO(int32, thunkCount); GET_INTO(int32, thunkSize); - GET_INTO(int32, thunkTableStream); + GET_INTO(int32, thunkTableStream); GET_INTO(int32, thunkTableOfs); GET_INTO(int32, thunkSectCount); @@ -5818,24 +5816,24 @@ void COFF::ParseSymbolStream(CvSymStreamType symStreamType) /*int addrMapEntryCount = addrMapSize / 4; for (int addrIdx = 0; addrIdx < addrMapEntryCount; addrIdx++) { - GET_INTO(int32, addrVal); + GET_INTO(int32, addrVal); } for (int thunkIdx = 0; thunkIdx < thunkCount; thunkIdx++) { - GET_INTO(int32, thunkVal); + GET_INTO(int32, thunkVal); } for (int sectionIdx = 0; sectionIdx < thunkSectCount; sectionIdx++) { GET_INTO(int32, ofs); - GET_INTO(int32, sectNum); + GET_INTO(int32, sectNum); }*/ - } + } } void COFF::Fail(const StringImpl& error) -{ +{ DbgModule::Fail(StrFormat("%s in %s", error.c_str(), mPDBPath.c_str())); } @@ -5856,14 +5854,14 @@ void COFF::ParseGlobalsData() if (mParsedGlobalsData) return; ParseTypeData(); - mParsedGlobalsData = true; + mParsedGlobalsData = true; //gDbgPerfManager->StartRecording(); int startTypeIdx = (int)mTypes.size(); ParseSymbolStream(CvSymStreamType_Globals_Scan); - + //gDbgPerfManager->StopRecording(true); //int addedTypes = (int)mTypes.size() - startTypeIdx; @@ -5892,19 +5890,19 @@ bool COFF::ParseCv(DataStream& pdbFS, uint8* rootDirData, int pageSize, uint8 wa InitCvTypes(); - int startingTypeIdx = mTypes.size(); + int startingTypeIdx = mTypes.size(); uint8* data = rootDirData; bool failed = false; int numStreams = GET(int32); - if (numStreams == 0) + if (numStreams == 0) return true; mCvStreamSizes.Resize(numStreams); mCvStreamPtrStartIdxs.Resize(numStreams); - int streamPages = 0; + int streamPages = 0; for (int i = 0; i < (int)mCvStreamSizes.size(); i++) mCvStreamSizes[i] = GET(int32); for (int streamIdx = 0; streamIdx < numStreams; streamIdx++) @@ -5915,14 +5913,13 @@ bool COFF::ParseCv(DataStream& pdbFS, uint8* rootDirData, int pageSize, uint8 wa } mCvStreamPtrs.Resize(streamPages); for (int i = 0; i < (int)mCvStreamPtrs.size(); i++) - mCvStreamPtrs[i] = GET(int32); - + mCvStreamPtrs[i] = GET(int32); ////////////////////////////////////////////////////////////////////////// if (!CvParseHeader(wantGuid, wantAge)) return false; - + if (!CvParseDBI(wantAge)) return false; @@ -5940,19 +5937,19 @@ bool COFF::ParseCv(DataStream& pdbFS, uint8* rootDirData, int pageSize, uint8 wa } for (int compileUnitId = 0; compileUnitId < (int)mCvModuleInfo.size(); compileUnitId++) - { + { ScanCompileUnit(compileUnitId); } ////////////////////////////////////////////////////////////////////////// - + return true; } void COFF::ReportMemory(MemReporter* memReporter) { DbgModule::ReportMemory(memReporter); - + memReporter->AddVec("mCvTypeMap", mCvTypeMap); memReporter->AddVec("mCvTagStartMap", mCvTagStartMap); memReporter->AddVec("mCvIPITagStartMap", mCvIPITagStartMap); @@ -5963,14 +5960,14 @@ void COFF::ReportMemory(MemReporter* memReporter) memReporter->AddVec(mCVSrcFileRefCache); if (mCvHeaderData != NULL) - memReporter->Add("mCvHeaderData", mCvStreamSizes[1]); - for (auto& entry : mCvTypeSectionData) + memReporter->Add("mCvHeaderData", mCvStreamSizes[1]); + for (auto& entry : mCvTypeSectionData) { if (entry.mSize != -1) memReporter->Add("mCvTypeSectionData", entry.mSize); else memReporter->Add("mCvTypeSectionData", mCvStreamSizes[2]); - } + } if (mCvStrTableData != NULL) memReporter->Add("mCvStrTableData", mCvStreamSizes[mStringTable.mStream]); if (mCvPublicSymbolData != NULL) @@ -5990,7 +5987,7 @@ bool COFF::TryLoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) mCvMappedFile = CreateFileA(pdbPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (mCvMappedFile == INVALID_HANDLE_VALUE) - { + { return false; } @@ -6023,22 +6020,22 @@ bool COFF::TryLoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) Fail("PDB signature error"); return false; } - + BfLogDbg("Loading PDB %s\n", pdbPath.c_str()); BP_ZONE_F("LoadCv %s", pdbPath.c_str()); - + int pageSize = mCvDataStream->ReadInt32(); int fpmPageNum = mCvDataStream->ReadInt32(); int totalPageCount = mCvDataStream->ReadInt32(); int rootDirSize = mCvDataStream->ReadInt32(); int unknown = mCvDataStream->ReadInt32(); - + int rootDirPtrs[NUM_ROOT_DIRS]; mCvDataStream->ReadT(rootDirPtrs); - + bool failed = false; - + mCvPageSize = pageSize; for (int i = 0; i < 31; i++) { @@ -6077,16 +6074,16 @@ bool COFF::TryLoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) } } - int startingTypeIdx = mTypes.size(); + int startingTypeIdx = mTypes.size(); if (!ParseCv(*mCvDataStream, &rootDirData[0], pageSize, wantGuid, wantAge)) { //mDebugger->OutputMessage("Failed to parse PDB\n"); - return false; + return false; } - + if (mCvDataStream->mFailed) return false; - + //OutputDebugStrF("COFF::TryLoadPDB %s\n", pdbPath.c_str()); if (!isVerifyOnly) mDebugger->ModuleChanged(this); @@ -6101,7 +6098,7 @@ void COFF::ClosePDB() delete mCvDataStream; mCvDataStream = NULL; delete mCvHeaderData; - mCvHeaderData = NULL; + mCvHeaderData = NULL; delete mCvStrTableData; mCvStrTableData = NULL; for (auto& entry : mCvTypeSectionData) @@ -6128,7 +6125,7 @@ void COFF::ClosePDB() for (auto kv : mHotLibMap) delete kv.mValue; - mHotLibMap.Clear(); + mHotLibMap.Clear(); mHotLibSymMap.Clear(); delete mEmitSourceFile; @@ -6136,7 +6133,7 @@ void COFF::ClosePDB() } bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) -{ +{ if (mDebugTarget->mTargetBinary == this) { // If we don't have to load the debug symbols from a remote source or the cache @@ -6149,20 +6146,20 @@ bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) memcpy(mWantPDBGuid, wantGuid, 16); mWantAge = wantAge; - mDbgSymRequest = mDebugger->mDbgSymSrv.CreateRequest(mFilePath, pdbPath, wantGuid, wantAge); + mDbgSymRequest = mDebugger->mDbgSymSrv.CreateRequest(mFilePath, pdbPath, wantGuid, wantAge); mDbgSymRequest->SearchLocal(); if (!mDbgSymRequest->mFinalPDBPath.IsEmpty()) - { + { TryLoadPDB(mDbgSymRequest->mFinalPDBPath, wantGuid, wantAge); mDebugger->mDbgSymSrv.ReleaseRequest(mDbgSymRequest); mDbgSymRequest = NULL; } else mMayBeOld = true; - + String fileName = GetFileName(mFilePath); - mWantsAutoLoadDebugInfo = !mDebugTarget->mWasLocallyBuilt; + mWantsAutoLoadDebugInfo = !mDebugTarget->mWasLocallyBuilt; if ((fileName.Equals("KERNEL32.DLL", String::CompareKind_OrdinalIgnoreCase)) || (fileName.Equals("KERNELBASE.DLL", String::CompareKind_OrdinalIgnoreCase)) || @@ -6193,7 +6190,7 @@ bool COFF::LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) //char exePath[MAX_PATH]; //GetModuleFileNameA(NULL, exePath, sizeof(exePath)); - + /*String checkPath = ::GetFileDir(mFilePath); checkPath += "/"; checkPath += GetFileName(pdbPath); @@ -6215,12 +6212,12 @@ bool COFF::CheckSection(const char* name, uint8* sectionData, int sectionSize) DbgSectionData entry; entry.mData = sectionData; entry.mSize = sectionSize; - mCvTypeSectionData.Add(entry); + mCvTypeSectionData.Add(entry); return true; } if (strcmp(name, ".debug$S") == 0) - { + { DbgSectionData entry; entry.mData = sectionData; entry.mSize = sectionSize; @@ -6236,19 +6233,19 @@ void COFF::ProcessDebugInfo() BP_ZONE("COFF::ProcessDebugInfo"); if ((!mCvTypeSectionData.IsEmpty()) && (!mCvCompileUnitData.IsEmpty())) - { + { auto linkedModule = (COFF*)GetLinkedModule(); int startingTypeIdx = (int)linkedModule->mTypes.size(); InitCvTypes(); - + for (auto entry : mCvTypeSectionData) { uint8* data = entry.mData; GET_INTO(uint32, infoType); BF_ASSERT(infoType == CV_SIGNATURE_C13); - CvInitStreamRaw(mCvTypeSectionReader, entry.mData + 4, entry.mSize - 4); + CvInitStreamRaw(mCvTypeSectionReader, entry.mData + 4, entry.mSize - 4); ParseTypeData(mCvTypeSectionReader, 0); } @@ -6258,7 +6255,7 @@ void COFF::ProcessDebugInfo() CvCompileUnit* compileUnit = NULL; for (auto entry : mCvCompileUnitData) { - compileUnit = ParseCompileUnit(NULL, compileUnit, entry.mData, entry.mSize); + compileUnit = ParseCompileUnit(NULL, compileUnit, entry.mData, entry.mSize); } compileUnit->mLanguage = DbgLanguage_Beef; mMasterCompileUnit->mLanguage = DbgLanguage_Beef; @@ -6268,9 +6265,9 @@ void COFF::ProcessDebugInfo() } void COFF::FinishHotSwap() -{ +{ DbgModule::FinishHotSwap(); - mTypeMap.Clear(); + mTypeMap.Clear(); } intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags) @@ -6288,11 +6285,11 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, addr_target pc = 0; if (stackFrame != NULL) { - // Use 'GetSourcePC', which will offset the RSP when we're not at the top position of the call stack, since RSP will be the + // Use 'GetSourcePC', which will offset the RSP when we're not at the top position of the call stack, since RSP will be the // return address in those cases pc = stackFrame->GetSourcePC(); } - + int inlineDepth = 0; uint8* data = (uint8*)locData; for (int locIdx = 0; locIdx < locDataLen; locIdx++) @@ -6301,7 +6298,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, GET_INTO(uint16, symLen); uint8* dataEnd = data + symLen; GET_INTO(uint16, symType); - + CV_LVAR_ADDR_RANGE* rangeInfo = NULL; CV_LVAR_ADDR_GAP* gapsInfo = NULL; addr_target result = 0; @@ -6322,7 +6319,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, case S_GDATA32: case S_LDATA32: { - DATASYM32& dataSym = *(DATASYM32*)dataStart; + DATASYM32& dataSym = *(DATASYM32*)dataStart; *outAddrType = DbgAddrType_Target; return GetSectionAddr(dataSym.seg, dataSym.off); } @@ -6344,10 +6341,10 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, case S_GTHREAD32: { THREADSYM32& threadSym = *(THREADSYM32*)dataStart; - + int tlsIndex = mDebugger->ReadMemory(mTLSIndexAddr); addr_target tlsEntry = mDebugger->GetTLSOffset(tlsIndex); - + *outAddrType = DbgAddrType_Target; return threadSym.off + tlsEntry; } @@ -6364,7 +6361,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, { REGREL32* regRel32 = (REGREL32*)dataStart; *outAddrType = DbgAddrType_Target; - int regNum = CvConvRegNum(regRel32->reg); + int regNum = CvConvRegNum(regRel32->reg); return stackFrame->mRegisters.mIntRegsArray[regNum] + regRel32->off; } break; @@ -6380,36 +6377,36 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, case S_DEFRANGE_FRAMEPOINTER_REL: { DEFRANGESYMFRAMEPOINTERREL& defRangeFPRel = *(DEFRANGESYMFRAMEPOINTERREL*)dataStart; - + DbgSubprogram::LocalBaseRegKind baseReg = ((flags & DbgEvalLocFlag_IsParam) != 0) ? dwSubprogram->mParamBaseReg : dwSubprogram->mLocalBaseReg; *outAddrType = DbgAddrType_Target; -#ifdef BF_DBG_64 +#ifdef BF_DBG_64 if (baseReg == DbgSubprogram::LocalBaseRegKind_RSP) result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RSP] + defRangeFPRel.offFramePointer; else if (baseReg == DbgSubprogram::LocalBaseRegKind_R13) result = stackFrame->mRegisters.mIntRegsArray[X64Reg_R13] + defRangeFPRel.offFramePointer; else result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RBP] + defRangeFPRel.offFramePointer; -#else +#else if (baseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) - result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; + result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; else if (baseReg == DbgSubprogram::LocalBaseRegKind_EBX) result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBX] + defRangeFPRel.offFramePointer; else result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer; -#endif - +#endif + rangeInfo = &defRangeFPRel.range; gapsInfo = &defRangeFPRel.gaps[0]; } break; case S_DEFRANGE_SUBFIELD_REGISTER: { - DEFRANGESYMSUBFIELDREGISTER& defRangeSubfieldReg = *(DEFRANGESYMSUBFIELDREGISTER*)dataStart; - + DEFRANGESYMSUBFIELDREGISTER& defRangeSubfieldReg = *(DEFRANGESYMSUBFIELDREGISTER*)dataStart; + *outAddrType = DbgAddrType_Target; - int regNum = CvConvRegNum(defRangeSubfieldReg.reg); + int regNum = CvConvRegNum(defRangeSubfieldReg.reg); result = stackFrame->mRegisters.mIntRegsArray[regNum] + defRangeSubfieldReg.offParent; rangeInfo = &defRangeSubfieldReg.range; @@ -6424,7 +6421,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int regNum = X64Reg_RSP; #else int regNum = X86Reg_ESP; -#endif +#endif *outAddrType = DbgAddrType_Target; result = stackFrame->mRegisters.mIntRegsArray[regNum] + defFPRel.offFramePointer; return result; @@ -6449,7 +6446,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, { inlineDepth++; } - break; + break; case S_FILESTATIC: { FILESTATICSYM& fileStaticSym = *(FILESTATICSYM*)dataStart; @@ -6462,9 +6459,9 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, } if (rangeInfo != NULL) - { - auto rangeStart = GetSectionAddr(rangeInfo->isectStart, rangeInfo->offStart); - + { + auto rangeStart = GetSectionAddr(rangeInfo->isectStart, rangeInfo->offStart); + if ((pc >= rangeStart) && (pc < rangeStart + rangeInfo->cbRange)) { bool inRange = true; @@ -6473,7 +6470,7 @@ intptr COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, if ((pc >= rangeStart + gapsInfo->gapStartOffset) && (pc < rangeStart + gapsInfo->gapStartOffset + gapsInfo->cbRange)) { inRange = false; - break; + break; } gapsInfo++; } @@ -6502,7 +6499,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) { if (mCvSrcSrvStream == -1) return ""; - + int outSize; uint8* data = CvReadStream(mCvSrcSrvStream, &outSize); String cmdBlock = String((char*)data, outSize); @@ -6519,7 +6516,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) _SectType_SourceFiles }; _SectType sectType = _SectType_None; - + // { AutoCrit autoCrit(gDebugManager->mCritSect); @@ -6535,7 +6532,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) int endIdx = str.IndexOf('%', i + 1); if (endIdx != -1) { - String varName = ToUpper(str.Substring(i + 1, endIdx - i - 1)); + String varName = ToUpper(str.Substring(i + 1, endIdx - i - 1)); if (((endIdx < str.length() - 1) && (str[endIdx + 1] == '(')) && ((varName == "FNVAR") || (varName == "FNBKSL") || (varName == "FNFILE"))) { @@ -6552,7 +6549,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) else { if (varName == "FNBKSL") - { + { paramStr.Replace("/", "\\"); } else if (varName == "FNFILE") @@ -6636,7 +6633,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) int starPos = line.IndexOf('*', curStrPos); if (starPos == -1) starPos = line.length(); - + //var = line.Substring(curStrPos, starPos - curStrPos); var.Clear(); var.Insert(0, line.c_str() + curStrPos, starPos - curStrPos); @@ -6647,7 +6644,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) if (!matches) break; } - + defs[StrFormat("VAR%d", curStrIdx + 1)] = var; curStrIdx++; @@ -6664,7 +6661,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) _Expand(target); _Expand(cmd); _Expand(env); - + String retVal; if ((cmd.IsEmpty()) && (target.StartsWith("HTTP", StringImpl::CompareKind_OrdinalIgnoreCase))) { @@ -6678,7 +6675,7 @@ String COFF::GetOldSourceCommand(const StringImpl& path) localFile.Append("SymbolCache\\src\\"); localFile.Append(StringView(target, dotPos + 3)); localFile.Replace("/", "\\"); - } + } retVal = localFile; retVal += "\n"; @@ -6694,11 +6691,11 @@ String COFF::GetOldSourceCommand(const StringImpl& path) retVal += "\n"; retVal += env; } - + return retVal; } break; - } + } } linePos = crPos + 1; @@ -6711,7 +6708,7 @@ bool COFF::GetEmitSource(const StringImpl& filePath, String& outText) { if (!filePath.StartsWith("$Emit")) return false; - + if (mEmitSourceFile == NULL) { mEmitSourceFile = new ZipFile(); @@ -6724,10 +6721,10 @@ bool COFF::GetEmitSource(const StringImpl& filePath, String& outText) { if (mCvEmitStream == -1) return ""; - + int outSize; uint8* data = CvReadStream(mCvEmitStream, &outSize); - + FileStream fileStream; fileStream.Open(zipPath, "wb"); fileStream.Write(data, outSize); @@ -6746,7 +6743,7 @@ bool COFF::GetEmitSource(const StringImpl& filePath, String& outText) { int dollarPos = usePath.IndexOf('$', 1); usePath.Remove(0, dollarPos + 1); - } + } usePath = EncodeFileName(usePath); usePath.Append(".bf"); @@ -6846,20 +6843,20 @@ bool COFF::RequestImage() return false; auto miniDumpDebugger = (MiniDumpDebugger*)mDebugger; - + if (mOrigImageData != NULL) return false; if (GetCurrentThreadId() == mDebugger->mDebuggerThreadId) - { + { auto prevRunState = mDebugger->mRunState; mDebugger->mRunState = RunState_SearchingSymSrv; mDebugger->mDebugManager->mOutMessages.push_back(StrFormat("symsrv Searching for image '%s'", mFilePath.c_str())); - + auto dbgSymRequest = mDebugger->mDbgSymSrv.CreateRequest(); mDebugger->mActiveSymSrvRequest = dbgSymRequest; BF_ASSERT(mDebugger->mDebugManager->mCritSect.mLockCount == 1); - mDebugger->mDebugManager->mCritSect.Unlock(); + mDebugger->mDebugManager->mCritSect.Unlock(); // We unlock to allow the IDE to continue updating while we search String imagePath = dbgSymRequest->SearchForImage(mFilePath, mTimeStamp, mImageSize); mDebugger->mDebugManager->mCritSect.Lock(); @@ -6867,8 +6864,8 @@ bool COFF::RequestImage() mDebugger->mActiveSymSrvRequest = NULL; mDebugger->mRunState = prevRunState; - - return LoadModuleImage(imagePath); + + return LoadModuleImage(imagePath); } else { @@ -6885,28 +6882,28 @@ bool COFF::RequestDebugInfo(bool allowRemote) if (mDbgSymRequest->mInProcess) return false; - + bool hasDebugInfo = false; mDbgSymRequest->SearchCache(); if (mDbgSymRequest->mFinalPDBPath.IsEmpty()) - { + { if (!allowRemote) return false; if (GetCurrentThreadId() == mDebugger->mDebuggerThreadId) - { + { auto prevRunState = mDebugger->mRunState; mDebugger->mRunState = RunState_SearchingSymSrv; - + mDbgSymRequest->mInProcess = true; mDebugger->mActiveSymSrvRequest = mDbgSymRequest; BF_ASSERT(mDebugger->mDebugManager->mCritSect.mLockCount == 1); - mDebugger->mDebugManager->mCritSect.Unlock(); + mDebugger->mDebugManager->mCritSect.Unlock(); mDbgSymRequest->SearchSymSrv(); mDebugger->mDebugManager->mCritSect.Lock(); mDebugger->mActiveSymSrvRequest = NULL; mDbgSymRequest->mInProcess = false; - + mDebugger->mRunState = prevRunState; } else @@ -6958,7 +6955,7 @@ addr_target COFF::LocateSymbol(const StringImpl& name) String libName = moduleInfo->mObjectName; if (!libName.EndsWith(".lib", StringImpl::CompareKind_OrdinalIgnoreCase)) continue; - + CvLibInfo** libInfoPtr; if (!mHotLibMap.TryAdd(libName, NULL, &libInfoPtr)) continue; @@ -6966,7 +6963,7 @@ addr_target COFF::LocateSymbol(const StringImpl& name) CvLibInfo* libInfo = new CvLibInfo(); *libInfoPtr = libInfo; - if (!libInfo->mLibFile.Init(libName, false)) + if (!libInfo->mLibFile.Init(libName, false)) continue; for (auto kv : libInfo->mLibFile.mOldEntries) @@ -7001,14 +6998,14 @@ addr_target COFF::LocateSymbol(const StringImpl& name) // We already tried to load this return 0; } - + auto fileExt = GetFileExtension(libEntry->mName); if (String::Equals(fileExt, ".dll", StringImpl::CompareKind_OrdinalIgnoreCase)) { for (auto dbgModule : mDebugTarget->mDbgModules) { if (String::Equals(libEntry->mName, dbgModule->mDisplayName)) - { + { dbgModule->ParseSymbolData(); auto entry = dbgModule->mSymbolNameMap.Find(name.c_str()); if (entry == NULL) @@ -7042,7 +7039,7 @@ addr_target COFF::LocateSymbol(const StringImpl& name) { uint8 mOpCode0; uint8 mOpCode1; - int32 mRIPRel; + int32 mRIPRel; uint64 mTarget; }; #pragma pack(pop) @@ -7074,9 +7071,9 @@ addr_target COFF::LocateSymbol(const StringImpl& name) // #ifdef _DEBUG // FILE* fpTest = fopen("c:\\temp\\locateSym.obj", "wb"); -// +// // uint8* data = new uint8[libEntry->mLength]; -// +// // fseek(libEntry->mLibFile->mOldFileStream.mFP, libEntry->mOldDataPos + sizeof(BeLibMemberHeader), SEEK_SET); // fread(data, 1, libEntry->mLength, libEntry->mLibFile->mOldFileStream.mFP); // fwrite(data, 1, libEntry->mLength, fpTest); @@ -7084,7 +7081,6 @@ addr_target COFF::LocateSymbol(const StringImpl& name) // delete data; // #endif - FileSubStream fileStream; fileStream.mFP = libEntry->mLibFile->mOldFileStream.mFP; fileStream.mOffset = libEntry->mOldDataPos + sizeof(BeLibMemberHeader); @@ -7107,7 +7103,7 @@ addr_target COFF::LocateSymbol(const StringImpl& name) Fail(StrFormat("Debugger failed to read binary '%s' in '%s'", libEntry->mName.c_str(), libEntry->mLibFile->mFilePath.c_str())); delete dbgModule; return 0; - } + } mDebugger->mDebugTarget->AddDbgModule(dbgModule); auto symbolEntry = mSymbolNameMap.Find(name.c_str()); @@ -7229,7 +7225,6 @@ void COFF::ParseFrameDescriptors(uint8* data, int size, addr_target baseAddr) } mParsedFrameDescriptors = true; - } void COFF::ParseFrameDescriptors() @@ -7252,10 +7247,10 @@ NS_BF_DBG_BEGIN // COFF coff(debugTarget); // coff.mCvTypeSectionData = (uint8*)tdata; // coff.mCvTypeSectionDataSize = tdataSize; -// +// // coff.mCvCompileUnitData = (uint8*)cuData; // coff.mCvCompileUnitDataSize = cuDataSize; -// +// // coff.ProcessDebugInfo(); // } // delete debugTarget; @@ -7264,7 +7259,7 @@ NS_BF_DBG_BEGIN void TestPDB(const StringImpl& fileName, WinDebugger* debugger) { DebugTarget* debugTarget = new DebugTarget(NULL); - COFF coff(debugTarget); + COFF coff(debugTarget); coff.mDebugger = debugger; uint8 wantGuid[16]; coff.TryLoadPDB(fileName, wantGuid, -1); @@ -7276,4 +7271,4 @@ void TestPDB(const StringImpl& fileName, WinDebugger* debugger) coff.ParseCompileUnit(compileUnitId); } -NS_BF_DBG_END +NS_BF_DBG_END \ No newline at end of file diff --git a/IDEHelper/COFF.h b/IDEHelper/COFF.h index d3c83a1d..71b4f6c5 100644 --- a/IDEHelper/COFF.h +++ b/IDEHelper/COFF.h @@ -1,6 +1,5 @@ #pragma once - #include "DbgModule.h" #include "StrBloomMap.h" #include "DbgSymSrv.h" @@ -68,11 +67,11 @@ struct CvCrossScopeExportEntry class CvCompileUnit : public DbgCompileUnit { -public: +public: Array mExports; Array mImports; Dictionary mExportMap; - int mModuleIdx; + int mModuleIdx; CvCompileUnit(DbgModule* dbgModule) : DbgCompileUnit(dbgModule) { @@ -80,12 +79,12 @@ public: }; struct CvModuleInfo : public CvModuleInfoBase -{ +{ const char* mModuleName; const char* mObjectName; CvCompileUnit* mCompileUnit; int mIdx; - bool mHasMappedMethods; + bool mHasMappedMethods; }; struct CvStringTable @@ -112,17 +111,17 @@ enum CvSymStreamType struct CvModuleRef { CvModuleRef* mNext; - int mModule; + int mModule; }; struct CvInlineInfo { CvInlineInfo* mNext; CvInlineInfo* mTail; - DbgSubprogram* mSubprogram; + DbgSubprogram* mSubprogram; uint8* mData; - int mDataLen; - int mInlinee; + int mDataLen; + int mInlinee; bool mDebugDump; }; typedef Array CvInlineInfoVec; @@ -172,18 +171,18 @@ class COFF; class CvStreamReader { -public: +public: COFF* mCOFF; int mPageBits; Array mStreamPtrs; Array mTempData; int mSize; - + public: CvStreamReader() { mCOFF = NULL; - mPageBits = 0; + mPageBits = 0; mSize = 0; } @@ -203,7 +202,6 @@ public: Dictionary mSymDict; }; - class COFF : public DbgModule { public: @@ -214,14 +212,14 @@ public: ParseKind_Full }; -public: +public: ZipFile* mEmitSourceFile; uint8 mWantPDBGuid[16]; int mWantAge; uint8 mPDBGuid[16]; int mFileAge; - int mDebugAge; + int mDebugAge; ParseKind mParseKind; bool mPDBLoaded; bool mIs64Bit; @@ -229,46 +227,46 @@ public: int mCvPageSize; int mCvPageBits; int mCvMinTag; - int mCvMaxTag; + int mCvMaxTag; int mCvIPIMinTag; int mCvIPIMaxTag; //Array mCvTagData; // a DbgType* for type info, or a ptr to the data stream for child info Array mCvTypeMap; Array mCvTagStartMap; Array mCvIPITagStartMap; - - Array> mTempBufs; - int mTempBufIdx; - Array mCvSystemTypes; - + Array> mTempBufs; + int mTempBufIdx; + + Array mCvSystemTypes; + Array mCvStreamSizes; Array mCvStreamPtrStartIdxs; Array mCvStreamPtrs; - + CvStreamReader mCvTypeSectionReader; CvStreamReader mCvIPIReader; CvStreamReader mCvSymbolRecordReader; - StringT<128> mPDBPath; + StringT<128> mPDBPath; SafeMemStream* mCvDataStream; CvStringTable mStringTable; - uint8* mCvHeaderData; + uint8* mCvHeaderData; //uint8* mCvTypeSectionData - uint8* mCvStrTableData; + uint8* mCvStrTableData; uint8* mCvPublicSymbolData; uint8* mCvGlobalSymbolData; uint8* mNewFPOData; int mCvGlobalSymbolInfoStream; int mCvPublicSymbolInfoStream; - int mCvSymbolRecordStream; + int mCvSymbolRecordStream; int mCvSrcSrvStream; int mCvEmitStream; int mCvNewFPOStream; - Array mCvModuleInfo; + Array mCvModuleInfo; Dictionary mCVSrcFileRefCache; - Dictionary mModuleNameMap; + Dictionary mModuleNameMap; HashSet mModuleNameSet; Dictionary mHotLibMap; Dictionary mHotLibSymMap; @@ -282,7 +280,7 @@ public: Array mCvCompileUnitData; //int mCvTypeSectionDataSize; //uint8* mCvCompileUnitData; - //int mCvCompileUnitDataSize; + //int mCvCompileUnitDataSize; HANDLE mCvMappedFile; void* mCvMappedViewOfFile; @@ -290,12 +288,12 @@ public: HANDLE mCvMappedFileMapping; bool mIsFastLink; bool mTriedSymSrv; - DbgSymRequest* mDbgSymRequest; - bool mWantsAutoLoadDebugInfo; - - int mProcSymCount; + DbgSymRequest* mDbgSymRequest; + bool mWantsAutoLoadDebugInfo; -public: + int mProcSymCount; + +public: virtual void Fail(const StringImpl& error) override; virtual void SoftFail(const StringImpl& error); virtual void HardFail(const StringImpl& error) override; @@ -304,7 +302,7 @@ public: virtual void ParseSymbolData() override; virtual void ParseTypeData(CvStreamReader& reader, int dataOffset); void ParseTypeData(int sectionNum, CvStreamReader& reader, int& sectionSize, int& dataOfs, int& hashStream, int& hashAdjOffset, int& hashAdjSize, int& minVal, int& maxVal); - virtual void ParseTypeData() override; + virtual void ParseTypeData() override; void ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionData, uint8* data, uint8* dataEnd, CvInlineInfoVec& inlineDataVec, bool deferInternals, DbgSubprogram* useSubprogram); CvCompileUnit* ParseCompileUnit(CvModuleInfo* moduleInfo, CvCompileUnit* compileUnit, uint8* sectionData, int sectionSize); virtual CvCompileUnit* ParseCompileUnit(int compileUnitId) override; @@ -323,7 +321,7 @@ public: virtual void FinishHotSwap() override; virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None) override; virtual bool CanGetOldSource() override; - virtual String GetOldSourceCommand(const StringImpl& path) override; + virtual String GetOldSourceCommand(const StringImpl& path) override; virtual bool GetEmitSource(const StringImpl& filePath, String& outText) override; virtual bool HasPendingDebugInfo() override; virtual void PreCacheImage() override; @@ -346,36 +344,36 @@ public: void ParseSymbolStream(CvSymStreamType symStreamType); void ScanCompileUnit(int compileUnitId); void ParseFrameDescriptors(uint8* data, int size, addr_target baseAddr); - + const char* CvParseSymbol(int offset, CvSymStreamType symStreamType, addr_target& outAddr); uint8* HandleSymStreamEntries(CvSymStreamType symStreamType, uint8* data, uint8* addrMap); const char* CvParseString(uint8*& data); - const char* CvParseAndDupString(uint8*& data); + const char* CvParseAndDupString(uint8*& data); const char* CvDupString(const char* str, int strLen); - - void CvReadStream(int sectionIdx, CvStreamReader& streamReader); + + void CvReadStream(int sectionIdx, CvStreamReader& streamReader); void CvInitStreamRaw(CvStreamReader& streamReader, uint8* data, int size); - uint8* CvReadStream(int sectionIdx, int* outSize = NULL); + uint8* CvReadStream(int sectionIdx, int* outSize = NULL); uint8* CvReadStreamSegment(int sectionIdx, int offset, int size); void ReleaseTempBuf(uint8* buf); - + void InitCvTypes(); DbgType* CvCreateType(); int CvConvRegNum(int regNum, int* outBits = NULL); - addr_target GetSectionAddr(uint16 section, uint32 offset); + addr_target GetSectionAddr(uint16 section, uint32 offset); int64 CvParseConstant(uint16 constVal, uint8*& data); - int64 CvParseConstant(uint8*& data); - DbgType* CvGetType(int typeId); + int64 CvParseConstant(uint8*& data); + DbgType* CvGetType(int typeId); DbgType* CvGetTypeSafe(int typeId); DbgType* CvGetType(int typeId, CvCompileUnit* compileUnit); - int CvGetTagStart(int tagIdx, bool ipi); + int CvGetTagStart(int tagIdx, bool ipi); int CvGetTagSize(int tagIdx, bool ipi); uint8* CvGetTagData(int tagIdx, bool ipi, int* outDataSize = NULL); void CvParseArgList(DbgSubprogram* subprogram, int tagIdx, bool ipi); DbgSubprogram* CvParseMethod(DbgType* parentType, const char* methodName, int tagIdx, bool ipi, DbgSubprogram* subprogram = NULL); void CvParseMethodList(DbgType* parentType, const char* methodName, int tagIdx, bool ipi); - void CvParseMembers(DbgType* parentType, int tagIdx, bool ipi); - DbgType* CvParseType(int tagIdx, bool ipi = false); + void CvParseMembers(DbgType* parentType, int tagIdx, bool ipi); + DbgType* CvParseType(int tagIdx, bool ipi = false); bool CvParseDBI(int wantAge); void ParseSectionHeader(int sectionIdx); void CvParseIPI(); @@ -384,7 +382,7 @@ public: bool ParseCv(DataStream& CvFS, uint8* rootDirData, int pageSize, uint8 wantGuid[16], int32 wantAge); bool TryLoadPDB(const String& CvPath, uint8 wantGuid[16], int32 wantAge); void ClosePDB(); - virtual void ReportMemory(MemReporter* memReporter) override; + virtual void ReportMemory(MemReporter* memReporter) override; public: COFF(DebugTarget* debugTarget); @@ -392,7 +390,7 @@ public: virtual bool LoadPDB(const String& CvPath, uint8 wantGuid[16], int32 wantAge) override; virtual bool CheckSection(const char* name, uint8* sectionData, - int sectionSize) override; + int sectionSize) override; }; class CvAutoReleaseTempData @@ -422,10 +420,8 @@ namespace std struct hash { size_t operator()(const NS_BF_DBG::CvModuleInfoNameEntry& val) const - { + { return NS_BF_DBG::CvModuleInfoNameEntry::GetHashCode(Beefy::StringImpl::MakeRef(val.mModuleInfo->mModuleName)); } }; } - - diff --git a/IDEHelper/COFFData.h b/IDEHelper/COFFData.h index 440a96d2..d0b19a4d 100644 --- a/IDEHelper/COFFData.h +++ b/IDEHelper/COFFData.h @@ -7,7 +7,6 @@ struct CV_LVAR_ADDR_GAP; NS_BF_BEGIN - #define PE_SIZEOF_SHORT_NAME 8 #define PE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define PE_NUMBEROF_DIRECTORY_ENTRIES 16 @@ -17,7 +16,6 @@ NS_BF_BEGIN #define PE_MACHINE_X86 0x14c #define PE_MACHINE_X64 0x8664 - // DOS .EXE header struct PEHeader { @@ -174,8 +172,8 @@ struct PE_NTHeaders64 struct PESectionHeader { - char mName[IMAGE_SIZEOF_SHORT_NAME]; - DWORD mVirtualSize; + char mName[IMAGE_SIZEOF_SHORT_NAME]; + DWORD mVirtualSize; DWORD mVirtualAddress; DWORD mSizeOfRawData; DWORD mPointerToRawData; @@ -234,8 +232,8 @@ struct PE_SymInfoAux // int GetPrologSize() const { return mAttributes & 0xF; } // // // # regs saved -// int GetNumSavedRegs() const { return (mAttributes >> 8) & 0x7; } -// bool HasSEH() const { return (mAttributes >> 9) & 1; } +// int GetNumSavedRegs() const { return (mAttributes >> 8) & 0x7; } +// bool HasSEH() const { return (mAttributes >> 9) & 1; } // bool UseBP() const { return (mAttributes >> 10) & 1; } // // // cbFrame: frame pointer @@ -279,7 +277,7 @@ struct COFFFrameProgram Command_Align, Command_Set, Command_Deref, - Command_Value, + Command_Value, Command_Value8 }; diff --git a/IDEHelper/CPU.h b/IDEHelper/CPU.h index 6fd41e0a..1c7d5d6f 100644 --- a/IDEHelper/CPU.h +++ b/IDEHelper/CPU.h @@ -49,4 +49,3 @@ enum RegForm : int8 RegForm_Double2, RegForm_Double4, }; - diff --git a/IDEHelper/Compiler/BfAst.cpp b/IDEHelper/Compiler/BfAst.cpp index 24e4e955..8d97dc94 100644 --- a/IDEHelper/Compiler/BfAst.cpp +++ b/IDEHelper/Compiler/BfAst.cpp @@ -17,11 +17,11 @@ BfStructuralVisitor::BfStructuralVisitor() } void BfStructuralVisitor::VisitMembers(BfBlock* node) -{ +{ for (auto& child : *node) - { + { child->Accept(this); - } + } } void BfStructuralVisitor::VisitChildNoRef(BfAstNode* node) @@ -141,6 +141,11 @@ void BfStructuralVisitor::Visit(BfExpressionStatement* exprStmt) Visit(exprStmt->ToBase()); } +void BfStructuralVisitor::Visit(BfNamedExpression* namedExpr) +{ + Visit(namedExpr->ToBase()); +} + void BfStructuralVisitor::Visit(BfAttributedExpression* attribExpr) { Visit(attribExpr->ToBase()); @@ -356,6 +361,11 @@ void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr) Visit(offsetOfExpr->ToBase()); } +void BfStructuralVisitor::Visit(BfNameOfExpression* nameOfExpr) +{ + Visit(nameOfExpr->ToBase()); +} + void BfStructuralVisitor::Visit(BfIsConstExpression* isConstExpr) { Visit(isConstExpr->ToBase()); @@ -586,6 +596,11 @@ void BfStructuralVisitor::Visit(BfConstructorDeclaration* ctorDeclaration) Visit(ctorDeclaration->ToBase()); } +void BfStructuralVisitor::Visit(BfAutoConstructorDeclaration* ctorDeclaration) +{ + Visit(ctorDeclaration->ToBase()); +} + void BfStructuralVisitor::Visit(BfDestructorDeclaration* dtorDeclaration) { Visit(dtorDeclaration->ToBase()); @@ -663,7 +678,7 @@ void BfStructuralVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) void BfStructuralVisitor::Visit(BfBlock* block) { - Visit(block->ToBase()); + Visit(block->ToBase()); } void BfStructuralVisitor::Visit(BfUnscopedBlock* block) @@ -678,7 +693,7 @@ void BfStructuralVisitor::Visit(BfBlockExtension* block) void BfStructuralVisitor::Visit(BfRootNode* rootNode) { - Visit(rootNode->ToBase()); + Visit(rootNode->ToBase()); } void BfStructuralVisitor::Visit(BfInlineAsmStatement* asmStmt) @@ -705,7 +720,7 @@ BfAstTypeInfo::BfAstTypeInfo(const char* name, BfAstTypeInfo* baseType, BfAstAcc if (mBaseType != NULL) { mBaseType->mDerivedTypes.Add(this); - } + } sTypeCount++; #ifdef _DEBUG @@ -790,7 +805,7 @@ bool BfAstNode::IsMissingSemicolon() return (attribExpr->mStatement == NULL) || (attribExpr->mStatement->IsMissingSemicolon()); if (auto stmt = BfNodeDynCast(this)) - return stmt->mTrailingSemicolon == NULL; + return stmt->mTrailingSemicolon == NULL; return false; } @@ -822,7 +837,7 @@ bool BfAstNode::WantsWarning(int warningNumber) } bool BfAstNode::LocationEquals(BfAstNode* otherNode) -{ +{ return (GetSourceData() == otherNode->GetSourceData()) && (GetSrcStart() == otherNode->GetSrcStart()) && (GetSrcEnd() == otherNode->GetSrcEnd()); @@ -841,7 +856,7 @@ String BfAstNode::LocationToString() return String(); String loc; - + int line = -1; int lineChar = -1; parserData->GetLineCharAtIdx(mSrcStart, line, lineChar); @@ -854,10 +869,10 @@ String BfAstNode::LocationToString() } void BfAstNode::Add(BfAstNode* bfAstNode) -{ +{ #ifdef BF_AST_HAS_PARENT_MEMBER BF_ASSERT(bfAstNode->mParent == NULL); - bfAstNode->mParent = this; + bfAstNode->mParent = this; #endif if (!IsInitialized()) @@ -887,7 +902,7 @@ void BfAstNode::Add(BfAstNode* bfAstNode) SetSrcStart(childSrcStart); if (childSrcEnd > prevSrcEnd) SetSrcEnd(childSrcEnd); -#else +#else BF_ASSERT(mSrcStart >= 0); BF_ASSERT(bfAstNode->mSrcStart >= 0); @@ -924,14 +939,14 @@ void BfAstNode::RemoveNextSibling() } void BfAstNode::DeleteNextSibling() -{ +{ //mNext->DeleteSelf(); } void BfAstNode::Init(BfParser* bfParser) { BF_ASSERT(GetSourceData() == bfParser->mSourceData); - Init(bfParser->mTriviaStart, bfParser->mTokenStart, bfParser->mTokenEnd); + Init(bfParser->mTriviaStart, bfParser->mTokenStart, bfParser->mTokenEnd); } void BfAstNode::Accept(BfStructuralVisitor* bfVisitor) @@ -950,7 +965,7 @@ bool BfAstNode::IsTemporary() int BfAstNode::GetStartCharId() { - if (!IsTemporary()) + if (!IsTemporary()) { auto bfParser = GetSourceData()->ToParserData(); if (bfParser != NULL) @@ -960,8 +975,8 @@ int BfAstNode::GetStartCharId() } BfSourceData* BfAstNode::GetSourceData() -{ -#ifdef BF_AST_ALLOCATOR_USE_PAGES +{ +#ifdef BF_AST_ALLOCATOR_USE_PAGES //BF_ASSERT((intptr)this > 0x4200000000); BfAstPageHeader* pageHeader = (BfAstPageHeader*)((intptr)this & ~(BfAstAllocManager::PAGE_SIZE - 1)); return pageHeader->mSourceData; @@ -1011,14 +1026,14 @@ String BfAstNode::ToString() int srcLen = GetSrcLength(); if (srcLen <= 0) { - if (auto namedTypeRef = BfNodeDynCast(this)) - return namedTypeRef->mNameNode->ToString(); + if (auto namedTypeRef = BfNodeDynCast(this)) + return namedTypeRef->mNameNode->ToString(); return ""; } auto source = GetSourceData(); - String str(source->mSrc + GetSrcStart(), srcLen); + String str(source->mSrc + GetSrcStart(), srcLen); return str; } @@ -1047,7 +1062,7 @@ void BfAstNode::ToString(StringImpl& str) } auto source = GetSourceData(); - str.Append(source->mSrc + GetSrcStart(), srcLen); + str.Append(source->mSrc + GetSrcStart(), srcLen); } bool BfAstNode::Equals(const StringImpl& str) @@ -1069,7 +1084,7 @@ bool BfAstNode::Equals(const StringView& str) } bool BfAstNode::Equals(const char* str) -{ +{ auto source = GetSourceData(); const char* ptrLhs = source->mSrc + mSrcStart; const char* ptrLhsEnd = source->mSrc + mSrcEnd; @@ -1077,7 +1092,7 @@ bool BfAstNode::Equals(const char* str) while (true) { - char cRhs = *(ptrRhs++); + char cRhs = *(ptrRhs++); if (cRhs == 0) return ptrLhs == ptrLhsEnd; if (ptrLhs == ptrLhsEnd) @@ -1088,7 +1103,6 @@ bool BfAstNode::Equals(const char* str) } } - ////////////////////////////////////////////////////////////////////////// void BfBlock::Init(const SizedArrayImpl& vec, BfAstAllocator* alloc) @@ -1102,18 +1116,18 @@ void BfBlock::Init(const SizedArrayImpl& vec, BfAstAllocator* alloc) { int bytesLeft = alloc->GetCurPageBytesLeft(); int useElems = std::min(bytesLeft / (int)sizeof(ASTREF(BfAstNode*)), elemsLeft); - BfBlockExtension* nextExt = NULL; + BfBlockExtension* nextExt = NULL; BfSizedArray& childArrRef = (curExt != NULL) ? curExt->mChildArr : mChildArr; childArrRef.mVals = (ASTREF(BfAstNode*)*)alloc->AllocBytes(useElems * sizeof(ASTREF(BfAstNode*)), sizeof(ASTREF(BfAstNode*))); childArrRef.mSize = useElems; - if (useElems < elemsLeft) + if (useElems < elemsLeft) { nextExt = alloc->Alloc(); useElems--; } for (int i = 0; i < useElems; i++) - childArrRef[i] = vec[curIdx++]; + childArrRef[i] = vec[curIdx++]; if (nextExt != NULL) { childArrRef[useElems] = nextExt; @@ -1121,7 +1135,7 @@ void BfBlock::Init(const SizedArrayImpl& vec, BfAstAllocator* alloc) } elemsLeft -= useElems; } -#else +#else BfSizedArrayInitIndirect(mChildArr, vec, alloc); #endif } @@ -1147,10 +1161,10 @@ int BfBlock::GetSize() { int size = mChildArr.mSize; if (mChildArr.mSize == 0) - return size; + return size; BfAstNode* backNode = mChildArr.mVals[mChildArr.mSize - 1]; while (true) - { + { if (auto blockExt = BfNodeDynCastExact(backNode)) { size--; @@ -1162,12 +1176,12 @@ int BfBlock::GetSize() break; } } - + return size; } void BfBlock::SetSize(int wantSize) -{ +{ int size = mChildArr.mSize; if (wantSize == size) return; @@ -1380,7 +1394,7 @@ const char* Beefy::BfTokenToString(BfToken token) case BfToken_Extension: return "extension"; case BfToken_Fallthrough: - return "fallthrough"; + return "fallthrough"; case BfToken_Finally: return "finally"; case BfToken_Fixed: @@ -1416,7 +1430,7 @@ const char* Beefy::BfTokenToString(BfToken token) case BfToken_Namespace: return "namespace"; case BfToken_New: - return "new"; + return "new"; case BfToken_Null: return "null"; case BfToken_Nullable: @@ -1568,7 +1582,7 @@ const char* Beefy::BfTokenToString(BfToken token) case BfToken_Colon: return ":"; case BfToken_Comma: - return ","; + return ","; case BfToken_Dot: case BfToken_AutocompleteDot: return "."; @@ -1635,7 +1649,7 @@ bool Beefy::BfTokenIsKeyword(BfToken token) BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp) { switch (assignmentOp) - { + { case BfAssignmentOp_Add: return BfBinaryOp_Add; case BfAssignmentOp_Subtract: @@ -1671,9 +1685,9 @@ BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp) } int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp) -{ +{ switch (binOp) - { + { case BfBinaryOp_Multiply: case BfBinaryOp_OverflowMultiply: case BfBinaryOp_Divide: @@ -1683,7 +1697,7 @@ int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp) case BfBinaryOp_Subtract: case BfBinaryOp_OverflowAdd: case BfBinaryOp_OverflowSubtract: - return 13; + return 13; case BfBinaryOp_LeftShift: case BfBinaryOp_RightShift: return 12; @@ -1712,7 +1726,7 @@ int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp) case BfBinaryOp_StrictInEquality: return 4; case BfBinaryOp_ConditionalAnd: - return 3; + return 3; case BfBinaryOp_ConditionalOr: return 2; case BfBinaryOp_NullCoalesce: @@ -1768,6 +1782,7 @@ const char* Beefy::BfGetOpName(BfUnaryOp unaryOp) { case BfUnaryOp_None: return ""; case BfUnaryOp_AddressOf: return "&"; + case BfUnaryOp_Arrow: return "->"; case BfUnaryOp_Dereference: return "*"; case BfUnaryOp_Negate: return "-"; case BfUnaryOp_Not: return "!"; @@ -1786,7 +1801,7 @@ const char* Beefy::BfGetOpName(BfUnaryOp unaryOp) case BfUnaryOp_FromEnd: return "^"; case BfUnaryOp_PartialRangeUpTo: return "..<"; case BfUnaryOp_PartialRangeThrough: return "..."; - case BfUnaryOp_PartialRangeFrom: return "..."; + case BfUnaryOp_PartialRangeFrom: return "..."; default: return "???"; } } @@ -1862,6 +1877,8 @@ BfUnaryOp Beefy::BfTokenToUnaryOp(BfToken token) return BfUnaryOp_Dereference; case BfToken_Ampersand: return BfUnaryOp_AddressOf; + case BfToken_Arrow: + return BfUnaryOp_Arrow; case BfToken_Minus: return BfUnaryOp_Negate; case BfToken_Bang: @@ -1916,7 +1933,6 @@ bool Beefy::BfCanOverloadOperator(BfUnaryOp unaryOp) } } - BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token) { switch (token) @@ -1928,7 +1944,7 @@ BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token) case BfToken_MinusEquals: return BfAssignmentOp_Subtract; case BfToken_MultiplyEquals: - return BfAssignmentOp_Multiply; + return BfAssignmentOp_Multiply; case BfToken_AndPlusEquals: return BfAssignmentOp_OverflowAdd; case BfToken_AndMinusEquals: @@ -2130,4 +2146,4 @@ String BfInlineAsmInstruction::AsmInst::ToString() } return s; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 4e8dacf0..c21d46fb 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -53,7 +53,7 @@ class BfPassInstance; enum BfProtection : uint8 { BfProtection_Hidden, - BfProtection_Private, + BfProtection_Private, BfProtection_Internal, BfProtection_Protected, BfProtection_ProtectedInternal, @@ -70,7 +70,7 @@ enum BfCheckedKind : int8 }; static bool CheckProtection(BfProtection protection, bool allowProtected, bool allowPrivate) -{ +{ return (protection == BfProtection_Public) || ((protection == BfProtection_Protected) && (allowProtected)) || ((protection == BfProtection_Private) && (allowPrivate)); @@ -92,10 +92,10 @@ struct BfVariant int64 mInt64; uint64 mUInt64; float mSingle; - double mDouble; + double mDouble; String* mString; void* mPtr; - }; + }; double ToDouble() { if (mTypeCode == BfTypeCode_Double) @@ -145,15 +145,15 @@ enum BfToken : uint8 BfToken_Explicit, BfToken_Extern, BfToken_Extension, - BfToken_Fallthrough, + BfToken_Fallthrough, BfToken_Finally, BfToken_Fixed, BfToken_For, BfToken_Function, BfToken_Goto, - BfToken_If, + BfToken_If, BfToken_Implicit, - BfToken_In, + BfToken_In, BfToken_Inline, BfToken_Interface, BfToken_Internal, @@ -164,14 +164,14 @@ enum BfToken : uint8 BfToken_Mut, BfToken_NameOf, BfToken_Namespace, - BfToken_New, + BfToken_New, BfToken_Null, BfToken_Nullable, BfToken_OffsetOf, BfToken_Operator, BfToken_Out, BfToken_Override, - BfToken_Params, + BfToken_Params, BfToken_Private, BfToken_Protected, BfToken_Public, @@ -179,10 +179,10 @@ enum BfToken : uint8 BfToken_Repeat, BfToken_Ref, BfToken_RetType, - BfToken_Return, + BfToken_Return, BfToken_Scope, BfToken_Sealed, - BfToken_SizeOf, + BfToken_SizeOf, BfToken_Stack, BfToken_Static, BfToken_StrideOf, @@ -200,10 +200,10 @@ enum BfToken : uint8 BfToken_Virtual, BfToken_Volatile, BfToken_When, - BfToken_Where, - BfToken_While, + BfToken_Where, + BfToken_While, BfToken_Yield, - BfToken_AssignEquals, + BfToken_AssignEquals, BfToken_CompareEquals, BfToken_CompareStrictEquals, BfToken_CompareNotEquals, @@ -238,7 +238,7 @@ enum BfToken : uint8 BfToken_RChevron, BfToken_LDblChevron, BfToken_RDblChevron, - BfToken_Semicolon, + BfToken_Semicolon, BfToken_Colon, BfToken_Comma, BfToken_Dot, @@ -251,9 +251,9 @@ enum BfToken : uint8 BfToken_Plus, BfToken_Minus, BfToken_DblPlus, - BfToken_DblMinus, + BfToken_DblMinus, BfToken_Star, - BfToken_ForwardSlash, + BfToken_ForwardSlash, BfToken_Modulus, BfToken_Ampersand, BfToken_At, @@ -278,6 +278,7 @@ class BfStatement; class BfLabelableStatement; class BfExpression; class BfExpressionStatement; +class BfNamedExpression; class BfAttributedExpression; class BfAttributedStatement; class BfLiteralExpression; @@ -380,6 +381,7 @@ class BfTypeAttrExpression; class BfSizeOfExpression; class BfAlignOfExpression; class BfOffsetOfExpression; +class BfNameOfExpression; class BfStrideOfExpression; class BfIsConstExpression; class BfDefaultExpression; @@ -407,7 +409,7 @@ public: bool mCapturingChildRef; BfAstNode** mCurChildRef; -public: +public: void VisitMembers(BfBlock* node); void VisitChildNoRef(BfAstNode* nodeRef); void DoVisitChild(BfAstNode*& nodeRef); @@ -428,7 +430,7 @@ public: } nodeRef->Accept(this); mCurChildRef = NULL; - } + } template void VisitChildNoRef(const T& nodeRef) { @@ -440,14 +442,15 @@ public: public: BfStructuralVisitor(); - virtual void Visit(BfAstNode* bfAstNode) {} + virtual void Visit(BfAstNode* bfAstNode) {} virtual void Visit(BfErrorNode* bfErrorNode); virtual void Visit(BfScopeNode* scopeNode); virtual void Visit(BfNewNode* newNode); virtual void Visit(BfLabeledBlock* labeledBlock); virtual void Visit(BfExpression* expr); virtual void Visit(BfExpressionStatement* exprStmt); - virtual void Visit(BfAttributedExpression* attribExpr); + virtual void Visit(BfNamedExpression* namedExpr); + virtual void Visit(BfAttributedExpression* attribExpr); virtual void Visit(BfStatement* stmt); virtual void Visit(BfAttributedStatement* attribStmt); virtual void Visit(BfLabelableStatement* labelableStmt); @@ -464,21 +467,21 @@ public: virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints); virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode); - virtual void Visit(BfEmptyStatement* emptyStmt); - virtual void Visit(BfTokenNode* tokenNode); - virtual void Visit(BfTokenPairNode* tokenPairNode); + virtual void Visit(BfEmptyStatement* emptyStmt); + virtual void Visit(BfTokenNode* tokenNode); + virtual void Visit(BfTokenPairNode* tokenPairNode); virtual void Visit(BfUsingSpecifierNode* usingSpecifier); virtual void Visit(BfLiteralExpression* literalExpr); virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression); virtual void Visit(BfIdentifierNode* identifierNode); virtual void Visit(BfAttributedIdentifierNode* attrIdentifierNode); - virtual void Visit(BfQualifiedNameNode* nameNode); + virtual void Visit(BfQualifiedNameNode* nameNode); virtual void Visit(BfThisExpression* thisExpr); virtual void Visit(BfBaseExpression* baseExpr); virtual void Visit(BfMixinExpression* thisExpr); virtual void Visit(BfSizedArrayCreateExpression* createExpr); virtual void Visit(BfInitializerExpression* collectionInitExpr); - virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); + virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); virtual void Visit(BfTypeReference* typeRef); virtual void Visit(BfNamedTypeReference* typeRef); virtual void Visit(BfQualifiedTypeReference* qualifiedType); @@ -493,19 +496,20 @@ public: virtual void Visit(BfArrayTypeRef* typeRef); virtual void Visit(BfGenericInstanceTypeRef* typeRef); virtual void Visit(BfTupleTypeRef* typeRef); - virtual void Visit(BfDelegateTypeRef* typeRef); + virtual void Visit(BfDelegateTypeRef* typeRef); virtual void Visit(BfExprModTypeRef* declTypeRef); virtual void Visit(BfPointerTypeRef* typeRef); virtual void Visit(BfNullableTypeRef* typeRef); - virtual void Visit(BfVariableDeclaration* varDecl); + virtual void Visit(BfVariableDeclaration* varDecl); virtual void Visit(BfLocalMethodDeclaration* methodDecl); - virtual void Visit(BfParameterDeclaration* paramDecl); + virtual void Visit(BfParameterDeclaration* paramDecl); virtual void Visit(BfTypeAttrExpression* typeAttrExpr); virtual void Visit(BfTypeOfExpression* typeOfExpr); - virtual void Visit(BfSizeOfExpression* sizeOfExpr); + virtual void Visit(BfSizeOfExpression* sizeOfExpr); virtual void Visit(BfAlignOfExpression* alignOfExpr); - virtual void Visit(BfStrideOfExpression* strideOfExpr); + virtual void Visit(BfStrideOfExpression* strideOfExpr); virtual void Visit(BfOffsetOfExpression* offsetOfExpr); + virtual void Visit(BfNameOfExpression* nameOfExpr); virtual void Visit(BfIsConstExpression* isConstExpr); virtual void Visit(BfDefaultExpression* defaultExpr); virtual void Visit(BfUninitializedExpression* uninitializedExpr); @@ -515,9 +519,9 @@ public: virtual void Visit(BfDelegateBindExpression* delegateBindExpr); virtual void Visit(BfLambdaBindExpression* lambdaBindExpr); virtual void Visit(BfObjectCreateExpression* objCreateExpr); - virtual void Visit(BfBoxExpression* boxExpr); + virtual void Visit(BfBoxExpression* boxExpr); virtual void Visit(BfScopedInvocationTarget* scopedTarget); - virtual void Visit(BfInvocationExpression* invocationExpr); + virtual void Visit(BfInvocationExpression* invocationExpr); virtual void Visit(BfEnumCaseBindExpression* caseBindExpr); virtual void Visit(BfCaseExpression* caseExpr); virtual void Visit(BfSwitchCase* switchCase); @@ -530,7 +534,7 @@ public: virtual void Visit(BfUncheckedStatement* uncheckedStmt); virtual void Visit(BfIfStatement* ifStmt); virtual void Visit(BfThrowStatement* throwStmt); - virtual void Visit(BfDeleteStatement* deleteStmt); + virtual void Visit(BfDeleteStatement* deleteStmt); virtual void Visit(BfReturnStatement* returnStmt); virtual void Visit(BfYieldStatement* returnStmt); virtual void Visit(BfBreakStatement* breakStmt); @@ -539,7 +543,7 @@ public: virtual void Visit(BfUsingStatement* whileStmt); virtual void Visit(BfDoStatement* whileStmt); virtual void Visit(BfRepeatStatement* repeatStmt); - virtual void Visit(BfWhileStatement* whileStmt); + virtual void Visit(BfWhileStatement* whileStmt); virtual void Visit(BfForStatement* forStmt); virtual void Visit(BfForEachStatement* forEachStmt); virtual void Visit(BfDeferStatement* deferStmt); @@ -552,6 +556,7 @@ public: virtual void Visit(BfUnaryOperatorExpression* binOpExpr); virtual void Visit(BfBinaryOperatorExpression* binOpExpr); virtual void Visit(BfConstructorDeclaration* ctorDeclaration); + virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration); virtual void Visit(BfDestructorDeclaration* dtorDeclaration); virtual void Visit(BfMethodDeclaration* methodDeclaration); virtual void Visit(BfOperatorDeclaration* operatorDeclaration); @@ -578,6 +583,7 @@ public: enum BfTypedValueKind { BfTypedValueKind_Addr, + BfTypedValueKind_VolatileAddr, BfTypedValueKind_CopyOnMutateAddr, BfTypedValueKind_CopyOnMutateAddr_Derived, BfTypedValueKind_ReadOnlyAddr, @@ -586,18 +592,18 @@ enum BfTypedValueKind BfTypedValueKind_ReadOnlyTempAddr, BfTypedValueKind_ThisAddr, BfTypedValueKind_BaseAddr, - BfTypedValueKind_ReadOnlyThisAddr, + BfTypedValueKind_ReadOnlyThisAddr, BfTypedValueKind_ReadOnlyBaseAddr, BfTypedValueKind_Value, - BfTypedValueKind_ThisValue, - BfTypedValueKind_BaseValue, - BfTypedValueKind_ReadOnlyThisValue, + BfTypedValueKind_ThisValue, + BfTypedValueKind_BaseValue, + BfTypedValueKind_ReadOnlyThisValue, BfTypedValueKind_ReadOnlyBaseValue, BfTypedValueKind_MutableValue, // Only applicable for generic params BfTypedValueKind_SplatHead, BfTypedValueKind_ThisSplatHead, - BfTypedValueKind_BaseSplatHead, + BfTypedValueKind_BaseSplatHead, BfTypedValueKind_SplatHead_NeedsCasting, BfTypedValueKind_ParamsSplat, BfTypedValueKind_Params, @@ -613,11 +619,11 @@ public: //llvm::Value* mValue; BfIRValue mValue; BfType* mType; - BfTypedValueKind mKind; // Is address of variable + BfTypedValueKind mKind; // Is address of variable public: BfTypedValue() - { + { mType = NULL; mKind = BfTypedValueKind_NoValue; } @@ -638,7 +644,7 @@ public: { BF_ASSERT((!val) || (resolvedType != NULL)); mValue = val; - mType = resolvedType; + mType = resolvedType; mKind = isAddr ? BfTypedValueKind_Addr : BfTypedValueKind_Value; #ifdef _DEBUG //DbgCheckType(); @@ -656,7 +662,7 @@ public: } BfTypedValue(BfIRValue val, BfType* resolvedType, BfTypedValueKind kind = BfTypedValueKind_Value) - { + { BF_ASSERT((!val) || (resolvedType != NULL)); mValue = val; mType = resolvedType; @@ -728,13 +734,13 @@ public: bool IsThis() const { - return (mKind == BfTypedValueKind_ThisValue) || (mKind == BfTypedValueKind_ThisAddr) || (mKind == BfTypedValueKind_ReadOnlyThisValue) || + return (mKind == BfTypedValueKind_ThisValue) || (mKind == BfTypedValueKind_ThisAddr) || (mKind == BfTypedValueKind_ReadOnlyThisValue) || (mKind == BfTypedValueKind_ReadOnlyThisAddr) || (mKind == BfTypedValueKind_ThisSplatHead); } bool IsBase() const { - return (mKind == BfTypedValueKind_BaseValue) || (mKind == BfTypedValueKind_BaseAddr) || (mKind == BfTypedValueKind_ReadOnlyBaseValue) || + return (mKind == BfTypedValueKind_BaseValue) || (mKind == BfTypedValueKind_BaseAddr) || (mKind == BfTypedValueKind_ReadOnlyBaseValue) || (mKind == BfTypedValueKind_ReadOnlyBaseAddr) || (mKind == BfTypedValueKind_BaseSplatHead); } @@ -750,11 +756,16 @@ public: mKind = (BfTypedValueKind)((int)mKind - 1); } + bool IsVolatile() const + { + return mKind == BfTypedValueKind_VolatileAddr; + } + bool IsSplat() const { return (mKind >= BfTypedValueKind_SplatHead) && (mKind <= BfTypedValueKind_ParamsSplat); } - + bool IsUntypedValue() const { return (mKind == BfTypedValueKind_UntypedValue); @@ -792,6 +803,21 @@ public: } } + void MakeTemporary(bool restricted = false) + { + switch (mKind) + { + case BfTypedValueKind_Addr: + mKind = restricted ? BfTypedValueKind_RestrictedTempAddr : BfTypedValueKind_TempAddr; + break; + case BfTypedValueKind_ReadOnlyAddr: + mKind = BfTypedValueKind_ReadOnlyTempAddr; + break; + default: + break; + } + } + bool CanModify() const; }; @@ -980,7 +1006,7 @@ public: } ~BfDeferredSizedArray() - { + { mSizedArray->mSize = (int)this->size(); if (mSizedArray->mSize > 0) { @@ -998,7 +1024,7 @@ public: template static void BfSizedArrayInitIndirect(BfSizedArray& sizedArray, const SizedArrayImpl& vec, BfAstAllocator* alloc) -{ +{ sizedArray.mSize = (int)vec.size(); BF_ASSERT(sizedArray.mSize >= 0); if (sizedArray.mSize > 0) @@ -1006,26 +1032,26 @@ static void BfSizedArrayInitIndirect(BfSizedArray& sizedArray, const SizedArr sizedArray.mVals = (T*)alloc->AllocBytes(sizedArray.mSize * sizeof(T), sizeof(T)); for (int i = 0; i < sizedArray.mSize; i++) sizedArray.mVals[i] = vec[i]; - } + } } template class BfDeferredAstSizedArray : public SizedArray { -public: +public: BfSizedArray* mSizedArray; BfAstAllocator* mAlloc; public: BfDeferredAstSizedArray(BfSizedArray& arr, BfAstAllocator* alloc) - { + { mSizedArray = &arr; - mAlloc = alloc; + mAlloc = alloc; } ~BfDeferredAstSizedArray() - { - BfSizedArrayInitIndirect(*mSizedArray, *this, mAlloc); + { + BfSizedArrayInitIndirect(*mSizedArray, *this, mAlloc); } }; @@ -1061,38 +1087,38 @@ struct BfAstInfo class BfAstNode { public: - static BfAstTypeInfo sTypeInfo; - + static BfAstTypeInfo sTypeInfo; + #ifndef BF_AST_ALLOCATOR_USE_PAGES BfSourceData* mSourceData; #endif #ifdef BF_AST_HAS_PARENT_MEMBER - BfAstNode* mParent; + BfAstNode* mParent; #endif #ifdef BF_AST_COMPACT union { struct - { + { uint8 mCompact_TriviaLen; uint8 mCompact_SrcLen; uint8 mCompact_TypeId; BfToken mCompact_Token; int mCompact_SrcStart : 31; - int mIsCompact : 1; + int mIsCompact : 1; }; BfAstInfo* mAstInfo; }; #else int mTriviaStart; int mSrcStart; - int mSrcEnd; + int mSrcEnd; uint8 mTypeId; BfToken mToken; #endif -public: +public: BfAstNode() { #ifdef BF_AST_COMPACT @@ -1112,7 +1138,7 @@ public: { } #endif - + void RemoveSelf(); void DeleteSelf(); void RemoveNextSibling(); @@ -1140,16 +1166,16 @@ public: bool IsMissingSemicolon(); bool IsExpression(); bool WantsWarning(int warningNumber); - + template bool IsA() - { - return (uint)GetTypeId() - (uint)T::sTypeInfo.mTypeId <= (uint)T::sTypeInfo.mFullDerivedCount; + { + return (uint)GetTypeId() - (uint)T::sTypeInfo.mTypeId <= (uint)T::sTypeInfo.mFullDerivedCount; } template bool IsExact() - { + { return (uint)GetTypeId() == (uint)T::sTypeInfo.mTypeId; } @@ -1157,7 +1183,7 @@ public: BfAstInfo* AllocAstInfo(); void InitEmpty() - { + { mIsCompact = true; mCompact_SrcStart = 0; mCompact_SrcLen = 0; @@ -1193,7 +1219,7 @@ public: { int triviaLen = srcStart - triviaStart; int srcLen = srcEnd - srcStart; - if ((triviaLen <= 255) && (srcLen <= 255)) + if ((triviaLen <= 255) && (srcLen <= 255)) { mCompact_SrcStart = srcStart; mIsCompact = 1; @@ -1209,8 +1235,8 @@ public: astInfo->mSrcStart = srcStart; astInfo->mSrcEnd = srcEnd; mAstInfo = astInfo; - } - } + } + } int GetTypeId() { @@ -1252,7 +1278,7 @@ public: mCompact_TriviaLen = (uint8)triviaLen; return; } - + auto astInfo = AllocAstInfo(); astInfo->mTypeId = mCompact_TypeId; astInfo->mToken = mCompact_Token; @@ -1260,7 +1286,7 @@ public: astInfo->mSrcEnd = mCompact_SrcStart + mCompact_SrcLen; mAstInfo = astInfo; } - + mAstInfo->mTriviaStart = triviaStart; } @@ -1293,7 +1319,7 @@ public: astInfo->mTriviaStart = srcStart - triviaLen; astInfo->mSrcEnd = srcStart + srcLen; mAstInfo = astInfo; - } + } } else mAstInfo->mSrcStart = srcStart; @@ -1352,7 +1378,7 @@ public: { mTriviaStart = 0; mSrcStart = 0; - mSrcEnd = 0; + mSrcEnd = 0; } void InitWithTypeId(int typeId) @@ -1452,7 +1478,6 @@ public: } #endif - #ifdef BF_AST_HAS_PARENT_MEMBER template T* FindParentOfType() @@ -1492,13 +1517,13 @@ public: template static void Zero(T* val) - { + { #ifdef BF_AST_COMPACT memset((uint8*)val + offsetof(T, mAstInfo), 0, sizeof(T) - offsetof(T, mAstInfo)); #else memset((uint8*)val + offsetof(T, mTriviaStart), 0, sizeof(T) - offsetof(T, mTriviaStart)); #endif - val->InitWithTypeId(T::sTypeInfo.mTypeId); + val->InitWithTypeId(T::sTypeInfo.mTypeId); } #endif }; @@ -1507,11 +1532,11 @@ BfAstTypeInfo BfAstNode::sTypeInfo("BfAstNode", NULL, &BfAstNode::ClassAccept); #endif template -bool BfNodeIsA(BfAstNode* node) -{ +bool BfNodeIsA(BfAstNode* node) +{ if (node == NULL) return false; - + bool canCast = (uint)node->GetTypeId() - (uint)T::sTypeInfo.mTypeId <= (uint)T::sTypeInfo.mFullDerivedCount; return canCast; } @@ -1530,8 +1555,8 @@ template T* BfNodeDynCast(BfAstNode* node) { if (node == NULL) - return NULL; - + return NULL; + bool canCast = (uint)node->GetTypeId() - (uint)T::sTypeInfo.mTypeId <= (uint)T::sTypeInfo.mFullDerivedCount; //BF_ASSERT(canCast == (node->DynCast(T::TypeId) != NULL)); return canCast ? (T*)node : NULL; @@ -1542,7 +1567,7 @@ T* BfNodeDynCastExact(BfAstNode* node) { if (node == NULL) return NULL; - + bool canCast = node->GetTypeId() == T::sTypeInfo.mTypeId; //BF_ASSERT(canCast == (node->GetTypeId() == T::TypeId)); return canCast ? (T*)node : NULL; @@ -1681,12 +1706,12 @@ public: } bool operator!=(const Iterator& itr) const - { + { return itr.mPtr != mPtr; } bool operator==(const Iterator& itr) const - { + { return itr.mPtr == mPtr; } @@ -1716,7 +1741,7 @@ public: //BfDebugArray mChildArr; BfSizedArray mChildArr; -public: +public: using BfAstNode::Init; void Init(const SizedArrayImpl& vec, BfAstAllocator* alloc); BfAstNode* GetFirst(); @@ -1748,7 +1773,7 @@ public: BfBlockExtension* blockExt = (BfBlockExtension*)(BfAstNode*)childArr->mVals[childArr->mSize - 1]; BF_ASSERT(blockExt->GetTypeId() == BfBlockExtension::TypeId); childArr = &blockExt->mChildArr; - } + } #else return mChildArr.mVals[idx]; #endif @@ -1785,7 +1810,7 @@ public: mTypedValue = typedValue; mRefNode = NULL; #ifdef BF_AST_HAS_PARENT_MEMBER - mParent = NULL; + mParent = NULL; #endif } }; BF_AST_DECL(BfTypedValueExpression, BfExpression); @@ -1880,6 +1905,7 @@ enum BfUnaryOp { BfUnaryOp_None, BfUnaryOp_AddressOf, + BfUnaryOp_Arrow, BfUnaryOp_Dereference, BfUnaryOp_Negate, BfUnaryOp_Not, @@ -1904,7 +1930,7 @@ enum BfUnaryOp class BfTokenNode : public BfAstNode { public: - BF_AST_TYPE(BfTokenNode, BfAstNode); + BF_AST_TYPE(BfTokenNode, BfAstNode); }; BF_AST_DECL(BfTokenNode, BfAstNode); class BfScopeNode : public BfAstNode @@ -1924,7 +1950,7 @@ public: BF_AST_TYPE(BfNewNode, BfAstNode); BfTokenNode* mNewToken; - BfTokenNode* mColonToken; + BfTokenNode* mColonToken; BfAstNode* mAllocNode; // Expression or BfScopedInvocationTarget BfAttributeDirective* mAttributes; }; BF_AST_DECL(BfNewNode, BfAstNode); @@ -1936,7 +1962,7 @@ enum BfCommentKind BfCommentKind_Documentation_Block_Pre, BfCommentKind_Documentation_Line_Pre, BfCommentKind_Documentation_Block_Post, - BfCommentKind_Documentation_Line_Post, + BfCommentKind_Documentation_Line_Post, }; class BfCommentNode : public BfAstNode @@ -1969,15 +1995,15 @@ public: BF_AST_TYPE(BfPreprocessorNode, BfAstNode); BfIdentifierNode* mCommand; - BfBlock* mArgument; + BfBlock* mArgument; }; BF_AST_DECL(BfPreprocessorNode, BfAstNode); class BfPreprocessorDefinedExpression : public BfExpression -{ +{ public: BF_AST_TYPE(BfPreprocessorDefinedExpression, BfExpression); - BfIdentifierNode* mIdentifier; + BfIdentifierNode* mIdentifier; }; BF_AST_DECL(BfPreprocessorDefinedExpression, BfExpression); class BfReplaceNode : public BfAstNode @@ -1999,7 +2025,7 @@ public: BF_AST_TYPE(BfAttributedIdentifierNode, BfExpression); BfIdentifierNode* mIdentifier; - BfAttributeDirective* mAttributes; + BfAttributeDirective* mAttributes; }; BF_AST_DECL(BfAttributedIdentifierNode, BfExpression); class BfQualifiedNameNode : public BfIdentifierNode @@ -2017,8 +2043,8 @@ class BfUsingDirective : public BfStatement public: BF_AST_TYPE(BfUsingDirective, BfStatement); - BfTokenNode* mUsingToken; - BfIdentifierNode* mNamespace; + BfTokenNode* mUsingToken; + BfIdentifierNode* mNamespace; }; BF_AST_DECL(BfUsingDirective, BfStatement); class BfUsingModDirective : public BfStatement @@ -2042,7 +2068,7 @@ public: class BfAttributeDirective : public BfAstNode { -public: +public: BF_AST_TYPE(BfAttributeDirective, BfAstNode); ASTREF(BfTokenNode*) mAttrOpenToken; // [ @ , @@ -2199,7 +2225,7 @@ public: BfTokenNode* mOpenBrace; BfSizedArray mValues; BfSizedArray mCommas; - BfTokenNode* mCloseBrace; + BfTokenNode* mCloseBrace; }; BF_AST_DECL(BfCollectionInitializerExpression, BfExpression); class BfSizedArrayCreateExpression : public BfExpression @@ -2236,7 +2262,7 @@ public: BF_AST_TYPE(BfTupleExpression, BfExpression); BfTokenNode* mOpenParen; - BfSizedArray mNames; + BfSizedArray mNames; BfSizedArray mValues; BfSizedArray mCommas; ASTREF(BfTokenNode*) mCloseParen; @@ -2280,7 +2306,7 @@ public: BfTokenNode* mCaseToken; BfSizedArray mCaseExpressions; BfSizedArray mCaseCommas; - BfTokenNode* mColonToken; + BfTokenNode* mColonToken; BfBlock* mCodeBlock; // May or may not have braces set BfTokenNode* mEndingToken; // Null, Fallthrough, or Break BfTokenNode* mEndingSemicolonToken; @@ -2337,14 +2363,14 @@ public: BfCommentNode* mDocumentation; BfAttributeDirective* mAttributes; - BfTokenNode* mAbstractSpecifier; - BfTokenNode* mSealedSpecifier; + BfTokenNode* mAbstractSpecifier; + BfTokenNode* mSealedSpecifier; BfAstNode* mProtectionSpecifier; BfTokenNode* mStaticSpecifier; BfTokenNode* mPartialSpecifier; BfTokenNode* mTypeNode; - BfIdentifierNode* mNameNode; - BfAstNode* mDefineNode; + BfIdentifierNode* mNameNode; + BfAstNode* mDefineNode; BfAutoConstructorDeclaration* mAutoCtor; BfGenericParamsDeclaration* mGenericParams; BfGenericConstraintsDeclaration* mGenericConstraintsDeclaration; @@ -2353,7 +2379,6 @@ public: BfTokenNode* mColonToken; BfSizedArray mBaseClasses; BfSizedArray mBaseClassCommas; - }; BF_AST_DECL(BfTypeDeclaration, BfAstNode); class BfTypeAliasDeclaration : public BfTypeDeclaration @@ -2364,32 +2389,29 @@ public: BfTokenNode* mEqualsToken; BfTypeReference* mAliasToType; BfTokenNode* mEndSemicolon; - }; BF_AST_DECL(BfTypeAliasDeclaration, BfTypeDeclaration); class BfTypeReference : public BfAstNode { public: - BF_AST_TYPE(BfTypeReference, BfAstNode); + BF_AST_TYPE(BfTypeReference, BfAstNode); bool IsNamedTypeReference(); bool IsTypeDefTypeReference(); String ToCleanAttributeString(); - }; BF_AST_DECL(BfTypeReference, BfAstNode); class BfDirectTypeReference : public BfTypeReference { public: - BF_AST_TYPE(BfDirectTypeReference, BfAstNode); + BF_AST_TYPE(BfDirectTypeReference, BfAstNode); BfType* mType; void Init(BfType* type) { mType = type; InitEmpty(); - } - + } }; BF_AST_DECL(BfDirectTypeReference, BfAstNode); class BfDirectTypeDefReference : public BfTypeReference @@ -2403,14 +2425,13 @@ public: mTypeDef = type; InitEmpty(); } - }; BF_AST_DECL(BfDirectTypeDefReference, BfTypeReference); // class BfTypeDefTypeReference : public BfTypeReference // { // public: // BF_AST_TYPE(BfTypeDefTypeReference, BfTypeReference); -// +// // BfTypeDef* mTypeDef; // }; BF_AST_DECL(BfTypeDefTypeReference, BfTypeReference); @@ -2430,8 +2451,8 @@ public: mParent = NULL; #endif InitEmpty(); - //mTypeDef = NULL; - } + //mTypeDef = NULL; + } }; BF_AST_DECL(BfDirectStrTypeReference, BfTypeReference); class BfDotTypeReference : public BfTypeReference @@ -2552,7 +2573,7 @@ public: BF_AST_TYPE(BfGenericInstanceTypeRef, BfElementedTypeRef); BfTokenNode* mOpenChevron; - BfSizedArray mGenericArguments; + BfSizedArray mGenericArguments; BfSizedArray mCommas; BfTokenNode* mCloseChevron; int GetGenericArgCount() @@ -2608,7 +2629,7 @@ public: }; BF_AST_DECL(BfExprModTypeRef, BfTypeReference); enum BfGenericParamKind -{ +{ BfGenericParamKind_Type, BfGenericParamKind_Method }; @@ -2626,7 +2647,7 @@ class BfPointerTypeRef : public BfElementedTypeRef { public: BF_AST_TYPE(BfPointerTypeRef, BfElementedTypeRef); - + BfTokenNode* mStarNode; }; BF_AST_DECL(BfPointerTypeRef, BfElementedTypeRef); @@ -2685,7 +2706,7 @@ public: class BfAlignOfExpression : public BfTypeAttrExpression { public: - BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression); + BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression); }; BF_AST_DECL(BfAlignOfExpression, BfTypeAttrExpression); class BfStrideOfExpression : public BfTypeAttrExpression @@ -2694,7 +2715,6 @@ public: BF_AST_TYPE(BfStrideOfExpression, BfTypeAttrExpression); }; BF_AST_DECL(BfStrideOfExpression, BfTypeAttrExpression); - class BfOffsetOfExpression : public BfTypeAttrExpression { public: @@ -2704,6 +2724,16 @@ public: BfIdentifierNode* mMemberName; }; BF_AST_DECL(BfOffsetOfExpression, BfTypeAttrExpression); +class BfNameOfExpression : public BfExpression +{ +public: + BF_AST_TYPE(BfNameOfExpression, BfExpression); + BfTokenNode* mToken; + BfTokenNode* mOpenParen; + BfAstNode* mTarget; + BfTokenNode* mCloseParen; +}; BF_AST_DECL(BfNameOfExpression, BfExpression); + class BfIsConstExpression : public BfExpression { public: @@ -2751,17 +2781,17 @@ public: BfExpression* mTarget; BfTokenNode* mAsToken; - BfTypeReference* mTypeRef; + BfTypeReference* mTypeRef; }; BF_AST_DECL(BfDynamicCastExpression, BfExpression); class BfCastExpression : public BfUnaryOperatorExpression { public: BF_AST_TYPE(BfCastExpression, BfUnaryOperatorExpression); - + BfTokenNode* mOpenParen; BfTypeReference* mTypeRef; - BfTokenNode* mCloseParen; + BfTokenNode* mCloseParen; }; BF_AST_DECL(BfCastExpression, BfUnaryOperatorExpression); class BfDelegateBindExpression : public BfMethodBoundExpression @@ -2780,16 +2810,26 @@ class BfLambdaBindExpression : public BfExpression public: BF_AST_TYPE(BfLambdaBindExpression, BfExpression); - BfAstNode* mNewToken; + BfAstNode* mNewToken; BfTokenNode* mOpenParen; - BfTokenNode* mCloseParen; + BfTokenNode* mCloseParen; BfSizedArray mParams; BfSizedArray mCommas; - BfTokenNode* mFatArrowToken; + BfTokenNode* mFatArrowToken; BfAstNode* mBody; // Either expression or block BfFieldDtorDeclaration* mDtor; }; BF_AST_DECL(BfLambdaBindExpression, BfExpression); +class BfNamedExpression : public BfExpression +{ +public: + BF_AST_TYPE(BfNamedExpression, BfExpression); + + BfIdentifierNode* mNameNode; + BfTokenNode* mColonToken; + BfExpression* mExpression; +}; BF_AST_DECL(BfNamedExpression, BfExpression); + class BfAttributedExpression : public BfExpression { public: @@ -2815,11 +2855,11 @@ public: BfAstNode* mNewNode; BfTokenNode* mStarToken; - BfTypeReference* mTypeRef; + BfTypeReference* mTypeRef; BfTokenNode* mOpenToken; - BfTokenNode* mCloseToken; + BfTokenNode* mCloseToken; BfSizedArray mArguments; - BfSizedArray mCommas; + BfSizedArray mCommas; }; BF_AST_DECL(BfObjectCreateExpression, BfMethodBoundExpression); class BfBoxExpression : public BfExpression @@ -2837,7 +2877,7 @@ class BfDeleteStatement : public BfStatement public: BF_AST_TYPE(BfDeleteStatement, BfStatement); - BfTokenNode* mDeleteToken; + BfTokenNode* mDeleteToken; BfTokenNode* mTargetTypeToken; // colon token BfAstNode* mAllocExpr; BfAttributeDirective* mAttributes; @@ -2848,11 +2888,11 @@ class BfDeferBindNode : public BfAstNode { public: BF_AST_TYPE(BfDeferBindNode, BfAstNode); - + BfTokenNode* mOpenBracket; BfTokenNode* mCloseBracket; BfSizedArray mParams; - BfSizedArray mCommas; + BfSizedArray mCommas; }; BF_AST_DECL(BfDeferBindNode, BfAstNode); class BfDeferStatement : public BfStatement @@ -2908,7 +2948,7 @@ public: ASTREF(BfTokenNode*) mCloseParen; ASTREF(BfGenericArgumentsNode*) mGenericArgs; BfSizedArray mArguments; - BfSizedArray mCommas; + BfSizedArray mCommas; }; BF_AST_DECL(BfInvocationExpression, BfMethodBoundExpression); class BfEnumCaseDeclaration : public BfAstNode @@ -2918,7 +2958,7 @@ public: ASTREF(BfTokenNode*) mCaseToken; BfSizedArray mEntries; - BfSizedArray mCommas; + BfSizedArray mCommas; }; BF_AST_DECL(BfEnumCaseDeclaration, BfAstNode); class BfMemberDeclaration : public BfAstNode @@ -2926,9 +2966,9 @@ class BfMemberDeclaration : public BfAstNode public: BF_AST_TYPE(BfMemberDeclaration, BfAstNode); - BfAttributeDirective* mAttributes; + BfAttributeDirective* mAttributes; BfAstNode* mProtectionSpecifier; - BfTokenNode* mStaticSpecifier; + BfTokenNode* mStaticSpecifier; BfTokenNode* mReadOnlySpecifier; // Also stores 'inline' }; BF_AST_DECL(BfMemberDeclaration, BfAstNode); @@ -2943,7 +2983,7 @@ public: ASTREF(BfTokenNode*) mPrecedingComma; BfAstNode* mNameNode; // Either BfIdentifierNode or BfTupleExpression ASTREF(BfTokenNode*) mEqualsNode; - ASTREF(BfExpression*) mInitializer; + ASTREF(BfExpression*) mInitializer; }; BF_AST_DECL(BfVariableDeclaration, BfExpression); class BfLocalMethodDeclaration : public BfCompoundStatement @@ -2996,7 +3036,7 @@ class BfGenericOperatorConstraint : public BfAstNode { public: BF_AST_TYPE(BfGenericOperatorConstraint, BfAstNode); - + BfTokenNode* mOperatorToken; BfTypeReference* mLeftType; BfTokenNode* mOpToken; @@ -3012,7 +3052,7 @@ public: BfTypeReference* mTypeRef; BfTokenNode* mColonToken; BfSizedArray mConstraintTypes; - BfSizedArray mCommas; + BfSizedArray mCommas; }; BF_AST_DECL(BfGenericConstraint, BfAstNode); class BfGenericConstraintExpression : public BfAstNode @@ -3036,8 +3076,8 @@ class BfMethodDeclaration : public BfMemberDeclaration { public: BF_AST_TYPE(BfMethodDeclaration, BfMemberDeclaration); - - BfCommentNode* mDocumentation; + + BfCommentNode* mDocumentation; BfTokenNode* mExternSpecifier; BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract' BfTokenNode* mNewSpecifier; @@ -3047,7 +3087,7 @@ public: BfTypeReference* mReturnType; BfTypeReference* mExplicitInterface; BfTokenNode* mExplicitInterfaceDotToken; - BfIdentifierNode* mNameNode; + BfIdentifierNode* mNameNode; BfTokenNode* mOpenParen; BfTokenNode* mThisToken; BfSizedArray mParams; @@ -3057,7 +3097,7 @@ public: BfGenericConstraintsDeclaration* mGenericConstraintsDeclaration; BfAstNode* mEndSemicolon; BfTokenNode* mFatArrowToken; - BfAstNode* mBody; // Either expression or block + BfAstNode* mBody; // Either expression or block //BfMethodDef* mMethodDef; @@ -3068,13 +3108,13 @@ class BfOperatorDeclaration : public BfMethodDeclaration { public: BF_AST_TYPE(BfOperatorDeclaration, BfMethodDeclaration); - + BfTokenNode* mExplicitToken; // Explicit or Implicit BfTokenNode* mOperatorToken; BfTokenNode* mOpTypeToken; bool mIsConvOperator; BfUnaryOp mUnaryOp; - BfBinaryOp mBinOp; + BfBinaryOp mBinOp; BfAssignmentOp mAssignOp; }; BF_AST_DECL(BfOperatorDeclaration, BfMethodDeclaration); @@ -3084,21 +3124,22 @@ public: BF_AST_TYPE(BfConstructorDeclaration, BfMethodDeclaration); BfTokenNode* mThisToken; - + BfTokenNode* mInitializerColonToken; BfExpression* mInitializer; - }; BF_AST_DECL(BfConstructorDeclaration, BfMethodDeclaration); class BfAutoConstructorDeclaration : public BfConstructorDeclaration { public: BF_AST_TYPE(BfAutoConstructorDeclaration, BfConstructorDeclaration); + + BfAstNode* mPrefix; }; BF_AST_DECL(BfAutoConstructorDeclaration, BfConstructorDeclaration); class BfDestructorDeclaration : public BfMethodDeclaration { -public: +public: BF_AST_TYPE(BfDestructorDeclaration, BfMethodDeclaration); BfTokenNode* mTildeToken; @@ -3129,19 +3170,19 @@ class BfFieldDeclaration : public BfMemberDeclaration { public: BF_AST_TYPE(BfFieldDeclaration, BfMemberDeclaration); - + BfCommentNode* mDocumentation; BfTokenNode* mPrecedingComma; - BfAstNode* mConstSpecifier; // Could be 'const' or 'using' + BfAstNode* mConstSpecifier; // Could be 'const' or 'using' BfTokenNode* mVolatileSpecifier; BfTokenNode* mNewSpecifier; - BfTokenNode* mExternSpecifier; + BfTokenNode* mExternSpecifier; // Could be 'extern' or 'append' BfTypeReference* mTypeRef; BfIdentifierNode* mNameNode; BfTokenNode* mEqualsNode; BfExpression* mInitializer; BfFieldDtorDeclaration* mFieldDtor; - + BfFieldDef* mFieldDef; }; BF_AST_DECL(BfFieldDeclaration, BfMemberDeclaration); @@ -3149,7 +3190,6 @@ class BfEnumEntryDeclaration : public BfFieldDeclaration { public: BF_AST_TYPE(BfEnumEntryDeclaration, BfFieldDeclaration); - }; BF_AST_DECL(BfEnumEntryDeclaration, BfFieldDeclaration); class BfPropertyMethodDeclaration : public BfAstNode @@ -3160,10 +3200,10 @@ public: BfAttributeDirective* mAttributes; BfAstNode* mProtectionSpecifier; BfTokenNode* mSetRefSpecifier; - BfTokenNode* mMutSpecifier; + BfTokenNode* mMutSpecifier; BfIdentifierNode* mNameNode; BfTokenNode* mFatArrowToken; - BfAstNode* mBody; + BfAstNode* mBody; BfAstNode* mEndSemicolon; }; BF_AST_DECL(BfPropertyMethodDeclaration, BfAstNode); @@ -3172,7 +3212,7 @@ class BfPropertyBodyExpression : public BfAstNode public: BF_AST_TYPE(BfPropertyBodyExpression, BfAstNode); BfTokenNode* mMutSpecifier; - BfTokenNode* mFatTokenArrow; + BfTokenNode* mFatTokenArrow; }; BF_AST_DECL(BfPropertyBodyExpression, BfAstNode); class BfPropertyDeclaration : public BfFieldDeclaration @@ -3182,10 +3222,10 @@ public: BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract' BfTypeReference* mExplicitInterface; - BfTokenNode* mExplicitInterfaceDotToken; + BfTokenNode* mExplicitInterfaceDotToken; BfAstNode* mDefinitionBlock; - BfSizedArray mMethods; + BfSizedArray mMethods; BfPropertyMethodDeclaration* GetMethod(const StringImpl& name); }; BF_AST_DECL(BfPropertyDeclaration, BfFieldDeclaration); @@ -3314,7 +3354,7 @@ public: BfTokenNode* mUsingToken; BfTokenNode* mOpenParen; - BfVariableDeclaration* mVariableDeclaration; + BfVariableDeclaration* mVariableDeclaration; BfTokenNode* mCloseParen; BfAstNode* mEmbeddedStatement; }; BF_AST_DECL(BfUsingStatement, BfCompoundStatement); @@ -3338,7 +3378,7 @@ public: BfTokenNode* mWhileToken; BfTokenNode* mOpenParen; BfExpression* mCondition; - BfTokenNode* mCloseParen; + BfTokenNode* mCloseParen; }; BF_AST_DECL(BfRepeatStatement, BfLabelableStatement); class BfWhileStatement : public BfLabelableStatement @@ -3417,7 +3457,7 @@ public: String ToString(); }; - + class AsmInst { public: diff --git a/IDEHelper/Compiler/BfAstAllocator.cpp b/IDEHelper/Compiler/BfAstAllocator.cpp index 7b3243c6..2d749c1e 100644 --- a/IDEHelper/Compiler/BfAstAllocator.cpp +++ b/IDEHelper/Compiler/BfAstAllocator.cpp @@ -24,36 +24,35 @@ void BfBitSet::Init(int numBits) memset(mBits, 0, numInts * 4); } - bool BfBitSet::IsSet(int idx) { return (mBits[idx / 32] & (1 << (idx % 32))) != 0; } void BfBitSet::Set(int idx) -{ +{ mBits[idx / 32] |= (1 << (idx % 32)); } void BfBitSet::Clear(int idx) -{ +{ mBits[idx / 32] &= ~(1 << (idx % 32)); } ////////////////////////////////////////////////////////////////////////// BfAstAllocator::BfAstAllocator() -{ +{ mSourceData = NULL; - mCurPtr = NULL; - mCurPageEnd = mCurPtr; + mCurPtr = NULL; + mCurPageEnd = mCurPtr; mLargeAllocSizes = 0; - mNumPagesUsed = 0; + mNumPagesUsed = 0; mUsedSize = 0; } BfAstAllocator::~BfAstAllocator() -{ +{ for (auto addr : mLargeAllocs) delete [] (uint8*)addr; if (mPages.size() != 0) @@ -61,16 +60,16 @@ BfAstAllocator::~BfAstAllocator() } void BfAstAllocator::InitChunkHead(int wantSize) -{ +{ mCurPtr = mSourceData->mAstAllocManager->AllocPage(); mPages.push_back(mCurPtr); mCurPageEnd = mCurPtr + BfAstAllocManager::PAGE_SIZE; mNumPagesUsed++; -#ifdef BF_AST_ALLOCATOR_USE_PAGES +#ifdef BF_AST_ALLOCATOR_USE_PAGES BfAstPageHeader* pageHeader = (BfAstPageHeader*)mCurPtr; pageHeader->mSourceData = mSourceData; BF_ASSERT(sizeof(BfAstPageHeader) <= 16); - mCurPtr += 16; + mCurPtr += 16; #endif } @@ -95,28 +94,28 @@ BfAstAllocManager::~BfAstAllocManager() #endif } -//TODO: Remove this +//TODO: Remove this //static int gAstChunkAllocCount = 0; uint8* BfAstAllocManager::AllocPage() { #ifdef BF_AST_ALLOCATOR_USE_PAGES AutoCrit autoCrit(mCritSect); - if (mFreePageCount != 0) + if (mFreePageCount != 0) { mFreePageCount--; return (uint8*)mFreePages.PopFront(); } - + BF_ASSERT(mFreePages.mHead == NULL); - + //auto newChunk = (uint8*)::VirtualAlloc((void*)(0x4200000000 + gAstChunkAllocCount*CHUNK_SIZE), CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); //gAstChunkAllocCount++; auto newChunk = (uint8*)::VirtualAlloc(NULL, CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); BF_ASSERT(newChunk != NULL); - BF_ASSERT(((intptr)newChunk & (PAGE_SIZE - 1)) == 0); - mAllocChunks.push_back(newChunk); + BF_ASSERT(((intptr)newChunk & (PAGE_SIZE - 1)) == 0); + mAllocChunks.push_back(newChunk); //BfLog("BfAstAllocManager alloc %p\n", newChunk); @@ -128,7 +127,7 @@ uint8* BfAstAllocManager::AllocPage() } mFreePageCount--; - return (uint8*)mFreePages.PopFront(); + return (uint8*)mFreePages.PopFront(); #else return new uint8[PAGE_SIZE]; #endif diff --git a/IDEHelper/Compiler/BfAstAllocator.h b/IDEHelper/Compiler/BfAstAllocator.h index 163cdf82..4be75bfe 100644 --- a/IDEHelper/Compiler/BfAstAllocator.h +++ b/IDEHelper/Compiler/BfAstAllocator.h @@ -49,14 +49,13 @@ public: class BfAstPageHeader { public: - BfSourceData* mSourceData; + BfSourceData* mSourceData; }; #endif class BfAstAllocChunk; class BfAstAllocManager; - struct BfAstFreePage { BfAstFreePage* mNext; @@ -75,7 +74,7 @@ public: Array mAllocChunks; #endif -public: +public: BfAstAllocManager(); ~BfAstAllocManager(); @@ -90,7 +89,7 @@ public: // { // int mCount; // int mSize; -// +// // BumpAllocTrackedEntry() // { // mCount = 0; @@ -103,9 +102,9 @@ class BfAstAllocator { public: static const int LARGE_ALLOC_SIZE = 2048; - BfSourceData* mSourceData; - uint8* mCurPtr; - uint8* mCurPageEnd; + BfSourceData* mSourceData; + uint8* mCurPtr; + uint8* mCurPageEnd; Array mLargeAllocs; Array mPages; int mLargeAllocSizes; @@ -117,8 +116,8 @@ public: public: BfAstAllocator(); - ~BfAstAllocator(); - + ~BfAstAllocator(); + void InitChunkHead(int wantSize); int GetAllocSize() const @@ -141,7 +140,7 @@ public: { int alignSize = alignof(T); mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1)); - int wantSize = sizeof(T) + extraBytes; + int wantSize = sizeof(T) + extraBytes; #ifdef BUMPALLOC_TRACKALLOCS const char* name = typeid(T).name(); @@ -152,10 +151,10 @@ public: #endif if (mCurPtr + wantSize >= mCurPageEnd) - InitChunkHead(wantSize); + InitChunkHead(wantSize); memset(mCurPtr, 0, wantSize); - T* retVal = new (mCurPtr) T(); - mCurPtr += wantSize; + T* retVal = new (mCurPtr) T(); + mCurPtr += wantSize; #ifndef BF_AST_ALLOCATOR_USE_PAGES retVal->mSourceData = this->mSourceData; @@ -165,8 +164,8 @@ public: } uint8* AllocBytes(int wantSize, int alignSize, const char* dbgName = "AllocBytes") - { -#ifdef BUMPALLOC_TRACKALLOCS + { +#ifdef BUMPALLOC_TRACKALLOCS BumpAllocTrackedEntry* allocSizePtr; mTrackedAllocs.TryAdd(dbgName, NULL, &allocSizePtr); allocSizePtr->mCount++; @@ -188,13 +187,13 @@ public: InitChunkHead(wantSize); memset(mCurPtr, 0, wantSize); uint8* retVal = mCurPtr; - mCurPtr += wantSize; + mCurPtr += wantSize; return retVal; } uint8* AllocBytes(int wantSize, const char* dbgName = "AllocBytes") { -#ifdef BUMPALLOC_TRACKALLOCS +#ifdef BUMPALLOC_TRACKALLOCS BumpAllocTrackedEntry* allocSizePtr; mTrackedAllocs.TryAdd(dbgName, NULL, &allocSizePtr); allocSizePtr->mCount++; @@ -211,12 +210,10 @@ public: if (mCurPtr + wantSize >= mCurPageEnd) InitChunkHead(wantSize); memset(mCurPtr, 0, wantSize); - uint8* retVal = mCurPtr; + uint8* retVal = mCurPtr; mCurPtr += wantSize; return retVal; } }; NS_BF_END - - diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index 525ab000..964d9c35 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -35,7 +35,7 @@ AutoCompleteBase::~AutoCompleteBase() AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry, const StringImpl& filter) { uint8 matches[256]; - + if (!DoesFilterMatch(entry.mDisplay, filter.c_str(), entry.mScore, matches, 256) || (entry.mNamePrefixCount < 0)) return NULL; @@ -43,7 +43,7 @@ AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry, co entry.mMatches = (entry.mMatchesLength > 0) ? matches : nullptr; auto result = AddEntry(entry); - + // Reset matches because the array will be invalid after return entry.mMatches = nullptr; entry.mMatchesLength = 0; @@ -82,13 +82,13 @@ AutoCompleteEntry* AutoCompleteBase::AddEntry(const AutoCompleteEntry& entry) { insertedEntry->mEntryType = entry.mEntryType; - const char* display = entry.mDisplay; + const char* display = entry.mDisplay; int size = (int)strlen(display) + 1; insertedEntry->mDisplay = (char*)mAlloc.AllocBytes(size); memcpy((char*)insertedEntry->mDisplay, display, size); if (entry.mMatchesLength > 0) - { + { insertedEntry->mMatches = (uint8*)mAlloc.AllocBytes(insertedEntry->mMatchesLength); memcpy((char*)insertedEntry->mMatches, entry.mMatches, insertedEntry->mMatchesLength); } @@ -105,8 +105,8 @@ bool AutoCompleteBase::DoesFilterMatch(const char* entry, const char* filter, in if (entry[entryLen - 1] == '=') return (strncmp(filter, entry, entryLen - 1) == 0); return (strcmp(filter, entry) == 0); - } - + } + if (!mIsAutoComplete) return false; @@ -176,7 +176,7 @@ bool AutoCompleteBase::DoesFilterMatch(const char* entry, const char* filter, in } void AutoCompleteBase::Clear() -{ +{ //mEntries.clear(); mAlloc.Clear(); mEntriesSet.Clear(); @@ -195,8 +195,8 @@ BfAutoComplete::BfAutoComplete(BfResolveType resolveType, bool doFuzzyAutoComple mHasFriendSet = false; mUncertain = false; mForceAllowNonStatic = false; - mMethodMatchInfo = NULL; - mIsGetDefinition = + mMethodMatchInfo = NULL; + mIsGetDefinition = (resolveType == BfResolveType_GetSymbolInfo) || (resolveType == BfResolveType_GoToDefinition); mIsAutoComplete = (resolveType == BfResolveType_Autocomplete); @@ -253,18 +253,18 @@ void BfAutoComplete::Clear() else { // Keep mBestIdx - for when we match but then backspace - mMethodMatchInfo->mPrevBestIdx = mMethodMatchInfo->mBestIdx; + mMethodMatchInfo->mPrevBestIdx = mMethodMatchInfo->mBestIdx; mMethodMatchInfo->mMostParamsMatched = 0; mMethodMatchInfo->mHadExactMatch = false; mMethodMatchInfo->mInstanceList.Clear(); mMethodMatchInfo->mSrcPositions.Clear(); } } - + mInsertStartIdx = -1; mInsertEndIdx = -1; mIsCapturingMethodMatchInfo = false; - + AutoCompleteBase::Clear(); } @@ -306,7 +306,7 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int star return false; if (node == NULL) return false; - + // if (!node->IsFromParser(mCompiler->mResolvePassData->mParser)) // return false; @@ -317,13 +317,13 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int star return false; if ((bfParser->mParserFlags & ParserFlag_Autocomplete) == 0) return false; - + //if (mCompiler->mResolvePassData->mResolveType != BfResolveType_Autocomplete) lengthAdd++; int cursorIdx = bfParser->mCursorCheckIdx; - int nodeSrcStart = node->GetSrcStart(); - if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= node->GetSrcEnd() + lengthAdd)) + int nodeSrcStart = node->GetSrcStart(); + if ((cursorIdx < nodeSrcStart + startAdd) || (cursorIdx >= node->GetSrcEnd() + lengthAdd)) return false; return true; } @@ -371,7 +371,7 @@ bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node) return false; int startAdd = 0; - + if (mCursorLineStart == -1) { auto nodeSource = node->GetSourceData(); @@ -388,7 +388,7 @@ bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node) while (mCursorLineEnd < nodeSource->mSrcLength) { if (nodeSource->mSrc[mCursorLineEnd] == '\n') - break; + break; mCursorLineEnd++; } } @@ -414,7 +414,7 @@ BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* is }; if (auto typeRef = BfNodeDynCast(node)) - { + { if (auto namedTypeRef = BfNodeDynCast(typeRef)) { BfExprEvaluator exprEvaluator(mModule); @@ -466,16 +466,16 @@ BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* is *isStatic = true; return _FixType(BfTypedValue(type)); } - } + } if (auto identifier = BfNodeDynCast(node)) - { + { BfExprEvaluator exprEvaluator(mModule); auto identifierResult = exprEvaluator.LookupIdentifier(identifier, false, NULL); if (!identifierResult) identifierResult = exprEvaluator.GetResult(); if (identifierResult) return _FixType(identifierResult); - + if (auto qualifiedIdentifier = BfNodeDynCast(node)) { bool leftIsStatic = false; @@ -506,12 +506,12 @@ BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* is } } else if (auto memberRefExpr = BfNodeDynCast(node)) - { + { return _FixType(mModule->CreateValueFromExpression(memberRefExpr, expectingType, evalExprFlags)); } else if (auto parenExpr = BfNodeDynCast(node)) { - // Don't pass BfEvalExprFlags_IgnoreNullConditional, since parenExprs end nullable chains and we actually + // Don't pass BfEvalExprFlags_IgnoreNullConditional, since parenExprs end nullable chains and we actually // DO want the nullable at this point return _FixType(mModule->CreateValueFromExpression(parenExpr)); } @@ -521,7 +521,6 @@ BfTypedValue BfAutoComplete::LookupTypeRefOrIdentifier(BfAstNode* node, bool* is } return BfTypedValue(); - } void BfAutoComplete::SetDefinitionLocation(BfAstNode* astNode, bool force) @@ -529,7 +528,7 @@ void BfAutoComplete::SetDefinitionLocation(BfAstNode* astNode, bool force) if (mIsGetDefinition) { if ((mGetDefinitionNode == NULL) || (force)) - mGetDefinitionNode = astNode; + mGetDefinitionNode = astNode; } } @@ -554,7 +553,7 @@ void BfAutoComplete::AddMethod(BfTypeInstance* typeInstance, BfMethodDef* method { filterStr++; wantPrefixCount++; - } + } String replaceName; AutoCompleteEntry entry("method", methodName, methodDef->mNamePrefixCount - wantPrefixCount); if (methodDecl != NULL) @@ -565,15 +564,15 @@ void BfAutoComplete::AddMethod(BfTypeInstance* typeInstance, BfMethodDef* method replaceName += "!"; entry.mDisplay = replaceName.c_str(); entry.mEntryType = "mixin"; - } - } + } + } if (methodDef->mMethodType == BfMethodType_Extension) entry.mEntryType = "extmethod"; if (auto entryAdded = AddEntry(entry, filterStr)) { if (methodDecl != NULL) - { + { if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsLocalMethod) && (methodDecl->mReturnType != NULL) && (GetCursorIdx(methodDecl) == methodDecl->mReturnType->mSrcEnd)) { // This isn't really a local method decl, it just looks like one @@ -601,7 +600,7 @@ void BfAutoComplete::AddMethod(BfTypeInstance* typeInstance, BfMethodDef* method { if (!str.IsEmpty()) str += "\x05"; - methodDecl->mDocumentation->GetDocString(str); + methodDecl->mDocumentation->GetDocString(str); } if (!str.IsEmpty()) entryAdded->mDocumentation = mAlloc.AllocString(str); @@ -624,9 +623,9 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo if (name == "@") return; int gravePos = (int)name.IndexOf('`'); - if (gravePos != -1) + if (gravePos != -1) name = name.Substring(0, gravePos) + "<>"; - + if (onlyAttribute) { if ((mIsGetDefinition) && (name == filter + "Attribute")) @@ -638,7 +637,7 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo int score; uint8 matches[256]; if (!DoesFilterMatch(name.c_str(), filter.c_str(), score, matches, sizeof(matches))) - return; + return; auto type = mModule->ResolveTypeDef(typeDef, BfPopulateType_Declaration); if (type != NULL) @@ -669,7 +668,7 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo { if ((CheckDocumentation(entryAdded, NULL)) && (entryAdded->mDocumentation == NULL)) { - auto type = mModule->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias); + auto type = mModule->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias); StringT<1024> str; if (type != NULL) { @@ -681,7 +680,7 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo { if (!str.IsEmpty()) str += "\x05"; - typeDef->mTypeDeclaration->mDocumentation->GetDocString(str); + typeDef->mTypeDeclaration->mDocumentation->GetDocString(str); } entryAdded->mDocumentation = mAlloc.AllocString(str); } @@ -690,9 +689,15 @@ void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bo bool BfAutoComplete::CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate) { + if (mResolveType == BfResolveType_GetSymbolInfo) + { + // This is needed for nameof on private inner types + return true; + } + if ((protection == BfProtection_Internal) && (typeDef != NULL)) { - return mModule->CheckProtection(protection, typeDef, allowProtected, allowPrivate); + return mModule->CheckProtection(protection, typeDef, allowProtected, allowPrivate); } return (mHasFriendSet) || (protection == BfProtection_Public) || @@ -712,24 +717,41 @@ const char* BfAutoComplete::GetTypeName(BfType* type) return "value"; } -void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate) -{ +void BfAutoComplete::AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, BfTypeInstance* startType, bool allowProtected, bool allowPrivate) +{ if (typeInst->IsEnum()) AddEntry(AutoCompleteEntry("valuetype", "UnderlyingType"), filter); + BfShow checkShow = (typeInst == startType) ? BfShow_Hide : BfShow_HideIndirect; + for (auto innerType : typeInst->mTypeDef->mNestedTypes) { + if (innerType->mShow >= checkShow) + continue; + + if (innerType->mOuterType->mTypeCode == BfTypeCode_Extension) + { + if (typeInst->mDefineState < BfTypeDefineState_Defined) + mModule->PopulateType(typeInst); + + if ((typeInst->mGenericTypeInfo != NULL) && (typeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)) + { + if (!typeInst->mGenericTypeInfo->mGenericExtensionInfo->mConstraintsPassedSet.IsSet(innerType->mOuterType->mPartialIdx)) + continue; + } + } + if (CheckProtection(innerType->mProtection, innerType, allowProtected, allowPrivate)) AddTypeDef(innerType, filter); - } + } allowPrivate = false; if (typeInst->mBaseType != NULL) - AddInnerTypes(typeInst->mBaseType, filter, allowProtected, allowPrivate); + AddInnerTypes(typeInst->mBaseType, filter, startType, allowProtected, allowPrivate); } void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute) -{ +{ if (typeInst != mModule->mCurTypeInstance) AddTypeDef(typeInst->mTypeDef->GetDefinition(), filter, onlyAttribute); @@ -758,14 +780,14 @@ void BfAutoComplete::AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& } void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, BfFieldInstance* fieldInstance, const StringImpl& filter) -{ +{ int wantPrefixCount = 0; const char* filterStr = filter.c_str(); while (filterStr[0] == '@') { filterStr++; wantPrefixCount++; - } + } AutoCompleteEntry entry(GetTypeName(fieldInstance->mResolvedType), fieldDef->mName, fieldDef->mNamePrefixCount - wantPrefixCount); if (auto entryAdded = AddEntry(entry, filterStr)) { @@ -774,10 +796,10 @@ void BfAutoComplete::AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, Bf if (CheckDocumentation(entryAdded, documentation)) { mModule->PopulateType(typeInst); - - String str; + + String str; str += mModule->TypeToString(fieldInstance->mResolvedType); - str += " "; + str += " "; str += mModule->TypeToString(typeInst); str += "."; str += fieldDef->mName; @@ -812,7 +834,7 @@ void BfAutoComplete::AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, c { filterStr++; wantPrefixCount++; - } + } BfCommentNode* documentation = NULL; auto fieldDecl = propDef->GetFieldDeclaration(); if (fieldDecl != NULL) @@ -834,13 +856,13 @@ void BfAutoComplete::AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, c if (methodDef->mMethodType == BfMethodType_PropertyGetter) { hasGetter = true; - propType = methodInstance->mReturnType; + propType = methodInstance->mReturnType; } if (methodDef->mMethodType == BfMethodType_PropertySetter) { hasSetter = true; - if (methodInstance->GetParamCount() > 0) - propType = methodInstance->GetParamType(0); + if (methodInstance->GetParamCount() > 0) + propType = methodInstance->GetParamType(0); } } @@ -882,13 +904,13 @@ void BfAutoComplete::AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, c void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis, bool checkOuterType) { bool isInterface = false; - + if (mForceAllowNonStatic) addNonStatic = true; auto activeTypeDef = mModule->GetActiveTypeDef(); - if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum())) + if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum()) && (allowImplicitThis)) { AddEntry(AutoCompleteEntry("value", "_"), filter); } @@ -897,32 +919,34 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo mModule->PopulateType(typeInst, BfPopulateType_Data); + BfShow checkShow = (startType == typeInst) ? BfShow_Hide : BfShow_HideIndirect; + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; for (auto& fieldInst : typeInst->mFieldInstances) - { + { auto fieldDef = fieldInst.GetFieldDef(); if (fieldDef == NULL) continue; - if (fieldDef->mIsNoShow) + if (fieldDef->mShow >= checkShow) continue; - if ((CHECK_STATIC(fieldDef->mIsStatic)) && + if ((CHECK_STATIC(fieldDef->mIsStatic)) && ((mIsGetDefinition) || (mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mDeclaringType->mProject, fieldDef->mProtection, startType)))) { if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) || (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef))) continue; - + AddField(typeInst, fieldDef, &fieldInst, filter); } - } + } for (auto methodDef : typeInst->mTypeDef->mMethods) { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -943,17 +967,17 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo else { canUseMethod &= (CHECK_STATIC(methodDef->mIsStatic) && - (mModule->CheckProtection(protectionCheckFlags, typeInst, methodDef->mDeclaringType->mProject, methodDef->mProtection, startType))); + (mModule->CheckProtection(protectionCheckFlags, typeInst, methodDef->mDeclaringType->mProject, methodDef->mProtection, startType))); } if (canUseMethod) { - AddMethod(typeInst, methodDef, NULL, methodDef->GetMethodDeclaration(), methodDef->mName, filter); + AddMethod(typeInst, methodDef, NULL, methodDef->GetMethodDeclaration(), methodDef->mName, filter); } } for (auto propDef : typeInst->mTypeDef->mProperties) { - if (propDef->mIsNoShow) + if (propDef->mShow >= checkShow) continue; if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) || @@ -970,7 +994,7 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo AddProp(typeInst, propDef, filter); } } - + if (allowInterfaces) { for (auto iface : typeInst->mInterfaces) @@ -985,6 +1009,12 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo AddTypeMembers(mModule->mContext->mBfObjectType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis, false); } + if (typeInst->IsInterface()) + { + for (auto interface : typeInst->mInterfaces) + AddTypeMembers(interface.mInterfaceType, addStatic, addNonStatic, filter, startType, false, allowImplicitThis, false); + } + if ((addStatic) && (allowImplicitThis) && (checkOuterType)) { auto outerType = mModule->GetOuterType(typeInst); @@ -993,6 +1023,63 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo AddTypeMembers(outerType, true, false, filter, startType, false, allowImplicitThis, false); } } + + if ((typeInst->mTypeDef->mHasUsingFields) && + ((typeInst->mTypeInfoEx == NULL) || (typeInst->mTypeInfoEx->mUsingFieldData == NULL))) + mModule->PopulateUsingFieldData(typeInst); + + if ((typeInst->mTypeInfoEx != NULL) && (typeInst->mTypeInfoEx->mUsingFieldData != NULL)) + { + for (int pass = 0; pass < 2; pass++) + { + auto& dict = (pass == 0) ? typeInst->mTypeInfoEx->mUsingFieldData->mEntries : typeInst->mTypeInfoEx->mUsingFieldData->mMethods; + for (auto& entryKV : dict) + { + for (auto& entryList : entryKV.mValue.mLookups) + { + auto& endEntry = entryList.back(); + + bool isStatic = endEntry.IsStatic(); + if ((isStatic) && (!addStatic)) + continue; + if ((!isStatic) && (!addNonStatic)) + continue; + + bool passesProtection = true; + for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++) + { + auto& entry = entryList[entryIdx]; + if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject, + (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), typeInst)) + { + passesProtection = false; + break; + } + } + if (!passesProtection) + continue; + + switch (endEntry.mKind) + { + case BfUsingFieldData::MemberRef::Kind_Field: + if (endEntry.mTypeInstance->mDefineState < BfTypeDefineState_Defined) + mModule->PopulateType(endEntry.mTypeInstance); + AddField(endEntry.mTypeInstance, endEntry.mTypeInstance->mTypeDef->mFields[endEntry.mIdx], &endEntry.mTypeInstance->mFieldInstances[endEntry.mIdx], filter); + break; + case BfUsingFieldData::MemberRef::Kind_Property: + AddProp(endEntry.mTypeInstance, endEntry.mTypeInstance->mTypeDef->mProperties[endEntry.mIdx], filter); + break; + case BfUsingFieldData::MemberRef::Kind_Method: + { + auto methodDef = endEntry.mTypeInstance->mTypeDef->mMethods[endEntry.mIdx]; + AddMethod(endEntry.mTypeInstance, methodDef, NULL, methodDef->GetMethodDeclaration(), methodDef->mName, filter); + } + break; + } + } + } + } + } } void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate) @@ -1004,15 +1091,17 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn mModule->PopulateType(typeInst, BfPopulateType_Data); + BfShow checkShow = allowPrivate ? BfShow_Hide : BfShow_HideIndirect; + for (auto& fieldInst : typeInst->mFieldInstances) { auto fieldDef = fieldInst.GetFieldDef(); if (fieldDef == NULL) continue; - if (fieldDef->mIsNoShow) + if (fieldDef->mShow > checkShow) continue; - + if ((fieldDef->mIsStatic) && (CheckProtection(fieldDef->mProtection, fieldDef->mDeclaringType, allowProtected, allowPrivate))) { if (!mModule->CanCast(BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), fieldInst.mResolvedType), selfType)) @@ -1022,7 +1111,7 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn (!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef))) continue; - AddField(typeInst, fieldDef, &fieldInst, filter); + AddField(typeInst, fieldDef, &fieldInst, filter); } } @@ -1030,7 +1119,7 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow > checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -1045,9 +1134,9 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn continue; bool canUseMethod; - canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin); + canUseMethod = (methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Mixin); canUseMethod &= CheckProtection(methodDef->mProtection, methodDef->mDeclaringType, allowProtected, allowPrivate); - + if (methodDef->mMethodType != BfMethodType_Normal) continue; @@ -1070,7 +1159,7 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn for (auto propDef : typeInst->mTypeDef->mProperties) { - if (propDef->mIsNoShow) + if (propDef->mShow > checkShow) continue; if ((!typeInst->IsTypeMemberIncluded(propDef->mDeclaringType, activeTypeDef, mModule)) || @@ -1109,16 +1198,16 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn AddProp(typeInst, propDef, filter); } } - + auto outerType = mModule->GetOuterType(typeInst); if (outerType != NULL) { AddSelfResultTypeMembers(outerType, selfType, filter, false); - } + } } bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter) -{ +{ bool isDot = (dotNode != NULL) && (dotNode->mToken == BfToken_Dot); if (IsAutocompleteNode(nameNode)) { @@ -1162,8 +1251,8 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm for (auto& fieldInst : typeInst->mFieldInstances) { auto fieldDef = fieldInst.GetFieldDef(); - if ((fieldDef != NULL) && (fieldDef->mIsConst) && - ((fieldInst.mResolvedType == typeInst) || (fieldInst.mIsEnumPayloadCase)) && + if ((fieldDef != NULL) && (fieldDef->mIsConst) && + ((fieldInst.mResolvedType == typeInst) || (fieldInst.mIsEnumPayloadCase)) && (CheckProtection(fieldDef->mProtection, fieldDef->mDeclaringType, allowProtected, allowPrivate))) { if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) || @@ -1194,7 +1283,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm } } } - } + } } void BfAutoComplete::AddExtensionMethods(BfTypeInstance* targetType, BfTypeInstance* extensionContainer, const StringImpl & filter, bool allowProtected, bool allowPrivate) @@ -1204,18 +1293,20 @@ void BfAutoComplete::AddExtensionMethods(BfTypeInstance* targetType, BfTypeInsta mModule->PopulateType(extensionContainer, BfPopulateType_Data); + BfShow checkShow = allowPrivate ? BfShow_Hide : BfShow_HideIndirect; + for (auto methodDef : extensionContainer->mTypeDef->mMethods) { if (methodDef->mMethodType != BfMethodType_Extension) - continue; - if (methodDef->mIsNoShow) + continue; + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; - - bool canUseMethod = true; + + bool canUseMethod = true; canUseMethod &= CheckProtection(methodDef->mProtection, methodDef->mDeclaringType, allowProtected, allowPrivate); - + auto methodInstance = mModule->GetRawMethodInstanceAtIdx(extensionContainer, methodDef->mIdx); if (methodInstance == NULL) continue; @@ -1226,7 +1317,7 @@ void BfAutoComplete::AddExtensionMethods(BfTypeInstance* targetType, BfTypeInsta if (!DoesFilterMatch(methodDef->mName.c_str(), filter.c_str(), score, matches, sizeof(matches))) continue; - auto thisType = methodInstance->GetParamType(0); + auto thisType = methodInstance->GetParamType(0); bool paramValidated = false; if (methodInstance->GetNumGenericParams() > 0) { @@ -1311,7 +1402,7 @@ bool BfAutoComplete::WantsEntries() if (mModule == NULL) return false; - return (mResolveType == BfResolveType_Autocomplete) || + return (mResolveType == BfResolveType_Autocomplete) || (mResolveType == BfResolveType_Autocomplete_HighPri) || (mResolveType == BfResolveType_GetSymbolInfo) || (mResolveType == BfResolveType_GoToDefinition) || @@ -1319,7 +1410,7 @@ bool BfAutoComplete::WantsEntries() } void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode) -{ +{ String filter; if (identifierNode != NULL) { @@ -1328,8 +1419,8 @@ void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode) mInsertEndIdx = identifierNode->GetSrcEnd(); } - BfProject* bfProject = GetActiveProject(); - + BfProject* bfProject = GetActiveProject(); + auto _AddProjectNamespaces = [&](BfProject* project) { for (auto namespacePair : project->mNamespaces) @@ -1360,7 +1451,7 @@ void BfAutoComplete::AddTopLevelNamespaces(BfAstNode* identifierNode) void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute) { String filter; - + if (identifierNode != NULL) { filter = identifierNode->ToString(); @@ -1371,7 +1462,7 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib AddEntry(AutoCompleteEntry("token", "function"), filter); AddEntry(AutoCompleteEntry("token", "delegate"), filter); AddEntry(AutoCompleteEntry("token", "decltype"), filter); - + if (mModule->mCurTypeInstance != NULL) { if (!onlyAttribute) @@ -1380,7 +1471,7 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib for (auto genericParam : activeTypeDef->mGenericParamDefs) AddEntry(AutoCompleteEntry("generic", genericParam->mName), filter); } - + AddCurrentTypes(mModule->mCurTypeInstance, filter, true, true, onlyAttribute); } @@ -1395,14 +1486,14 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib if (!onlyAttribute) { - BfTypeDef* showTypeDef = NULL; + BfTypeDef* showTypeDef = NULL; for (auto& systemTypeDefEntry : mModule->mSystem->mSystemTypeDefs) { auto systemTypeDef = systemTypeDefEntry.mValue; if ((systemTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (systemTypeDef->mTypeCode == BfTypeCode_UIntUnknown)) continue; if ((AddEntry(AutoCompleteEntry("valuetype", systemTypeDef->mName->mString.mPtr), filter)) && (mIsGetDefinition)) - showTypeDef = systemTypeDef; + showTypeDef = systemTypeDef; } AddEntry(AutoCompleteEntry("valuetype", "SelfBase"), filter); AddEntry(AutoCompleteEntry("valuetype", "SelfOuter"), filter); @@ -1424,7 +1515,7 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib if (activeTypeDef != NULL) { BfProject* curProject = activeTypeDef->mProject; - + if (mModule->mCurTypeInstance != NULL) { for (auto innerTypeDef : mModule->mCurTypeInstance->mTypeDef->mNestedTypes) @@ -1435,14 +1526,14 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib } } - auto& namespaceSearch = activeTypeDef->mNamespaceSearch; + auto& namespaceSearch = activeTypeDef->mNamespaceSearch; String prevName; for (auto typeDef : mModule->mSystem->mTypeDefs) - { + { if (typeDef->mIsPartial) continue; //TODO :Check protection - if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject))) + if ((curProject != NULL) && (curProject->ContainsReference(typeDef->mProject))) { bool matches = false; if (typeDef->mOuterType == NULL) @@ -1450,7 +1541,7 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib if (((typeDef->mNamespace.IsEmpty()) || (namespaceSearch.Contains(typeDef->mNamespace)))) matches = true; - } + } if (matches) { @@ -1490,7 +1581,7 @@ void BfAutoComplete::AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttrib } void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpression, bool isUsingDirective) -{ +{ if ((identifierNode != NULL) && (!IsAutocompleteNode(identifierNode))) return; @@ -1503,7 +1594,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress auto parentBlock = mModule->mCurMethodState->mCurScope->mAstBlock; if ((identifierNode == binExpr->mRight) && (binExpr->mOp == BfBinaryOp_Multiply) && (parentBlock != NULL)) { - // If we are the last identifier in a block then we MAY be a partially-typed variable declaration + // If we are the last identifier in a block then we MAY be a partially-typed variable declaration if (parentBlock->mChildArr.back() == binExpr) { mUncertain = true; @@ -1511,7 +1602,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress } } } - + if (auto qualifiedNameNode = BfNodeDynCast(identifierNode)) { CheckMemberReference(qualifiedNameNode->mLeft, qualifiedNameNode->mDot, qualifiedNameNode->mRight, false, NULL, isUsingDirective); @@ -1521,7 +1612,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress AddTopLevelNamespaces(identifierNode); if (isUsingDirective) return; // Only do namespaces - + AddTopLevelTypes(identifierNode); String filter; @@ -1540,10 +1631,9 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress for (auto prop : showAttrTypeDef->mProperties) { if (auto entryAdded = AddEntry(AutoCompleteEntry("property", prop->mName + "="), filter)) - { + { if (CheckDocumentation(entryAdded, prop->GetFieldDeclaration()->mDocumentation)) { - } if (mIsGetDefinition) SetDefinitionLocation(prop->GetFieldDeclaration()->mNameNode); @@ -1551,12 +1641,11 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress } for (auto field : showAttrTypeDef->mFields) - { + { if (auto entryAdded = AddEntry(AutoCompleteEntry("field", field->mName + "="), filter)) - { + { if (CheckDocumentation(entryAdded, field->GetFieldDeclaration()->mDocumentation)) { - } if (mIsGetDefinition) SetDefinitionLocation(field->GetFieldDeclaration()->mNameNode); @@ -1577,17 +1666,17 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress AddTypeMembers(globalContainer.mTypeInst, true, false, filter, globalContainer.mTypeInst, true, true, false); } } - + BfStaticSearch* staticSearch = mModule->GetStaticSearch(); if (staticSearch != NULL) { for (auto typeInst : staticSearch->mStaticTypes) { AddTypeMembers(typeInst, true, false, filter, typeInst, true, true, false); - AddInnerTypes(typeInst, filter, false, false); + AddInnerTypes(typeInst, filter, typeInst, false, false); } } - + if (auto ceDbgState = mModule->GetCeDbgState()) { auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger; @@ -1601,7 +1690,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress if ((instIdx >= dbgVar.mStartCodePos) && (instIdx < dbgVar.mEndCodePos)) AddEntry(AutoCompleteEntry(GetTypeName(dbgVar.mType), dbgVar.mName), filter); } - } + } } ////////////////////////////////////////////////////////////////////////// @@ -1610,7 +1699,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress if (mModule->mCurMethodState != NULL) curMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance; if (curMethodInstance != NULL) - { + { if (!curMethodInstance->mMethodDef->mIsStatic) { if (mModule->mCurTypeInstance->IsObject()) @@ -1689,7 +1778,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress (varMethodState->mMixinState != NULL) || ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing))) break; - } + } } } } @@ -1705,9 +1794,9 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress auto checkMethodState = mModule->mCurMethodState; while (checkMethodState != NULL) - { + { for (auto localMethod : checkMethodState->mLocalMethods) - { + { if (localMethod->mMethodInstanceGroup != NULL) AddMethod(mModule->mCurTypeInstance, localMethod->mMethodDef, localMethod->mMethodInstanceGroup->mDefault, localMethod->mMethodDeclaration, localMethod->mMethodName, filter); } @@ -1715,17 +1804,17 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress } if (isInExpression) - { + { const char* tokens [] = { - "alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "const", "default", "defer", - "delegate", "delete", "do", "else", "false", "finally", + "alignof", "append", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "const", "default", "defer", + "delegate", "delete", "do", "else", "false", "finally", "fixed", "for", "function", "if", "implicit", "in", "internal", "is", "isconst", "new", "mixin", "null", "offsetof", "out", "params", "readonly", "ref", "rettype", "return", "sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked", "using", "var", "virtual", "volatile", "where", "while", "alloctype", "comptype", "decltype", "nullable", - }; + }; for (int i = 0; i < sizeof(tokens) / sizeof(char*); i++) AddEntry(AutoCompleteEntry("token", tokens[i]), filter); @@ -1739,7 +1828,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress { const char* tokens[] = { - "abstract", "base", "class", "const", + "abstract", "append", "base", "class", "const", "delegate", "extern", "enum", "explicit", "extension", "function", "interface", "in", "implicit", "internal", "mixin", "namespace", "new", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return", @@ -1749,15 +1838,15 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress for (int i = 0; i < sizeof(tokens)/sizeof(char*); i++) AddEntry(AutoCompleteEntry("token", tokens[i]), filter); } - + //if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (BfNodeDynCast(identifierNode->mParent) != NULL))) /*if ((identifierNode != NULL) && ((mModule->mCurMethodInstance == NULL) || (isInExpression))) { AddEntry(AutoCompleteEntry("token", "#if"), filter); AddEntry(AutoCompleteEntry("token", "#elif"), filter); AddEntry(AutoCompleteEntry("token", "#endif"), filter); - }*/ - + }*/ + //OutputDebugStrF("Autocomplete: %s\n", str.c_str()); } @@ -1775,14 +1864,14 @@ String BfAutoComplete::GetFilter(BfAstNode* node) auto bfParser = node->GetSourceData()->ToParser(); int cursorIdx = bfParser->mCursorIdx; filter = filter.Substring(0, BF_CLAMP(cursorIdx - node->GetSrcStart(), 0, (int)filter.length())); - mInsertEndIdx = cursorIdx; + mInsertEndIdx = cursorIdx; } const char* cPtr = filter.c_str(); while (cPtr[0] == '@') { mInsertStartIdx++; - cPtr++; + cPtr++; } return filter; @@ -1800,7 +1889,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken memberName = attrIdentifier->mIdentifier; if (IsAutocompleteNode(attrIdentifier->mAttributes)) { - auto bfParser = attrIdentifier->mAttributes->GetSourceData()->ToParser(); + auto bfParser = attrIdentifier->mAttributes->GetSourceData()->ToParser(); int cursorIdx = bfParser->mCursorIdx; if (cursorIdx == attrIdentifier->mAttributes->GetSrcEnd()) isAutocompletingName = true; @@ -1817,8 +1906,8 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken BfLogSys(mModule->mSystem, "Triggered autocomplete\n"); bool isFriend = false; - - mInsertStartIdx = dotToken->GetSrcEnd(); + + mInsertStartIdx = dotToken->GetSrcEnd(); if (attrIdentifier != NULL) { BfAttributeState attributeState; @@ -1832,7 +1921,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken mInsertStartIdx = attrIdentifier->mAttributes->GetSrcEnd(); } - + if (memberName != NULL) { //Member name MAY be incorrectly identified in cases like: @@ -1851,12 +1940,20 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken filter = GetFilter(memberName); } else if (mResolveType != BfResolveType_Autocomplete) - mInsertStartIdx = -1; // Require a full span for everything but autocomplete + mInsertStartIdx = -1; // Require a full span for everything but autocomplete SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); bool isStatic = false; BfTypedValue targetValue = LookupTypeRefOrIdentifier(target, &isStatic, (BfEvalExprFlags)(BfEvalExprFlags_IgnoreNullConditional | BfEvalExprFlags_NoCast), expectingType); + if ((targetValue) && (dotToken->mToken == BfToken_Arrow)) + { + SetAndRestoreValue prevIgnoreClassifying(mModule->mIsInsideAutoComplete, true); + BfExprEvaluator exprEvaluator(mModule); + auto arrowValue = exprEvaluator.PerformUnaryOperation_TryOperator(targetValue, NULL, BfUnaryOp_Arrow, BfNodeDynCast(dotToken), BfUnaryOpFlag_None); + if (arrowValue) + targetValue = arrowValue; + } bool hadResults = false; bool doAsNamespace = true; @@ -1884,13 +1981,13 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken targetValue = mModule->MakeAddressable(targetValue); BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, 1); // mValue targetValue = BfTypedValue(valuePtr, nullableType->mGenericTypeInfo->mTypeGenericArguments[0], true); - } + } } } // Statics, inner types - - auto checkType = targetValue.mType; + + auto checkType = targetValue.mType; if (checkType->IsConcreteInterfaceType()) checkType = checkType->GetUnderlyingType(); @@ -1898,7 +1995,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken { auto genericParamType = (BfGenericParamType*)checkType; auto genericParamInstance = mModule->GetGenericParamInstance(genericParamType); - + auto _HandleGenericParamInstance = [&](BfGenericParamInstance* genericParamInstance) { bool showStatics = !targetValue.mValue; @@ -1944,7 +2041,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken checkType = underlyingType; } auto typeInst = checkType->ToTypeInstance(); - if ((typeInst == NULL) && + if ((typeInst == NULL) && ((checkType->IsPrimitiveType()) || (checkType->IsSizedArray()))) typeInst = mModule->GetWrappedStructType(checkType); @@ -1957,14 +2054,14 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken bool allowProtected = allowPrivate; if (isStatic) - AddInnerTypes(typeInst, filter, allowProtected, allowPrivate); + AddInnerTypes(typeInst, filter, typeInst, allowProtected, allowPrivate); if (!onlyShowTypes) { AddTypeMembers(typeInst, isStatic, !isStatic, filter, typeInst, false, false, false); if (!isStatic) - { + { auto checkTypeInst = mModule->mCurTypeInstance; while (checkTypeInst != NULL) { @@ -2010,9 +2107,9 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken BfProject* bfProject = GetActiveProject(); auto _CheckProject = [&](BfProject* project) - { + { if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite))) - { + { for (auto namespacePair : project->mNamespaces) { const BfAtomComposite& namespaceComposite = namespacePair.mKey; @@ -2025,7 +2122,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken } if (!isUsingDirective) - { + { BfProject* activeProject = GetActiveProject(); for (auto typeDef : mSystem->mTypeDefs) { @@ -2035,7 +2132,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken { AddTypeDef(typeDef, filter, onlyAttribute); } - } + } } hadResults = true; @@ -2060,7 +2157,7 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken return hadResults; } else - { + { auto identifierNode = BfNodeDynCast(target); if (identifierNode != NULL) CheckIdentifier(identifierNode); @@ -2087,7 +2184,7 @@ bool BfAutoComplete::CheckExplicitInterface(BfTypeInstance* interfaceType, BfAst } else return false; - + mModule->PopulateType(interfaceType, BfPopulateType_DataAndMethods); String filter; @@ -2096,11 +2193,13 @@ bool BfAutoComplete::CheckExplicitInterface(BfTypeInstance* interfaceType, BfAst auto activeTypeDef = mModule->GetActiveTypeDef(); + BfShow checkShow = BfShow_Hide; + for (auto methodDef : interfaceType->mTypeDef->mMethods) { if (methodDef->mIsOverride) continue; - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; if (methodDef->mName.IsEmpty()) continue; @@ -2115,14 +2214,13 @@ bool BfAutoComplete::CheckExplicitInterface(BfTypeInstance* interfaceType, BfAst continue; bool canUseMethod; - canUseMethod = (methodDef->mMethodType == BfMethodType_Normal); + canUseMethod = (methodDef->mMethodType == BfMethodType_Normal); if (canUseMethod) { AddMethod(interfaceType, methodDef, NULL, methodDef->GetMethodDeclaration(), methodDef->mName, filter); } } - return false; } @@ -2196,13 +2294,13 @@ void BfAutoComplete::CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier } if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) - { + { // Only consider the left side as an identifier if there's space after the dot. Consider this: // mVal. // Type a = null; // vs // mVal.Type a = null; - // The first one is clearly a member reference being typed out even though it looks the same + // The first one is clearly a member reference being typed out even though it looks the same // to the parser except for the spacing if ((qualifiedTypeRef->mRight == NULL) || (qualifiedTypeRef->mDot->GetSrcEnd() < qualifiedTypeRef->mRight->GetSrcStart())) { @@ -2250,11 +2348,11 @@ void BfAutoComplete::CheckInvocation(BfAstNode* invocationNode, BfTokenNode* ope else { // Ignore close paren - lenAdd = -1; + lenAdd = -1; } - + if (!IsAutocompleteNode(invocationNode, lenAdd)) - return; + return; if (openParen == NULL) { @@ -2295,14 +2393,14 @@ void BfAutoComplete::CheckInvocation(BfAstNode* invocationNode, BfTokenNode* ope bool doCapture = (bfParser->mCursorIdx >= openParen->GetSrcStart()); if (mIsGetDefinition) - { + { doCapture |= (target != NULL) && (bfParser->mCursorIdx >= target->GetSrcStart()); } if (doCapture) - { + { mIsCapturingMethodMatchInfo = true; - + delete mMethodMatchInfo; mMethodMatchInfo = new MethodMatchInfo(); @@ -2347,7 +2445,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho { StringT<128> methodPrefix; StringT<128> methodName; - StringT<256> impString; + StringT<256> impString; bool isAbstract = (methodDef->mIsAbstract) || (isInterface) || (!methodDef->mIsVirtual); @@ -2357,22 +2455,22 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho impString += "return default;"; } else if (!isAbstract) - { + { if (!methodInst->mReturnType->IsVoid()) impString = "return "; impString += "base."; impString += methodDef->mName; - impString += "("; + impString += "("; } auto methodDeclaration = methodDef->GetMethodDeclaration(); if (isInterface) - { + { if (!isExplicitInterface) methodPrefix += "public "; - } + } else if (methodDeclaration->mProtectionSpecifier != NULL) methodPrefix += methodDeclaration->mProtectionSpecifier->ToString() + " "; if (!isInterface) @@ -2439,14 +2537,14 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho methodName += ")"; if (methodInst->GetNumGenericArguments() > 0) - { + { for (int genericArgIdx = 0; genericArgIdx < (int)methodInst->mMethodInfoEx->mGenericParams.size(); genericArgIdx++) - { + { auto genericParam = methodInst->mMethodInfoEx->mGenericParams[genericArgIdx]; - - if (genericParam->mTypeConstraint != NULL) + + if (genericParam->mTypeConstraint != NULL) methodName += " where " + genericParam->GetName() + " : " + mModule->TypeToString(genericParam->mTypeConstraint, nameFlags); - + for (auto ifaceConstraint : genericParam->mInterfaceConstraints) methodName += " where " + genericParam->GetName() + " : " + mModule->TypeToString(ifaceConstraint, nameFlags); @@ -2461,15 +2559,15 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Delete) != 0) methodName += " where " + genericParam->GetName() + " : delete"; if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0) - methodName += " where " + genericParam->GetName() + " : var"; - } + methodName += " where " + genericParam->GetName() + " : var"; + } } if (!isAbstract) impString += ");"; if (showString != NULL) - *showString += methodName; + *showString += methodName; if (insertString != NULL) { if (showString == insertString) @@ -2493,7 +2591,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho if (propDeclaration->mNameNode != NULL) propDeclaration->mNameNode->ToString(propName); - else + else { StringT<128> args; @@ -2563,7 +2661,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho impl += "set\t"; if (!isAbstract) { - if (!isInterface) + if (!isInterface) { impl += "base."; impl += propName; @@ -2581,7 +2679,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho if (showString == insertString) *insertString += "\t"; *insertString += impl; - } + } return true; } @@ -2597,12 +2695,14 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter) auto activeTypeDef = mModule->GetActiveTypeDef(); + BfShow checkShow = BfShow_Hide; + BfTypeInstance* curType = mModule->mCurTypeInstance; while (curType != NULL) { for (auto methodDef : curType->mTypeDef->mMethods) { - if (methodDef->mIsNoShow) + if (methodDef->mShow >= checkShow) continue; bool allowInternalOverride = false; @@ -2621,7 +2721,7 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter) if (methodDef->mIsExtern) allowInternalOverride = true; } - + auto& methodGroup = curType->mMethodInstanceGroups[methodDef->mIdx]; if (methodGroup.mDefault == NULL) { @@ -2635,12 +2735,12 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter) } else if ((!methodDef->mIsVirtual) || (methodDef->mIsOverride)) continue; - + if ((methodDef->mMethodType != BfMethodType_Normal) && (methodDef->mMethodType != BfMethodType_PropertyGetter) && (methodDef->mMethodType != BfMethodType_PropertySetter)) continue; - + if ((methodInst->mVirtualTableIdx >= 0) && (methodInst->mVirtualTableIdx < mModule->mCurTypeInstance->mVirtualMethodTable.size())) { auto& vEntry = mModule->mCurTypeInstance->mVirtualMethodTable[methodInst->mVirtualTableIdx]; @@ -2664,14 +2764,13 @@ void BfAutoComplete::AddOverrides(const StringImpl& filter) void BfAutoComplete::UpdateReplaceData() { - } void BfAutoComplete::CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod) { if (/*(propertyDeclaration->mDefinitionBlock == NULL) &&*/ (methodDeclaration->mVirtualSpecifier != NULL) && (methodDeclaration->mVirtualSpecifier->GetToken() == BfToken_Override)) - { + { auto bfParser = methodDeclaration->mVirtualSpecifier->GetSourceData()->ToParser(); if (bfParser == NULL) return; @@ -2734,8 +2833,8 @@ void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration) if (type != NULL) typeInst = type->ToTypeInstance(); - if (typeInst != NULL) - CheckExplicitInterface(typeInst, propertyDeclaration->mExplicitInterfaceDotToken, propertyDeclaration->mNameNode); + if (typeInst != NULL) + CheckExplicitInterface(typeInst, propertyDeclaration->mExplicitInterfaceDotToken, propertyDeclaration->mNameNode); } if ((propertyDeclaration->mVirtualSpecifier != NULL) && @@ -2754,7 +2853,7 @@ void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration) if (((IsAutocompleteNode(propertyDeclaration, 1)) && (cursorIdx == propertyDeclaration->mVirtualSpecifier->GetSrcEnd())) || (isInTypeRef) || (isInNameNode)) - { + { mInsertStartIdx = propertyDeclaration->mVirtualSpecifier->GetSrcStart(); String filter; @@ -2765,17 +2864,17 @@ void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration) defNode = propertyDeclaration->mNameNode; else if (isInTypeRef) defNode = propertyDeclaration->mTypeRef; - - filter = defNode->ToString(); + + filter = defNode->ToString(); mInsertEndIdx = defNode->GetSrcEnd(); - } + } else if (propertyDeclaration->mTypeRef != NULL) { - // We're just inside 'override' - we may be inserting a new method + // We're just inside 'override' - we may be inserting a new method mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd(); } else - { + { mInsertEndIdx = propertyDeclaration->mVirtualSpecifier->GetSrcEnd(); } AddOverrides(filter); @@ -2790,14 +2889,14 @@ void BfAutoComplete::CheckProperty(BfPropertyDeclaration* propertyDeclaration) } void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedType) -{ +{ if (IsAutocompleteNode(varTypeRef)) - { + { if ((resolvedType == NULL) || (resolvedType->IsVar()) || (resolvedType->IsLet())) return; if (mIsGetDefinition) - { + { auto typeInst = resolvedType->ToTypeInstance(); if (typeInst != NULL) { @@ -2838,7 +2937,7 @@ void BfAutoComplete::CheckResult(BfAstNode* node, const BfTypedValue& typedValue else if (BfIRConstHolder::IsFloat(constant->mTypeCode)) { mResultString = StrFormat(":%f", constant->mDouble); - } + } } void BfAutoComplete::CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl) @@ -2854,7 +2953,7 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v if (mResolveType == BfResolveType_GoToDefinition) { if (IsAutocompleteNode(identifierNode)) - { + { if (varDecl->mNameNode != NULL) SetDefinitionLocation(varDecl->mNameNode, true); else if (varDecl->mIsThis) @@ -2863,9 +2962,9 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v } else if (mResolveType == BfResolveType_GetSymbolInfo) { - if ((IsAutocompleteNode(identifierNode)) && + if ((IsAutocompleteNode(identifierNode)) && ((!varDecl->mIsShadow) || (varDecl->mShadowedLocal != NULL))) - { + { if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing)) { @@ -2876,13 +2975,13 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v auto rootMethodInstance = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance; if (rootMethodInstance == NULL) return; - + if (varDecl->mIsThis) return; - auto resolvePassData = mModule->mCompiler->mResolvePassData; + auto resolvePassData = mModule->mCompiler->mResolvePassData; mDefType = mModule->mCurTypeInstance->mTypeDef; - + mReplaceLocalId = varDecl->mLocalVarId; mDefMethod = rootMethodInstance->mMethodDef; if (mInsertStartIdx == -1) @@ -2891,28 +2990,28 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v mInsertEndIdx = identifierNode->GetSrcEnd(); } } - } + } else if (mResolveType == BfResolveType_GetResultString) { if (IsAutocompleteNode(identifierNode)) - { + { String constStr; if (varDecl->mConstValue.IsConst()) - constStr = ConstantToString(mModule->mBfIRBuilder, varDecl->mConstValue); + constStr = ConstantToString(mModule->mBfIRBuilder, varDecl->mConstValue); if (!constStr.IsEmpty()) { mResultString = constStr; } else { - SetResultStringType(varDecl->mResolvedType); + SetResultStringType(varDecl->mResolvedType); } } - } + } } void BfAutoComplete::CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst) -{ +{ if (mResolveType == BfResolveType_GetSymbolInfo) { if (mDefField != NULL) @@ -2949,14 +3048,14 @@ void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* pre if (identifierNode != NULL) { if ((mModule->mCompiler->mResolvePassData != NULL) && (scopeData != NULL)) - { + { auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, scopeData->mScopeLocalId); } if (!IsAutocompleteNode(identifierNode)) return; - + if (scopeData != NULL) { if (mResolveType == BfResolveType_GoToDefinition) @@ -3000,7 +3099,7 @@ void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* pre if (!IsAutocompleteNode(precedingNode, expectSpacing)) return; - + auto bfParser = precedingNode->GetSourceData()->ToParser(); if (bfParser->mCursorIdx != precedingNode->GetSrcEnd() + expectSpacing - 1) return; @@ -3021,12 +3120,12 @@ void BfAutoComplete::CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* pre void BfAutoComplete::CheckNamespace(BfAstNode* node, const BfAtomComposite& namespaceName) { if (mResolveType == BfResolveType_GetSymbolInfo) - { + { if (IsAutocompleteNode(node)) - { + { int namespaceCount = namespaceName.mSize; auto checkNode = node; - + while (auto qualifiedTypeRef = BfNodeDynCast(checkNode)) { if (!IsAutocompleteNode(qualifiedTypeRef->mLeft)) @@ -3041,22 +3140,24 @@ void BfAutoComplete::CheckNamespace(BfAstNode* node, const BfAtomComposite& name namespaceCount--; checkNode = qualifiedNameNode->mLeft; } - - while (auto qualifiedTypeRef = BfNodeDynCast(checkNode)) - checkNode = qualifiedTypeRef->mRight; + + while (auto qualifiedTypeRef = BfNodeDynCast(checkNode)) + checkNode = qualifiedTypeRef->mRight; while (auto qualifiedNameNode = BfNodeDynCast(checkNode)) checkNode = qualifiedNameNode->mRight; - mInsertStartIdx = checkNode->GetSrcStart(); - mInsertEndIdx = checkNode->GetSrcEnd(); - - mDefNamespace.Set(namespaceName.mParts, namespaceCount, NULL, 0); + if (checkNode != NULL) + { + mInsertStartIdx = checkNode->GetSrcStart(); + mInsertEndIdx = checkNode->GetSrcEnd(); + mDefNamespace.Set(namespaceName.mParts, namespaceCount, NULL, 0); + } } - } + } } void BfAutoComplete::AddTypeInstanceEntry(BfTypeInstance* typeInst) -{ +{ String bestTypeName = mModule->TypeToString(typeInst, BfTypeNameFlag_ReduceName); if (typeInst->IsValueType()) @@ -3070,16 +3171,16 @@ bool BfAutoComplete::CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* { if (mDocumentationEntryName.IsEmpty()) return false; - + if (mDocumentationEntryName != entry->mDisplay) return false; if (documentation != NULL) { StringT<128> str; - documentation->GetDocString(str); + documentation->GetDocString(str); entry->mDocumentation = mAlloc.AllocString(str); - } + } return true; } @@ -3100,9 +3201,9 @@ void BfAutoComplete::CheckEmptyStart(BfAstNode* prevNode, BfType* type) wantCursorIdx++; if (prevNode->GetSourceData()->ToParser()->mCursorIdx != wantCursorIdx) return; - + AddTypeInstanceEntry(type->ToTypeInstance()); - CheckIdentifier(NULL); + CheckIdentifier(NULL); mInsertStartIdx = wantCursorIdx + 1; mInsertEndIdx = mInsertStartIdx; } @@ -3112,6 +3213,8 @@ bool BfAutoComplete::CheckFixit(BfAstNode* node) { if (mIgnoreFixits) return false; + if (mModule == NULL) + return false; if (mCompiler->mResolvePassData->mResolveType != BfResolveType_GetFixits) return false; if (!IsAutocompleteLineNode(node)) @@ -3159,7 +3262,7 @@ void BfAutoComplete::CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode if (!CheckFixit(node)) return; if (typeInstance == NULL) - return; + return; if (typeInstance->IsInterface()) return; @@ -3189,7 +3292,7 @@ void BfAutoComplete::CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode continue; // Don't consider overrides here // If we have "ProjA depends on LibBase", "ProjB depends on LibBase", then a type ClassC in LibBase implementing IFaceD, - // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC -- + // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC -- // the visibility is bidirectional. A type ClassF implementing IFaceD inside ProjB will not be required to implement // MethodE, however if ((!ifaceInst->IsTypeMemberAccessible(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType)) && @@ -3208,7 +3311,7 @@ void BfAutoComplete::CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode } if (!missingMethods.IsEmpty()) - { + { BfParserData* parser = declTypeDef->mTypeDeclaration->GetSourceData()->ToParserData(); if (parser != NULL) { @@ -3403,16 +3506,16 @@ void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& ca } } - bool isSimpleCase = false; + bool isSimpleCase = false; if (!typeInst->mTypeDef->mFields.IsEmpty()) - { + { if (auto block = BfNodeDynCast(typeInst->mTypeDef->mTypeDeclaration->mDefineNode)) { bool endsInComma = false; if (!block->mChildArr.IsEmpty()) - { - auto lastNode = block->mChildArr.back(); + { + auto lastNode = block->mChildArr.back(); if (auto tokenNode = BfNodeDynCast(lastNode)) { if (tokenNode->mToken == BfToken_Comma) @@ -3445,7 +3548,7 @@ void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& ca } } - if (!isSimpleCase) + if (!isSimpleCase) { fieldStr += "|case "; fieldStr += caseName; @@ -3453,13 +3556,13 @@ void BfAutoComplete::FixitAddCase(BfTypeInstance* typeInst, const StringImpl& ca if (!fieldTypes.IsEmpty()) { fieldStr += "("; - FixitGetParamString(fieldTypes, fieldStr); + FixitGetParamString(fieldTypes, fieldStr); fieldStr += ")"; } fieldStr += ";"; - } + } - AddEntry(AutoCompleteEntry("fixit", StrFormat("Create case '%s' in '%s'\taddField|%s|%s", caseName.c_str(), fullName.c_str(), + AddEntry(AutoCompleteEntry("fixit", StrFormat("Create case '%s' in '%s'\taddField|%s|%s", caseName.c_str(), fullName.c_str(), FixitGetLocation(parser->mParserData, fileLoc).c_str(), fieldStr.c_str()).c_str())); } @@ -3507,7 +3610,7 @@ void BfAutoComplete::FixitGetParamString(const BfTypeVector& paramTypes, StringI { checkName[0] = tolower(checkName[0]); for (int i = 1; i < (int)checkName.length(); i++) - { + { if ((i + 1 < (int)checkName.length()) && (islower(checkName[i + 1]))) break; @@ -3555,56 +3658,56 @@ String BfAutoComplete::FixitGetLocation(BfParserData* parser, int insertPos) String BfAutoComplete::ConstantToString(BfIRConstHolder* constHolder, BfIRValue id) { char str[32]; - + int stringId = mModule->GetStringPoolIdx(id, constHolder); if (stringId != -1) { BfStringPoolEntry* entry; if (mModule->mContext->mStringObjectIdMap.TryGetValue(stringId, &entry)) { - String result = "\""; + String result = "\""; result += SlashString(entry->mString, true, true, true); result += "\""; return result; - } + } } - + auto constant = constHolder->GetConstant(id); switch (constant->mTypeCode) { case BfTypeCode_Boolean: return StrFormat(":(bool) %s", constant->mBool ? "true" : "false"); case BfTypeCode_UInt8: - return StrFormat(":(uint8) %llu", constant->mUInt64); + return StrFormat(":(uint8) %llu", constant->mUInt64); case BfTypeCode_UInt16: - return StrFormat(":(uint16) %llu", constant->mUInt64); + return StrFormat(":(uint16) %llu", constant->mUInt64); case BfTypeCode_UInt32: - return StrFormat(":(uint32) %llu", constant->mUInt64); + return StrFormat(":(uint32) %llu", constant->mUInt64); case BfTypeCode_UInt64: - return StrFormat(":(uint64) %llu", constant->mUInt64); + return StrFormat(":(uint64) %llu", constant->mUInt64); case BfTypeCode_Int8: - return StrFormat(":(int8) %lld", constant->mInt64); + return StrFormat(":(int8) %lld", constant->mInt64); case BfTypeCode_Int16: return StrFormat(":(int16) %lld", constant->mInt64); case BfTypeCode_Int32: - return StrFormat(":(int32) %lld", constant->mInt64); + return StrFormat(":(int32) %lld", constant->mInt64); case BfTypeCode_Int64: - return StrFormat(":(int64) %lld", constant->mInt64); + return StrFormat(":(int64) %lld", constant->mInt64); - case BfTypeCode_Float: - { + case BfTypeCode_Float: + { ExactMinimalFloatToStr((float)constant->mDouble, str); String result; - result += str; + result += str; result += "f"; return result; - } + } case BfTypeCode_Double: { ExactMinimalDoubleToStr(constant->mDouble, str); String result; - result += str; + result += str; return result; } default: @@ -3687,7 +3790,7 @@ void BfAutoComplete::FixitCheckNamespace(BfTypeDef* activeTypeDef, BfAstNode* ty BfSizedAtomComposite namespaceComposite; String namespaceString = typeRef->ToString(); bool isValid = mSystem->ParseAtomComposite(namespaceString, namespaceComposite); - + bool hasNamespace = false; if (activeTypeDef != NULL) hasNamespace = activeTypeDef->mNamespaceSearch.Contains(namespaceComposite); @@ -3698,7 +3801,7 @@ void BfAutoComplete::FixitCheckNamespace(BfTypeDef* activeTypeDef, BfAstNode* ty FixitGetLocation(parserData, typeRef->GetSrcStart()).c_str(), nextDotToken->GetSrcEnd() - typeRef->GetSrcStart()).c_str())); } else - { + { FixitAddNamespace(typeRef, namespaceString); } } @@ -3721,7 +3824,7 @@ void BfAutoComplete::FixitAddConstructor(BfTypeInstance *typeInstance) auto methodInstance = mModule->GetRawMethodInstanceAtIdx(baseType, methodDef->mIdx); String ctorShowName; - + int insertPos = FixitGetMemberInsertPos(mModule->mCurTypeInstance->mTypeDef); String methodStr = "\f\a"; if (methodInstance->mMethodDef->mHasAppend) @@ -3742,7 +3845,7 @@ void BfAutoComplete::FixitAddConstructor(BfTypeInstance *typeInstance) case BfParamKind_Params: methodStr += "params "; break; - default: + default: break; } methodStr += mModule->TypeToString(methodInstance->GetParamType(paramIdx), BfTypeNameFlag_ReduceName); @@ -3750,7 +3853,7 @@ void BfAutoComplete::FixitAddConstructor(BfTypeInstance *typeInstance) methodStr += methodInstance->GetParamName(paramIdx); useParamIdx++; } - methodStr += ") : base("; + methodStr += ") : base("; ctorShowName += "this("; useParamIdx = 0; @@ -3815,3 +3918,27 @@ void BfAutoComplete::SetResultStringType(BfType * type) else mResultString += "\n:type\tvaluetype"; } + +void BfAutoComplete::FixitAddFullyQualify(BfAstNode* refNode, const StringImpl& findName, const SizedArrayImpl& foundList) +{ + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; + String fullName; + for (int entryIdx = 0; entryIdx < foundList.mSize - 1; entryIdx++) + { + auto& entry = foundList[entryIdx]; + if (entryIdx > 0) + fullName += "."; + if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject, entry.GetProtection(), mModule->mCurTypeInstance)) + fullName += "[Friend]"; + fullName += entry.GetName(mModule); + } + + BfParserData* parser = refNode->GetSourceData()->ToParserData(); + if (parser != NULL) + { + AddEntry(AutoCompleteEntry("fixit", StrFormat("Fully qualify 'using' name as '%s.%s'\tqualify|%s|%d|%s.", + fullName.c_str(), findName.c_str(), + parser->mFileName.c_str(), refNode->mSrcStart, + fullName.c_str()).c_str())); + } +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index bd650988..adb40c3f 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/IDEHelper/Compiler/BfAutoComplete.h @@ -62,7 +62,7 @@ public: } bool operator==(const AutoCompleteEntry& other) const - { + { return strcmp(mDisplay, other.mDisplay) == 0; } }; @@ -73,7 +73,7 @@ template <> struct BeefHash { size_t operator()(const Beefy::AutoCompleteEntry& val) - { + { intptr hash = 0; const char* curPtr = val.mDisplay; while (true) @@ -92,7 +92,7 @@ NS_BF_BEGIN class AutoCompleteBase { -public: +public: class EntryLess { public: @@ -103,7 +103,7 @@ public: result = strcmp(left.mDisplay, right.mDisplay); return result < 0; } - }; + }; public: BumpAllocator mAlloc; @@ -128,13 +128,13 @@ public: class BfAutoComplete : public AutoCompleteBase { -public: +public: class MethodMatchEntry { - public: + public: BfMethodDef* mMethodDef; BfFieldInstance* mPayloadEnumField; - BfTypeInstance* mTypeInstance; + BfTypeInstance* mTypeInstance; BfTypeVector mGenericArguments; BfMethodInstance* mCurMethodInstance; @@ -142,34 +142,34 @@ public: { mMethodDef = NULL; mPayloadEnumField = NULL; - mTypeInstance = NULL; + mTypeInstance = NULL; mCurMethodInstance = NULL; } }; class MethodMatchInfo { - public: + public: BfTypeInstance* mCurTypeInstance; BfMethodInstance* mCurMethodInstance; Array mInstanceList; int mInvocationSrcIdx; - int mBestIdx; - int mPrevBestIdx; + int mBestIdx; + int mPrevBestIdx; bool mHadExactMatch; - int mMostParamsMatched; + int mMostParamsMatched; Array mSrcPositions; // start, commas, end - + public: MethodMatchInfo() { mInvocationSrcIdx = -1; mCurTypeInstance = NULL; mCurMethodInstance = NULL; - mBestIdx = 0; - mPrevBestIdx = -1; + mBestIdx = 0; + mPrevBestIdx = -1; mHadExactMatch = false; - mMostParamsMatched = 0; + mMostParamsMatched = 0; } ~MethodMatchInfo() @@ -177,10 +177,10 @@ public: } }; -public: +public: BfModule* mModule; BfCompiler* mCompiler; - BfSystem* mSystem; + BfSystem* mSystem; MethodMatchInfo* mMethodMatchInfo; bool mIsCapturingMethodMatchInfo; String mDefaultSelection; @@ -196,8 +196,8 @@ public: bool mForceAllowNonStatic; int mCursorLineStart; int mCursorLineEnd; - - int mReplaceLocalId; + + int mReplaceLocalId; BfMethodDef* mDefMethod; BfTypeDef* mDefType; BfFieldDef* mDefField; @@ -206,7 +206,7 @@ public: int mDefMethodGenericParamIdx; int mDefTypeGenericParamIdx; -public: +public: BfProject* GetActiveProject(); bool WantsEntries(); bool CheckProtection(BfProtection protection, BfTypeDef* typeDef, bool allowProtected, bool allowPrivate); @@ -216,38 +216,38 @@ public: bool IsAutocompleteNode(BfAstNode* node, int lengthAdd = 0, int startAdd = 0); bool IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode, int lengthAdd = 0, int startAdd = 0); bool IsAutocompleteLineNode(BfAstNode* node); - BfTypedValue LookupTypeRefOrIdentifier(BfAstNode* node, bool* isStatic, BfEvalExprFlags evalExprFlags = BfEvalExprFlags_None, BfType* expectingType = NULL); + BfTypedValue LookupTypeRefOrIdentifier(BfAstNode* node, bool* isStatic, BfEvalExprFlags evalExprFlags = BfEvalExprFlags_None, BfType* expectingType = NULL); void SetDefinitionLocation(BfAstNode* astNode, bool force = false); - bool IsAttribute(BfTypeInstance* typeInst); + bool IsAttribute(BfTypeInstance* typeInst); void AddMethod(BfTypeInstance* typeInstance, BfMethodDef* methodDef, BfMethodInstance* methodInstance, BfMethodDeclaration* methodDecl, const StringImpl& methodName, const StringImpl& filter); void AddField(BfTypeInstance* typeInst, BfFieldDef* fieldDef, BfFieldInstance* fieldInstance, const StringImpl& filter); void AddProp(BfTypeInstance* typeInst, BfPropertyDef* propDef, const StringImpl& filter); void AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute = false); - void AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate); + void AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, BfTypeInstance* startType, bool allowProtected, bool allowPrivate); void AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute); void AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis, bool checkOuterType); void AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate); bool InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter); - void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate); + void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate); void AddExtensionMethods(BfTypeInstance* targetType, BfTypeInstance* extensionContainer, const StringImpl& filter, bool allowProtected, bool allowPrivate); void AddTopLevelNamespaces(BfAstNode* identifierNode); void AddTopLevelTypes(BfAstNode* identifierNode, bool onlyAttribute = false); void AddOverrides(const StringImpl& filter); - void UpdateReplaceData(); + void UpdateReplaceData(); void AddTypeInstanceEntry(BfTypeInstance* typeInst); bool CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation); bool GetMethodInfo(BfMethodInstance* methodInst, StringImpl* methodName, StringImpl* insertString, bool isImplementing, bool isExplicitInterface); void FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr); int FixitGetMemberInsertPos(BfTypeDef* typeDef); String FixitGetLocation(BfParserData* parserData, int insertPos); - String ConstantToString(BfIRConstHolder* constHolder, BfIRValue id); + String ConstantToString(BfIRConstHolder* constHolder, BfIRValue id); public: BfAutoComplete(BfResolveType resolveType = BfResolveType_Autocomplete, bool doFuzzyAutoComplete = false); ~BfAutoComplete(); void SetModule(BfModule* module); - void Clear(); + void Clear(); void RemoveMethodMatchInfo(); void ClearMethodMatchEntries(); @@ -256,27 +256,28 @@ public: bool CheckExplicitInterface(BfTypeInstance* interfaceType, BfAstNode* dotToken, BfAstNode* memberName); void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false); void CheckAttributeTypeRef(BfTypeReference* typeRef); - void CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray& commas); + void CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray& commas); void CheckNode(BfAstNode* node, bool mayBeIdentifier, bool isInExpression = false); void CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod); - void CheckProperty(BfPropertyDeclaration* propertyDeclaration); + void CheckProperty(BfPropertyDeclaration* propertyDeclaration); void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef); void CheckResult(BfAstNode* node, const BfTypedValue& typedValue); void CheckLocalDef(BfAstNode* identifierNode, BfLocalVariable* varDecl); void CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* varDecl); - void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst); + void CheckFieldRef(BfAstNode* identifierNode, BfFieldInstance* fieldInst); void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode, BfScopeData* scopeData); void CheckNamespace(BfAstNode* node, const BfAtomComposite& namespaceName); - void CheckEmptyStart(BfAstNode* prevNode, BfType* type); - bool CheckFixit(BfAstNode* node); + void CheckEmptyStart(BfAstNode* prevNode, BfType* type); + bool CheckFixit(BfAstNode* node); void CheckInterfaceFixit(BfTypeInstance* typeInstance, BfAstNode* node); - + void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom); void FixitAddCase(BfTypeInstance * typeInst, const StringImpl & caseName, const BfTypeVector & fieldTypes); void FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic); void FixitAddNamespace(BfAstNode* refNode, const StringImpl& namespacStr); void FixitCheckNamespace(BfTypeDef* activeTypeDef, BfAstNode* typeRef, BfTokenNode* nextDotToken); void FixitAddConstructor(BfTypeInstance* typeInstance); + void FixitAddFullyQualify(BfAstNode* refNode, const StringImpl& findName, const SizedArrayImpl& foundList); void SetResultStringType(BfType* type); }; diff --git a/IDEHelper/Compiler/BfCodeGen.cpp b/IDEHelper/Compiler/BfCodeGen.cpp index dc1a8040..4bd41ff6 100644 --- a/IDEHelper/Compiler/BfCodeGen.cpp +++ b/IDEHelper/Compiler/BfCodeGen.cpp @@ -57,7 +57,6 @@ USING_NS_BF; using namespace llvm; - String BfCodeGenDirectoryData::GetDataFileName() { return mDirectoryName + "/build.dat"; @@ -89,7 +88,7 @@ void BfCodeGenDirectoryData::Read() for (int fileIdx = 0; fileIdx < numFiles; fileIdx++) { String fileName = fileStream.ReadAscii32SizedString(); - BfCodeGenFileData fileData; + BfCodeGenFileData fileData; fileStream.Read(&fileData.mIRHash, sizeof(Val128)); fileStream.Read(&fileData.mIROrderedHash, sizeof(Val128)); fileStream.Read(&fileData.mLastWasObjectWrite, sizeof(bool)); @@ -159,7 +158,7 @@ void BfCodeGenDirectoryData::Write() } void BfCodeGenDirectoryData::Verify() -{ +{ if (!mError.empty()) return; @@ -171,12 +170,12 @@ void BfCodeGenDirectoryData::Verify() } else { - mError = "Build directory corrupted, perform clean"; - } + mError = "Build directory corrupted, perform clean"; + } } void BfCodeGenDirectoryData::Clear() -{ +{ mFileMap.Clear(); mBuildSettings.Clear(); } @@ -187,16 +186,16 @@ bool BfCodeGenDirectoryData::CheckCache(const StringImpl& fileName, Val128 hash, Verify(); BfCodeGenFileData* fileData = NULL; - + if (!mFileMap.TryAdd(fileName, NULL, &fileData)) - { + { if ((fileData->mLastWasObjectWrite) && (disallowObjectWrite)) return false; if (outOrderedHash != NULL) *outOrderedHash = fileData->mIROrderedHash; - if (fileData->mIRHash == hash) - return true; - fileData->mIRHash = hash; + if (fileData->mIRHash == hash) + return true; + fileData->mIRHash = hash; return false; } @@ -212,9 +211,9 @@ void BfCodeGenDirectoryData::SetHash(const StringImpl& fileName, Val128 hash, Va BfCodeGenFileData* fileData = NULL; - mFileMap.TryAdd(fileName, NULL, &fileData); + mFileMap.TryAdd(fileName, NULL, &fileData); fileData->mIRHash = hash; - fileData->mIROrderedHash = orderedHash; + fileData->mIROrderedHash = orderedHash; fileData->mLastWasObjectWrite = isObjectWrite; } @@ -223,7 +222,6 @@ void BfCodeGenDirectoryData::ClearHash(const StringImpl& fileName) mFileMap.Remove(fileName); } - void BfCodeGenDirectoryData::FileFailed() { mFileFailed = true; @@ -240,7 +238,7 @@ String BfCodeGenDirectoryData::GetValue(const StringImpl& key) } void BfCodeGenDirectoryData::SetValue(const StringImpl& key, const StringImpl& value) -{ +{ mBuildSettings[key] = value; } @@ -265,16 +263,16 @@ void DbgSaveData(BfCodeGenRequest* genRequest) ////////////////////////////////////////////////////////////////////////// BfCodeGenThread::BfCodeGenThread() -{ +{ mShuttingDown = false; - mRunning = false; + mRunning = false; mThreadIdx = 0; mCodeGen = NULL; } BfCodeGenThread::~BfCodeGenThread() { - Shutdown(); + Shutdown(); } void BfCodeGenThread::RunLoop() @@ -282,21 +280,21 @@ void BfCodeGenThread::RunLoop() String threadName = StrFormat("CodeGen/Worker %d", mThreadIdx); BpSetThreadName(threadName.c_str()); BfpThread_SetName(NULL, threadName.c_str(), NULL); - + while (!mShuttingDown) - { + { BfCodeGenRequest* request = NULL; { AutoCrit autoCrit(mCodeGen->mPendingRequestCritSect); if (!mCodeGen->mPendingRequests.IsEmpty()) { request = mCodeGen->mPendingRequests[0]; - mCodeGen->mPendingRequests.RemoveAt(0); + mCodeGen->mPendingRequests.RemoveAt(0); } } if (request == NULL) - { + { mCodeGen->mRequestEvent.WaitFor(20); continue; } @@ -318,7 +316,7 @@ void BfCodeGenThread::RunLoop() #ifndef CODEGEN_DISABLE_CACHE { - AutoCrit autoCrit(mCodeGen->mCacheCritSect); + AutoCrit autoCrit(mCodeGen->mCacheCritSect); dirCache = mCodeGen->GetDirCache(cacheDir); //For testing only! @@ -328,11 +326,11 @@ void BfCodeGenThread::RunLoop() fileStr.Write(request->mData.mVals, request->mData.mSize); }*/ - HashContext hashCtx; + HashContext hashCtx; hashCtx.Mixin(request->mOptions.mHash); - hashCtx.Mixin(request->mData.mVals, request->mData.mSize); + hashCtx.Mixin(request->mData.mVals, request->mData.mSize); hash = hashCtx.Finish128(); - + hasCacheMatch = dirCache->CheckCache(cacheFileName, hash, &orderedHash, isLibWrite); #ifdef BF_PLATFORM_WINDOWS @@ -346,10 +344,9 @@ void BfCodeGenThread::RunLoop() hash = Val128(); hasCacheMatch = false; } - } + } #endif - } #endif @@ -360,7 +357,7 @@ void BfCodeGenThread::RunLoop() hasCacheMatch = false; #endif - String errorMsg; + String errorMsg; bool doBEProcessing = true; // TODO: Normally 'true' so we do ordered cache check for LLVM too if (request->mOptions.mOptLevel == BfOptLevel_OgPlus) @@ -375,7 +372,7 @@ void BfCodeGenThread::RunLoop() } else { -#ifdef BF_PLATFORM_WINDOWS +#ifdef BF_PLATFORM_WINDOWS BeIRCodeGen* beIRCodeGen = new BeIRCodeGen(); defer ( delete beIRCodeGen; ); @@ -383,17 +380,17 @@ void BfCodeGenThread::RunLoop() beIRCodeGen->SetConfigConst(BfIRConfigConst_DynSlotOfs, request->mOptions.mDynSlotOfs); if (doBEProcessing) - { - BP_ZONE("ProcessBfIRData"); + { + BP_ZONE("ProcessBfIRData"); beIRCodeGen->Init(request->mData); BeHashContext hashCtx; hashCtx.Mixin(request->mOptions.mHash); - beIRCodeGen->Hash(hashCtx); + beIRCodeGen->Hash(hashCtx); auto newOrderedHash = hashCtx.Finish128(); BfLogX(2, "Ordered hash for %s New:%s Old:%s\n", cacheFileName.c_str(), newOrderedHash.ToString().c_str(), orderedHash.ToString().c_str()); hasCacheMatch = newOrderedHash == orderedHash; - + errorMsg = beIRCodeGen->mErrorMsg; orderedHash = newOrderedHash; } @@ -402,10 +399,10 @@ void BfCodeGenThread::RunLoop() { result.mType = BfCodeGenResult_DoneCached; } - + #ifndef CODEGEN_DISABLE_CACHE { - AutoCrit autoCrit(mCodeGen->mCacheCritSect); + AutoCrit autoCrit(mCodeGen->mCacheCritSect); dirCache->SetHash(cacheFileName, hash, orderedHash, !isLibWrite); } #endif @@ -416,7 +413,7 @@ void BfCodeGenThread::RunLoop() // } else if (request->mOptions.mOptLevel == BfOptLevel_OgPlus) - { + { #ifdef BF_PLATFORM_WINDOWS BP_ZONE("BfCodeGen::RunLoop.Beef"); @@ -432,7 +429,7 @@ void BfCodeGenThread::RunLoop() { if (!errorMsg.empty()) errorMsg += "\n"; - errorMsg += "Failed writing IR '" + fileName + "': " + ec.message(); + errorMsg += "Failed writing IR '" + fileName + "': " + ec.message(); } else fs.WriteSNZ(str); @@ -445,9 +442,9 @@ void BfCodeGenThread::RunLoop() BfLogX(2, "Generating obj %s\n", request->mOutFileName.c_str()); BeCOFFObject coffObject; - coffObject.mWriteToLib = request->mOptions.mWriteToLib; + coffObject.mWriteToLib = request->mOptions.mWriteToLib; if (!coffObject.Generate(beIRCodeGen->mBeModule, objFileName)) - errorMsg = StrFormat("Failed to write object file: %s", objFileName.c_str()); + errorMsg = StrFormat("Failed to write object file: %s", objFileName.c_str()); if (!beIRCodeGen->mErrorMsg.IsEmpty()) { @@ -467,14 +464,14 @@ void BfCodeGenThread::RunLoop() BfIRCodeGen* llvmIRCodeGen = new BfIRCodeGen(); llvmIRCodeGen->SetCodeGenOptions(request->mOptions); llvmIRCodeGen->SetConfigConst(BfIRConfigConst_VirtualMethodOfs, request->mOptions.mVirtualMethodOfs); - llvmIRCodeGen->SetConfigConst(BfIRConfigConst_DynSlotOfs, request->mOptions.mDynSlotOfs); + llvmIRCodeGen->SetConfigConst(BfIRConfigConst_DynSlotOfs, request->mOptions.mDynSlotOfs); llvmIRCodeGen->ProcessBfIRData(request->mData); - + errorMsg = llvmIRCodeGen->mErrorMsg; llvmIRCodeGen->mErrorMsg.Clear(); if (errorMsg.IsEmpty()) - { + { if (request->mOptions.mWriteLLVMIR) { BP_ZONE("BfCodeGen::RunLoop.LLVM.IR"); @@ -503,16 +500,16 @@ void BfCodeGenThread::RunLoop() result.mType = BfCodeGenResult_Failed; dirCache->FileFailed(); } - } + } } - + if (!llvmIRCodeGen->mErrorMsg.IsEmpty()) { if (!errorMsg.IsEmpty()) errorMsg += "\n"; errorMsg += llvmIRCodeGen->mErrorMsg; } - + delete llvmIRCodeGen; } } @@ -538,9 +535,9 @@ void BfCodeGenThread::RunLoop() // It's an extern request, so we own this bool deleteRequest = false; if (request->mExternResultPtr != NULL) - { + { *request->mExternResultPtr = result; - deleteRequest = true; + deleteRequest = true; } // We need this fence for BF_USE_CODEGEN_RELEASE_THUNK usage- because we can't access the request anymore after setting @@ -549,21 +546,21 @@ void BfCodeGenThread::RunLoop() AutoCrit autoCrit(mCodeGen->mPendingRequestCritSect); request->mResult = result; - mCodeGen->mDoneEvent.Set(); + mCodeGen->mDoneEvent.Set(); if (deleteRequest) delete request; - } + } } mRunning = false; - mCodeGen->mDoneEvent.Set(); + mCodeGen->mDoneEvent.Set(); } void BfCodeGenThread::Shutdown() { mShuttingDown = true; if (mRunning) - mCodeGen->mRequestEvent.Set(true); + mCodeGen->mRequestEvent.Set(true); while (mRunning) { @@ -580,11 +577,11 @@ static void BFP_CALLTYPE RunLoopThunk(void* codeGenThreadP) void BfCodeGenThread::Start() { - mRunning = true; + mRunning = true; //TODO: How much mem do we need? WTF- we have 32MB set before! auto mThread = BfpThread_Create(RunLoopThunk, (void*)this, 1024 * 1024, BfpThreadCreateFlag_StackSizeReserve); BfpThread_SetPriority(mThread, BfpThreadPriority_Low, NULL); - BfpThread_Release(mThread); + BfpThread_Release(mThread); } ////////////////////////////////////////////////////////////////////////// @@ -592,7 +589,7 @@ void BfCodeGenThread::Start() BfCodeGen::BfCodeGen() { mAttemptedReleaseThunkLoad = false; - mIsUsingReleaseThunk = false; + mIsUsingReleaseThunk = false; mReleaseModule = NULL; mClearCacheFunc = NULL; mGetVersionFunc = NULL; @@ -600,10 +597,10 @@ BfCodeGen::BfCodeGen() mCancelFunc = NULL; mFinishFunc = NULL; mGenerateObjFunc = NULL; - + mRequestIdx = 0; #ifdef MAX_THREADS - mMaxThreadCount = MAX_THREADS; + mMaxThreadCount = MAX_THREADS; #else mMaxThreadCount = 6; #endif @@ -703,7 +700,7 @@ void BfCodeGen::UpdateStats() auto request = mRequests[0]; if (request->mResult.mType == BfCodeGenResult_NotDone) return; - + RequestComplete(request); delete request; mRequests.RemoveAt(0); @@ -732,7 +729,7 @@ void BfCodeGen::ClearBuildCache() for (auto& dirCachePair : mDirectoryCache) { auto dirData = dirCachePair.mValue; - dirData->Clear(); + dirData->Clear(); } // This just disables reading the cache file, but it does not disable creating // the cache structes in memory and writing them out, thus it's valid to leave @@ -747,9 +744,9 @@ void BfCodeGen::ClearBuildCache() } void BfCodeGen::DoWriteObjectFile(BfCodeGenRequest* codeGenRequest, const void* ptr, int size, const StringImpl& outFileName, BfCodeGenResult* externResultPtr) -{ +{ codeGenRequest->mData.mVals = (uint8*)ptr; - codeGenRequest->mData.mSize = size; + codeGenRequest->mData.mSize = size; codeGenRequest->mOutFileName = outFileName; codeGenRequest->mResult.mType = BfCodeGenResult_NotDone; codeGenRequest->mResult.mErrorMsgBufLen = 0; @@ -769,11 +766,11 @@ void BfCodeGen::DoWriteObjectFile(BfCodeGenRequest* codeGenRequest, const void* auto thread = mThreads[threadIdx]; BP_ZONE("WriteObjectFile_CritSect"); - AutoCrit autoCrit(mPendingRequestCritSect); + AutoCrit autoCrit(mPendingRequestCritSect); mPendingRequests.push_back(codeGenRequest); #ifdef BF_PLATFORM_WINDOWS - BF_ASSERT(!mRequestEvent.mEvent->mManualReset); // Make sure it's out of the SignalAll state + BF_ASSERT(!mRequestEvent.mEvent->mManualReset); // Make sure it's out of the SignalAll state #endif mRequestEvent.Set(); @@ -843,11 +840,11 @@ bool BfCodeGen::ExternWriteObjectFile(BfCodeGenRequest* codeGenRequest) #ifndef BF_USE_CODEGEN_RELEASE_THUNK return false; #endif - + BindReleaseThunks(); if (!mIsUsingReleaseThunk) - return false; + return false; mGenerateObjFunc(codeGenRequest->mData.mVals, codeGenRequest->mData.mSize, codeGenRequest->mOutFileName.c_str(), &codeGenRequest->mResult, codeGenRequest->mOptions); @@ -855,15 +852,15 @@ bool BfCodeGen::ExternWriteObjectFile(BfCodeGenRequest* codeGenRequest) } void BfCodeGen::WriteObjectFile(BfModule* bfModule, const StringImpl& outFileName, const BfCodeGenOptions& options) -{ +{ mQueuedCount++; - + BfLogSys(bfModule->mSystem, "WriteObjectFile %s\n", outFileName.c_str()); - BfCodeGenRequest* codeGenRequest = new BfCodeGenRequest(); + BfCodeGenRequest* codeGenRequest = new BfCodeGenRequest(); mRequests.push_back(codeGenRequest); - - { + + { BP_ZONE("WriteObjectFile_GetBufferData"); bfModule->mBfIRBuilder->GetBufferData(codeGenRequest->mOutBuffer); } @@ -873,13 +870,13 @@ void BfCodeGen::WriteObjectFile(BfModule* bfModule, const StringImpl& outFileNam rootModule = rootModule->mParentModule; codeGenRequest->mSrcModule = rootModule; - codeGenRequest->mOutFileName = outFileName; - codeGenRequest->mData = codeGenRequest->mOutBuffer; + codeGenRequest->mOutFileName = outFileName; + codeGenRequest->mData = codeGenRequest->mOutBuffer; codeGenRequest->mOptions = options; if (ExternWriteObjectFile(codeGenRequest)) - return; + return; - DoWriteObjectFile(codeGenRequest, (void*)&codeGenRequest->mOutBuffer[0], (int)codeGenRequest->mOutBuffer.size(), codeGenRequest->mOutFileName, NULL); + DoWriteObjectFile(codeGenRequest, (void*)&codeGenRequest->mOutBuffer[0], (int)codeGenRequest->mOutBuffer.size(), codeGenRequest->mOutFileName, NULL); #ifdef DBG_FORCE_SYNCHRONIZED while (mRequests.size() != 0) @@ -918,7 +915,7 @@ void BfCodeGen::RequestComplete(BfCodeGenRequest* request) if ((request->mResult.mType == BfCodeGenResult_Failed) || (request->mResult.mType == BfCodeGenResult_Aborted)) { BfCodeGenErrorEntry errorEntry; - errorEntry.mSrcModule = request->mSrcModule; + errorEntry.mSrcModule = request->mSrcModule; errorEntry.mOutFileName = request->mOutFileName; int errorPos = 0; @@ -928,7 +925,7 @@ void BfCodeGen::RequestComplete(BfCodeGenRequest* request) errorEntry.mErrorMessages.push_back(errorStr); errorPos += (int)strlen(errorStr) + 1; } - + mFailedRequests.push_back(errorEntry); } else @@ -970,7 +967,7 @@ void BfCodeGen::ProcessErrors(BfPassInstance* passInstance, bool canceled) { passInstance->Fail(dirEntry->mError); showedCacheError = true; - } + } dirEntry->mError.clear(); } } @@ -1000,7 +997,7 @@ void BfCodeGen::Cancel() { for (auto thread : mThreads) { - thread->mShuttingDown = true; + thread->mShuttingDown = true; } mRequestEvent.Set(true); @@ -1016,9 +1013,9 @@ void BfCodeGen::ClearResults() } bool BfCodeGen::Finish() -{ +{ BP_ZONE("BfCodeGen::Finish"); - + while (mRequests.size() != 0) { auto request = mRequests[0]; @@ -1047,7 +1044,7 @@ bool BfCodeGen::Finish() return false; } - if (mIsUsingReleaseThunk) + if (mIsUsingReleaseThunk) { // Make the thunk release its threads (and more important, its LLVM contexts) mFinishFunc(); @@ -1056,14 +1053,14 @@ bool BfCodeGen::Finish() // We need to shut down these threads to remove their memory for (auto thread : mThreads) { - thread->mShuttingDown = true; - mOldThreads.push_back(thread); + thread->mShuttingDown = true; + mOldThreads.push_back(thread); } mThreads.Clear(); mRequestEvent.Set(true); ClearOldThreads(false); - + // for (auto request : mPendingRequests) // { // if (request->mExternResultPtr != NULL) @@ -1073,7 +1070,7 @@ bool BfCodeGen::Finish() // } // //request->mResult.mType = BfCodeGenResult_Aborted; // //delete request; -// } +// } // mPendingRequests.Clear(); /// @@ -1113,8 +1110,8 @@ BF_EXPORT int BF_CALLTYPE BfCodeGen_GetVersion() BF_EXPORT void BF_CALLTYPE BfCodeGen_ClearCache() { - GetExternCodeGen(); - gExternCodeGen->ClearBuildCache(); + GetExternCodeGen(); + gExternCodeGen->ClearBuildCache(); } BF_EXPORT void BF_CALLTYPE BfCodeGen_Finish() @@ -1129,7 +1126,7 @@ BF_EXPORT void BF_CALLTYPE BfCodeGen_Finish() BF_EXPORT void BF_CALLTYPE BfCodeGen_Kill() { delete gExternCodeGen; - gExternCodeGen = NULL; + gExternCodeGen = NULL; Targets_Delete(); } @@ -1140,11 +1137,10 @@ BF_EXPORT void BF_CALLTYPE BfCodeGen_Cancel() } BF_EXPORT void BF_CALLTYPE BfCodeGen_GenerateObj(const void* ptr, int size, const char* outFileName, BfCodeGenResult* resultPtr, const BfCodeGenOptions& options) -{ +{ GetExternCodeGen(); - BfCodeGenRequest* codeGenRequest = new BfCodeGenRequest(); + BfCodeGenRequest* codeGenRequest = new BfCodeGenRequest(); codeGenRequest->mOptions = options; gExternCodeGen->DoWriteObjectFile(codeGenRequest, ptr, size, outFileName, resultPtr); -} - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfCodeGen.h b/IDEHelper/Compiler/BfCodeGen.h index e8edec6b..8ae8b955 100644 --- a/IDEHelper/Compiler/BfCodeGen.h +++ b/IDEHelper/Compiler/BfCodeGen.h @@ -45,16 +45,15 @@ public: Array mErrorMessages; }; - class BfCodeGenRequest { -public: +public: BfModule* mSrcModule; BfCodeGenOptions mOptions; BfCodeGenResult mResult; Array mOutBuffer; BfSizedArray mData; - String mOutFileName; + String mOutFileName; BfCodeGenResult* mExternResultPtr; @@ -64,13 +63,13 @@ public: mSrcModule = NULL; mResult.mType = BfCodeGenResult_NotDone; mResult.mErrorMsgBufLen = 0; - mExternResultPtr = NULL; + mExternResultPtr = NULL; } ~BfCodeGenRequest() - { + { } - + void DbgSaveData(); }; @@ -78,18 +77,18 @@ class BfCodeGen; class BfCodeGenThread { -public: - BfCodeGen* mCodeGen; +public: + BfCodeGen* mCodeGen; int mThreadIdx; - //std::vector mRequests; + //std::vector mRequests; volatile bool mShuttingDown; volatile bool mRunning; public: bool RawWriteObjectFile(llvm::Module* module, const StringImpl& outFileName, const BfCodeGenOptions& codeGenOptions); - -public: + +public: BfCodeGenThread(); ~BfCodeGenThread(); @@ -103,7 +102,7 @@ class BfCodeGenFileData { public: Val128 mIRHash; // Equal when exact IR bits are equal - Val128 mIROrderedHash; // Equal when isomorphic (when alphabetically reordered functions hash equally) + Val128 mIROrderedHash; // Equal when isomorphic (when alphabetically reordered functions hash equally) bool mLastWasObjectWrite; }; @@ -115,7 +114,7 @@ public: Dictionary mBuildSettings; String mDirectoryName; bool mDirty; - bool mVerified; + bool mVerified; int64 mFileTime; String mError; bool mFileFailed; @@ -163,18 +162,18 @@ public: typedef void (BF_CALLTYPE* FinishFunc)(); typedef void (BF_CALLTYPE* GenerateObjFunc)(const void* ptr, int size, const char* outFileName, BfCodeGenResult* resultPtr, const BfCodeGenOptions& options); -public: +public: BfpDynLib* mReleaseModule; bool mAttemptedReleaseThunkLoad; bool mIsUsingReleaseThunk; ClearCacheFunc mClearCacheFunc; GetVersionFunc mGetVersionFunc; - KillFunc mKillFunc; + KillFunc mKillFunc; CancelFunc mCancelFunc; FinishFunc mFinishFunc; - GenerateObjFunc mGenerateObjFunc; + GenerateObjFunc mGenerateObjFunc; - Val128 mBackendHash; + Val128 mBackendHash; int mMaxThreadCount; CritSect mThreadsCritSect; Array mThreads; @@ -184,19 +183,19 @@ public: Deque mPendingRequests; SyncEvent mRequestEvent; int mRequestIdx; - SyncEvent mDoneEvent; + SyncEvent mDoneEvent; int mQueuedCount; - int mCompletionCount; + int mCompletionCount; Array mFailedRequests; Array mCodeGenFiles; - + CritSect mCacheCritSect; bool mDisableCacheReads; Dictionary mDirectoryCache; -public: +public: void SetMaxThreads(int maxThreads); void BindReleaseThunks(); void ClearResults(); @@ -208,13 +207,13 @@ public: void ProcessErrors(BfPassInstance* passInstance, bool canceled); BfCodeGenDirectoryData* GetDirCache(const StringImpl& cacheDir); -public: +public: BfCodeGen(); ~BfCodeGen(); void ResetStats(); void UpdateStats(); - void WriteObjectFile(BfModule* module, const StringImpl& outFileName, const BfCodeGenOptions& options); + void WriteObjectFile(BfModule* module, const StringImpl& outFileName, const BfCodeGenOptions& options); String GetBuildValue(const StringImpl& buildDir, const StringImpl& key); void SetBuildValue(const StringImpl& buildDir, const StringImpl& key, const StringImpl& value); void WriteBuildCache(const StringImpl& buildDir); diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index df43e3c1..d13b9bef 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -40,7 +40,7 @@ namespace llvm extern bool DebugFlag; } -#define SPLIT_CONTEXTS +#define SPLIT_CONTEXTS Beefy::BfCompiler* gBfCompiler = NULL; @@ -50,11 +50,11 @@ void pt(llvm::Type* t) Beefy::debug_ostream os; t->print(os); - os << "\n"; + os << "\n"; os << " isSized: " << t->isSized() << "\n"; os.flush(); - if (auto pointerType = llvm::dyn_cast(t)) + if (auto pointerType = llvm::dyn_cast(t)) { Beefy::OutputDebugStrF("Element: "); pt(pointerType->getElementType()); @@ -76,7 +76,7 @@ void pt(llvm::DINode* t) { Beefy::debug_ostream os; t->print(os); - os << "\n"; + os << "\n"; os.flush(); } @@ -145,13 +145,13 @@ void PrintUsers(llvm::MDNode* md) return L.second.second < R.second.second; }); for (const auto &Pair : Uses) - { + { auto Owner = Pair.second.first; os << Beefy::StrFormat(" %d %p %d\n", Pair.second.first.isNull(), Pair.first, Pair.second.second, Pair).c_str(); } os << "\n"; - } + } os.flush();*/ } @@ -205,13 +205,12 @@ GlobalVariable* AllocGlobalVariable(Module &M, Type *Ty, bool isConstant, GlobalValue::ThreadLocalMode tlm = GlobalValue::NotThreadLocal, unsigned AddressSpace = 0, bool isExternallyInitialized = false); - #include "BeefySysLib/util/AllocDebug.h" ////////////////////////////////////////////////////////////////////////// BfCompiler::HotData::~HotData() -{ +{ for (auto& kv : mMethodMap) { auto hotMethod = kv.mValue; @@ -229,8 +228,8 @@ BfCompiler::HotData::~HotData() kv.mValue->Deref(); for (auto& kv : mInnerMethods) kv.mValue->Deref(); - for (auto& kv : mMethodMap) - kv.mValue->Deref(); + for (auto& kv : mMethodMap) + kv.mValue->Deref(); } template @@ -257,7 +256,7 @@ static typename TDict::value_type AllocFromMap(TDict& dict, TElement* elem) typename TDict::value_type* valuePtr; if (dict.TryAdd(elem, NULL, &valuePtr)) { - auto val = new typename std::remove_pointer::type(elem); + auto val = new typename std::remove_pointer::type(elem); val->mRefCount++; *valuePtr = val; } @@ -270,7 +269,7 @@ void BfCompiler::HotData::ClearUnused(bool isHotCompile) DeleteUnused(mThisType); DeleteUnused(mAllocation); - DeleteUnused(mDevirtualizedMethods); + DeleteUnused(mDevirtualizedMethods); DeleteUnused(mVirtualDecls); DeleteUnused(mInnerMethods); @@ -297,7 +296,7 @@ BfHotDevirtualizedMethod* BfCompiler::HotData::GetDevirtualizedMethod(BfHotMetho } BfHotFunctionReference* BfCompiler::HotData::GetFunctionReference(BfHotMethod* hotMethod) -{ +{ return AllocFromMap(mFuncPtrs, hotMethod); } @@ -308,12 +307,11 @@ BfHotInnerMethod* BfCompiler::HotData::GetInnerMethod(BfHotMethod* hotMethod) BfHotVirtualDeclaration* BfCompiler::HotData::GetVirtualDeclaration(BfHotMethod* hotMethod) { - return AllocFromMap(mVirtualDecls, hotMethod); + return AllocFromMap(mVirtualDecls, hotMethod); } BfCompiler::HotState::~HotState() { - } bool BfCompiler::HotState::HasPendingChanges(BfTypeInstance* type) @@ -326,7 +324,7 @@ void BfCompiler::HotState::RemovePendingChanges(BfTypeInstance* type) BF_ASSERT(type->mHotTypeData->mPendingDataChange); if (!type->mHotTypeData->mPendingDataChange) return; - type->mHotTypeData->mPendingDataChange = false; + type->mHotTypeData->mPendingDataChange = false; bool didRemove = mPendingDataChanges.Remove(type->mTypeId); BF_ASSERT(didRemove); } @@ -344,7 +342,7 @@ BfCompiler::HotResolveData::~HotResolveData() BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) { memset(&mStats, 0, sizeof(mStats)); - mCompletionPct = 0; + mCompletionPct = 0; mCanceling = false; mHasRequiredTypes = false; mNeedsFullRefresh = false; @@ -353,30 +351,31 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mIsResolveOnly = isResolveOnly; mResolvePassData = NULL; mPassInstance = NULL; - mRevision = 0; + mRevision = 0; + mUniqueId = 0; mLastRevisionAborted = false; gBfCompiler = this; mSystem = bfSystem; - mCurTypeId = 1; + mCurTypeId = 1; mTypeInitCount = 0; //mMaxInterfaceSlots = 16; mMaxInterfaceSlots = -1; mInterfaceSlotCountChanged = false; mLastHadComptimeRebuilds = false; mHasComptimeRebuilds = false; - mDepsMayHaveDeletedTypes = false; - + mDepsMayHaveDeletedTypes = false; + mHSPreserveIdx = 0; mCompileLogFP = NULL; - mWantsDeferMethodDecls = false; + mWantsDeferMethodDecls = false; mHadCancel = false; mCompileState = CompileState_None; - //mMaxInterfaceSlots = 4; + //mMaxInterfaceSlots = 4; mHotData = NULL; - mHotState = NULL; + mHotState = NULL; mHotResolveData = NULL; - + mBfObjectTypeDef = NULL; mChar32TypeDef = NULL; mFloatTypeDef = NULL; @@ -392,7 +391,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mIndexTypeDef = NULL; mIndexRangeTypeDef = NULL; mAttributeTypeDef = NULL; - mAttributeUsageAttributeTypeDef = NULL; + mAttributeUsageAttributeTypeDef = NULL; mClassVDataTypeDef = NULL; mCLinkAttributeTypeDef = NULL; mImportAttributeTypeDef = NULL; @@ -406,7 +405,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mDisableObjectAccessChecksAttributeTypeDef = NULL; mDbgRawAllocDataTypeDef = NULL; mDeferredCallTypeDef = NULL; - mDelegateTypeDef = NULL; + mDelegateTypeDef = NULL; mFunctionTypeDef = NULL; mActionTypeDef = NULL; mEnumTypeDef = NULL; @@ -415,7 +414,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mConstEvalAttributeTypeDef = NULL; mNoExtensionAttributeTypeDef = NULL; mCheckedAttributeTypeDef = NULL; - mUncheckedAttributeTypeDef = NULL; + mUncheckedAttributeTypeDef = NULL; mGCTypeDef = NULL; mGenericIEnumerableTypeDef = NULL; mGenericIEnumeratorTypeDef = NULL; @@ -432,7 +431,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mIPrintableTypeDef = NULL; mIHashableTypeDef = NULL; mIComptimeTypeApply = NULL; - mIComptimeMethodApply = NULL; + mIComptimeMethodApply = NULL; mIOnTypeInitTypeDef = NULL; mIOnTypeDoneTypeDef = NULL; mIOnFieldInitTypeDef = NULL; @@ -462,13 +461,13 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mReflectFieldInfoTypeDef = NULL; mReflectMethodInfoTypeDef = NULL; mSizedArrayTypeDef = NULL; - mStaticInitAfterAttributeTypeDef = NULL; + mStaticInitAfterAttributeTypeDef = NULL; mStaticInitPriorityAttributeTypeDef = NULL; mStringTypeDef = NULL; mStringViewTypeDef = NULL; mThreadStaticAttributeTypeDef = NULL; mTypeTypeDef = NULL; - mUnboundAttributeTypeDef = NULL; + mUnboundAttributeTypeDef = NULL; mValueTypeTypeDef = NULL; mResultTypeDef = NULL; mObsoleteAttributeTypeDef = NULL; @@ -481,10 +480,10 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mLastAutocompleteModule = NULL; - mContext = new BfContext(this); + mContext = new BfContext(this); mCeMachine = new CeMachine(this); mCurCEExecuteId = -1; - mLastMidCompileRefreshRevision = -1; + mLastMidCompileRefreshRevision = -1; } BfCompiler::~BfCompiler() @@ -493,15 +492,15 @@ BfCompiler::~BfCompiler() mCeMachine = NULL; delete mContext; delete mHotData; - delete mHotState; - delete mHotResolveData; + delete mHotState; + delete mHotResolveData; } bool BfCompiler::IsTypeAccessible(BfType* checkType, BfProject* curProject) { if (checkType->IsBoxed()) return IsTypeAccessible(((BfBoxedType*)checkType)->mElementType, curProject); - + BfTypeInstance* typeInst = checkType->ToTypeInstance(); if (typeInst != NULL) { @@ -524,17 +523,17 @@ bool BfCompiler::IsTypeAccessible(BfType* checkType, BfProject* curProject) return curProject->ContainsReference(typeInst->mTypeDef->mProject); } - + if (checkType->IsPointer()) return IsTypeAccessible(((BfPointerType*)checkType)->mElementType, curProject); if (checkType->IsRef()) return IsTypeAccessible(((BfPointerType*)checkType)->mElementType, curProject); - + return true; } bool BfCompiler::IsTypeUsed(BfType* checkType, BfProject* curProject) -{ +{ if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) return IsTypeAccessible(checkType, curProject); @@ -550,7 +549,7 @@ bool BfCompiler::IsTypeUsed(BfType* checkType, BfProject* curProject) if (checkType->IsInterface()) return typeInst->mIsReified; - + //TODO: We could check to see if this project has any reified specialized instances... if (checkType->IsUnspecializedType()) return typeInst->mIsReified; @@ -612,17 +611,17 @@ void BfCompiler::FixVDataHash(BfModule* bfModule) } void BfCompiler::CheckModuleStringRefs(BfModule* module, BfVDataModule* vdataModule, int lastModuleRevision, HashSet& foundStringIds, HashSet& dllNameSet, Array& dllMethods, Array& stringValueEntries) -{ +{ for (int stringId : module->mStringPoolRefs) - { + { if (foundStringIds.Add(stringId)) - { + { BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; - + if (IsHotCompile()) { if (vdataModule->mDefinedStrings.Contains(stringId)) - continue; + continue; } StringValueEntry stringEntry; @@ -662,13 +661,13 @@ void BfCompiler::HashModuleVData(BfModule* module, HashContext& vdataHash) module->mStringPoolRefs.Sort([](int lhs, int rhs) { return lhs < rhs; }); vdataHash.Mixin(&module->mStringPoolRefs[0], (int)module->mStringPoolRefs.size() * (int)sizeof(int)); } - + if (module->mImportFileNames.size() > 0) { module->mImportFileNames.Sort([](int lhs, int rhs) { return lhs < rhs; }); vdataHash.Mixin(&module->mImportFileNames[0], (int)module->mImportFileNames.size() * (int)sizeof(int)); } - + auto altModule = module->mNextAltModule; while (altModule != NULL) { @@ -771,7 +770,7 @@ BfIRFunction BfCompiler::CreateLoadSharedLibraries(BfVDataModule* bfModule, Arra if (constant != NULL) { if (constant->IsNull()) - continue; // Invalid + continue; // Invalid strNum = constant->mInt32; } else @@ -791,8 +790,8 @@ BfIRFunction BfCompiler::CreateLoadSharedLibraries(BfVDataModule* bfModule, Arra args.push_back(namePtr); args.push_back(dllHandleVar); BfIRValue dllHandleValue = bfModule->mBfIRBuilder->CreateCall(loadSharedLibraryProc.mFunc, args); - - dllHandleMap[strNum] = dllHandleVar; + + dllHandleMap[strNum] = dllHandleVar; } String methodImportName; @@ -827,7 +826,7 @@ BfIRFunction BfCompiler::CreateLoadSharedLibraries(BfVDataModule* bfModule, Arra } } } - } + } bfModule->mBfIRBuilder->CreateRetVoid(); @@ -906,7 +905,6 @@ void BfCompiler::GetTestMethods(BfVDataModule* bfModule, Array& test vdataHashCtx.Mixin(methodInstance->mMethodDef->mIdx); }; - for (auto type : mContext->mResolvedTypes) { auto typeInstance = type->ToTypeInstance(); @@ -918,8 +916,8 @@ void BfCompiler::GetTestMethods(BfVDataModule* bfModule, Array& test for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups) { - if (methodInstanceGroup.mDefault != NULL) - _CheckMethod(typeInstance, methodInstanceGroup.mDefault); + if (methodInstanceGroup.mDefault != NULL) + _CheckMethod(typeInstance, methodInstanceGroup.mDefault); } } } @@ -1040,7 +1038,7 @@ void BfCompiler::EmitTestMethod(BfVDataModule* bfModule, Array& test else { for (int defaultIdx = 0; defaultIdx < (int)methodInstance->mDefaultValues.size(); defaultIdx++) - { + { auto constHolder = methodInstance->GetOwner()->mConstHolder; auto defaultTypedValue = methodInstance->mDefaultValues[defaultIdx]; auto defaultVal = bfModule->ConstantToCurrent(constHolder->GetConstant(defaultTypedValue.mValue), constHolder, defaultTypedValue.mType); @@ -1073,18 +1071,18 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) { bool isHotCompile = IsHotCompile(); if ((isHotCompile) && (bfModule->mProject != mOptions.mHotProject)) - return; - + return; + BP_ZONE("BfCompiler::CreateVData"); BfLogSysM("CreateVData %s\n", bfModule->mProject->mName.c_str()); CompileLog("CreateVData %s\n", bfModule->mProject->mName.c_str()); - + BF_ASSERT_REL(!bfModule->mIsDeleting); bfModule->mProject->mUsedModules.Add(bfModule); auto project = bfModule->mProject; - auto vdataContext = bfModule->mContext; - BF_ASSERT(bfModule->mModuleName == "vdata"); + auto vdataContext = bfModule->mContext; + BF_ASSERT(bfModule->mModuleName == "vdata"); ////////////////////////////////////////////////////////////////////////// @@ -1092,34 +1090,34 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) // Create types we'll need for vdata, so we won't change the vdata hash afterward // bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_NullPtr)); -// +// // /// -// +// // auto typeDefType = bfModule->ResolveTypeDef(mTypeTypeDef)->ToTypeInstance(); // if (!typeDefType) // return; // BF_ASSERT(typeDefType != NULL); // vdataContext->mBfTypeType = typeDefType->ToTypeInstance(); -// +// // auto typeInstanceDefType = bfModule->ResolveTypeDef(mReflectTypeInstanceTypeDef); // if (!typeInstanceDefType) // return; // auto typeInstanceDefTypeInstance = typeInstanceDefType->ToTypeInstance(); -// +// // auto typeDef = mSystem->FindTypeDef("System.ClassVData"); // BF_ASSERT(typeDef != NULL); -// auto bfClassVDataType = bfModule->ResolveTypeDef(typeDef)->ToTypeInstance(); +// auto bfClassVDataType = bfModule->ResolveTypeDef(typeDef)->ToTypeInstance(); // vdataContext->mBfClassVDataPtrType = bfModule->CreatePointerType(bfClassVDataType); ////////////////////////////////////////////////////////////////////////// int numEntries = 0; - int numConcreteTypes = 0; + int numConcreteTypes = 0; Array orderedTypes; for (auto type : mContext->mResolvedTypes) { - numEntries++; + numEntries++; BF_ASSERT((type != NULL) || (mPassInstance->HasFailed())); if (!type->IsReified()) @@ -1140,7 +1138,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) continue; } } - } + } { BP_ZONE("BfCompiler::CreateVData sort orderedTypes"); @@ -1151,12 +1149,12 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } BfLogSysM("TypeEntries: %d ConcreteTypes: %d\n", numEntries, numConcreteTypes); - + HashContext vdataHashCtx; //vdataHashCtx.mDbgViz = true; vdataHashCtx.Mixin(bfModule->mProject->mVDataConfigHash); - + Array testMethods; if (project->mTargetType == BfTargetType_BeefTest) GetTestMethods(bfModule, testMethods, vdataHashCtx); @@ -1169,7 +1167,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) }); struct _SortedTypeEntry - { + { BfTypeInstance* mTypeInstance; String* mTypeName; int mPriority; @@ -1183,7 +1181,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) _SortedTypeEntry(BfModule* module, BfTypeInstance* typeInstance, Array& nameList, String*& namePtr) { - if (namePtr == NULL) + if (namePtr == NULL) { namePtr = new String(module->TypeToString(typeInstance)); nameList.Add(namePtr); @@ -1215,18 +1213,18 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) }); } }; - Array<_SortedTypeEntry> preStaticInitList; + Array<_SortedTypeEntry> preStaticInitList; Array<_SortedTypeEntry> staticMarkList; Array<_SortedTypeEntry> staticTLSList; - Array vdataTypeList; + Array vdataTypeList; HashSet usedModuleSet; HashSet reflectTypeSet; HashSet reflectFieldTypeSet; vdataHashCtx.MixinStr(project->mStartupObject); vdataHashCtx.Mixin(project->mTargetType); - + for (auto type : orderedTypes) { if (type == NULL) @@ -1251,11 +1249,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BF_ASSERT((type != NULL) || (mPassInstance->HasFailed())); if ((type != NULL) && (typeInst != NULL)) - { + { auto module = typeInst->mModule; if (module == NULL) continue; - + if (type->IsEnum()) { for (auto& fieldInst : typeInst->mFieldInstances) @@ -1282,22 +1280,22 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) if (usedModuleSet.Add(module)) { CompileLog("UsedModule %p %s\n", module, module->mModuleName.c_str()); - + HashModuleVData(module, vdataHashCtx); } } - + vdataHashCtx.MixinStr(module->mModuleName); vdataHashCtx.Mixin(typeInst->mTypeDef->mSignatureHash); vdataHashCtx.Mixin(module->mHasForceLinkMarker); - + for (auto iface : typeInst->mInterfaces) { vdataHashCtx.Mixin(iface.mInterfaceType->mTypeId); vdataHashCtx.Mixin(iface.mDeclaringType->mTypeCode); vdataHashCtx.Mixin(iface.mDeclaringType->mProject); } - + if (!typeInst->IsUnspecializedType()) { for (auto& methodInstGroup : typeInst->mMethodInstanceGroups) @@ -1313,11 +1311,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) auto baseType = typeInst->mBaseType; while (baseType != NULL) { - vdataHashCtx.Mixin(baseType->mTypeDef->mSignatureHash); + vdataHashCtx.Mixin(baseType->mTypeDef->mSignatureHash); baseType = baseType->mBaseType; } - //TODO: What was this for? + //TODO: What was this for? // if (module->mProject != bfModule->mProject) // { // if ((module->mProject != NULL) && (module->mProject->mTargetType == BfTargetType_BeefDynLib)) @@ -1326,7 +1324,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) String* typeName = NULL; if ((typeInst->mHasStaticInitMethod) || (typeInst->mHasStaticDtorMethod)) - preStaticInitList.Add(_SortedTypeEntry(bfModule, typeInst, typeNameList, typeName)); + preStaticInitList.Add(_SortedTypeEntry(bfModule, typeInst, typeNameList, typeName)); if ((typeInst->mHasStaticMarkMethod) && (mOptions.mEnableRealtimeLeakCheck)) staticMarkList.Add(_SortedTypeEntry(bfModule, typeInst, typeNameList, typeName)); if ((typeInst->mHasTLSFindMethod) && (mOptions.mEnableRealtimeLeakCheck)) @@ -1336,22 +1334,22 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) int lastModuleRevision = bfModule->mRevision; Val128 vdataHash = vdataHashCtx.Finish128(); - bool wantsRebuild = vdataHash != bfModule->mDataHash; + bool wantsRebuild = vdataHash != bfModule->mDataHash; if (bfModule->mHadBuildError) wantsRebuild = true; // If we did one of those 'hot compile' partial vdata builds, now build the whole thing if ((!IsHotCompile()) && (bfModule->mHadHotObjectWrites)) wantsRebuild = true; - if (mOptions.mHotProject != NULL) + if (mOptions.mHotProject != NULL) { HashContext vdataHashCtxEx; vdataHashCtxEx.Mixin(mOptions.mHotProject->mName); - + vdataHashCtxEx.Mixin((int)mHotState->mNewlySlottedTypeIds.size()); for (auto typeId : mHotState->mNewlySlottedTypeIds) vdataHashCtxEx.Mixin(typeId); - + vdataHashCtxEx.Mixin((int)mHotState->mSlotDefineTypeIds.size()); for (auto typeId : mHotState->mSlotDefineTypeIds) vdataHashCtxEx.Mixin(typeId); @@ -1389,7 +1387,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) CompileLog("VData unchanged, skipping\n"); return; } - + BfTypeInstance* stringType = bfModule->ResolveTypeDef(mStringTypeDef, BfPopulateType_Data)->ToTypeInstance(); BfTypeInstance* stringViewType = bfModule->ResolveTypeDef(mStringViewTypeDef, BfPopulateType_Data)->ToTypeInstance(); BfTypeInstance* reflectSpecializedTypeInstance = bfModule->ResolveTypeDef(mReflectSpecializedGenericType)->ToTypeInstance(); @@ -1397,23 +1395,23 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BfTypeInstance* reflectArrayTypeInstance = bfModule->ResolveTypeDef(mReflectArrayType)->ToTypeInstance(); bool madeBfTypeData = false; - + auto typeDefType = mContext->mBfTypeType; bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType"); - bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType"); + bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType"); bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName"); bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern")) || (bfModule->IsMethodImplementedAndReified(stringViewType, "Intern")); Dictionary usedStringIdMap; - + reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef)); reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType)); reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType)); reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType)); reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType)); - - SmallVector typeDataVector; - for (auto type : vdataTypeList) + + SmallVector typeDataVector; + for (auto type : vdataTypeList) { if (type->IsTypeAlias()) continue; @@ -1422,7 +1420,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BF_ASSERT(!type->IsIncomplete()); auto typeInst = type->ToTypeInstance(); - + if ((typeInst != NULL) && (!typeInst->IsReified()) && (!typeInst->IsUnspecializedType())) continue; @@ -1435,11 +1433,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) { needsTypeData = true; if (type->IsEnum()) - forceReflectFields = true; + forceReflectFields = true; } - + BfIRValue typeVariable; - + if ((needsTypeData) || (needsVData)) { if (reflectFieldTypeSet.Contains(type)) @@ -1452,11 +1450,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) needsTypeData = true; needsVData = true; } - + typeVariable = bfModule->CreateTypeData(type, usedStringIdMap, forceReflectFields, needsTypeData, needsTypeNames, needsVData); } type->mDirty = false; - + if (needsTypeList) { int typeId = type->mTypeId; @@ -1475,7 +1473,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } // We only need 'sTypes' if we actually reference it - // + // { auto typeDefPtrType = bfModule->CreatePointerType(typeDefType); StringT<128> typesVariableName; @@ -1490,7 +1488,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) bfModule->mBfIRBuilder->CreateGlobalVariable(bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_Int32)), true, BfIRLinkageType_External, bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, (int)typeDataVector.size()), typeCountVariableName); } - + HashSet foundStringIds; for (int stringId : bfModule->mStringPoolRefs) foundStringIds.Add(stringId); @@ -1498,8 +1496,8 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) Array orderedUsedModules; for (auto module : usedModuleSet) orderedUsedModules.push_back(module); - std::sort(orderedUsedModules.begin(), orderedUsedModules.end(), [] (BfModule* lhs, BfModule* rhs) - { + std::sort(orderedUsedModules.begin(), orderedUsedModules.end(), [] (BfModule* lhs, BfModule* rhs) + { return lhs->mModuleName < rhs->mModuleName; }); @@ -1510,7 +1508,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) HashSet dllNameSet; Array stringValueEntries; for (auto module : orderedUsedModules) - { + { CheckModuleStringRefs(module, bfModule, lastModuleRevision, foundStringIds, dllNameSet, dllMethods, stringValueEntries); if ((module->mHasForceLinkMarker) && @@ -1527,7 +1525,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BfIRValue typeDataArray = bfModule->mBfIRBuilder->CreateGlobalVariable(arrayType, true, BfIRLinkageType_Internal, typeDataConst, "FORCELINK_MODULES"); } - + // Generate strings array { if (!needsStringLiteralList) @@ -1540,10 +1538,10 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) { return lhs.mId < rhs.mId; }); - + auto stringPtrType = bfModule->CreatePointerType(stringType); auto stringPtrIRType = bfModule->mBfIRBuilder->MapTypeInstPtr(stringType); - + StringT<128> stringsVariableName; BfMangler::MangleStaticFieldName(stringsVariableName, GetMangleKind(), stringType->ToTypeInstance(), "sStringLiterals", stringPtrType); Array stringList; @@ -1554,9 +1552,9 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)stringList.size()); auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList); - + auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName); - + if (bfModule->mBfIRBuilder->DbgHasInfo()) { auto dbgArrayType = bfModule->mBfIRBuilder->DbgCreateArrayType(stringList.size() * mSystem->mPtrSize * 8, mSystem->mPtrSize * 8, bfModule->mBfIRBuilder->DbgGetType(stringPtrType), (int)stringList.size()); @@ -1565,10 +1563,10 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } // Generate string ID array - { + { auto stringType = bfModule->ResolveTypeDef(mStringTypeDef, BfPopulateType_Data)->ToTypeInstance(); auto stringPtrType = bfModule->CreatePointerType(stringType); - auto stringPtrIRType = bfModule->mBfIRBuilder->MapTypeInstPtr(stringType); + auto stringPtrIRType = bfModule->mBfIRBuilder->MapTypeInstPtr(stringType); StringT<128> stringsVariableName; BfMangler::MangleStaticFieldName(stringsVariableName, GetMangleKind(), stringType->ToTypeInstance(), "sIdStringLiterals", stringPtrType); @@ -1576,7 +1574,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) stringList.Resize(usedStringIdMap.size()); for (auto& kv : usedStringIdMap) - { + { stringList[kv.mValue] = bfModule->mStringObjectPool[kv.mKey]; } @@ -1593,14 +1591,14 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } BfIRFunction loadSharedLibFunc = CreateLoadSharedLibraries(bfModule, dllMethods); - + BfIRType nullPtrType = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_NullPtr)); BfIRType voidType = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_None)); BfIRType int32Type = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_Int32)); Array<_SortedTypeEntry> staticInitList; // Populate staticInitList - { + { Dictionary pendingIDToInstanceMap; HashSet handledTypes; BfType* staticInitPriorityAttributeType = vdataContext->mUnreifiedModule->ResolveTypeDef(mStaticInitPriorityAttributeTypeDef); @@ -1638,7 +1636,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } if (!hadInitAfterAttribute) - { + { mapEntry.mPriority = priority; staticInitList.Add(mapEntry); mapEntry.mTypeInstance = NULL; @@ -1691,7 +1689,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) if (pass == 0) { - _SortedTypeEntry::Sort(staticInitList); + _SortedTypeEntry::Sort(staticInitList); } if ((pass > 0) && (!hadAdd) && (pendingIDToInstanceMap.size() > 0)) // Circular ref? @@ -1701,7 +1699,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) break; } } - + /// Generate "BfCallAllStaticDtors" BfIRFunction dtorFunc; { @@ -1713,7 +1711,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) bfModule->mBfIRBuilder->SetActiveFunction(dtorFunc); auto entryBlock = bfModule->mBfIRBuilder->CreateBlock("entry", true); bfModule->mBfIRBuilder->SetInsertPoint(entryBlock); - + for (int i = staticInitList.mSize - 1; i >= 0; i--) { auto typeInst = staticInitList[i].mTypeInstance; @@ -1748,9 +1746,9 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) isConsoleApplication = true; bool isDllMain = (targetType == BfTargetType_BeefLib_DynamicLib) && (mOptions.mPlatformType == BfPlatformType_Windows); - bool isPosixDynLib = ((targetType == BfTargetType_BeefLib_DynamicLib) || (targetType == BfTargetType_BeefLib_StaticLib)) && + bool isPosixDynLib = ((targetType == BfTargetType_BeefLib_DynamicLib) || (targetType == BfTargetType_BeefLib_StaticLib)) && (mOptions.mPlatformType != BfPlatformType_Windows); - + bool mainHasArgs = (targetType != BfTargetType_BeefLib_DynamicLib) && (targetType != BfTargetType_BeefLib_StaticLib) && (mOptions.mPlatformType != BfPlatformType_Wasm); bool mainHasRet = ((targetType != BfTargetType_BeefLib_DynamicLib) && (targetType != BfTargetType_BeefLib_StaticLib)) || (isDllMain); @@ -1770,15 +1768,15 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) paramTypes.push_back(int32Type); paramTypes.push_back(nullPtrType); mainFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false); - mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "main"); + mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "main"); bfModule->SetupIRMethod(NULL, mainFunc, false); } else if (isDllMain) - { + { SmallVector paramTypes; - paramTypes.push_back(nullPtrType); // hinstDLL + paramTypes.push_back(nullPtrType); // hinstDLL paramTypes.push_back(int32Type); // fdwReason - paramTypes.push_back(nullPtrType); // lpvReserved + paramTypes.push_back(nullPtrType); // lpvReserved mainFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false); mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "DllMain"); if (mOptions.mMachineType == BfMachineType_x86) @@ -1787,7 +1785,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) rtFlags = 0x10; // BfRtFlags_NoThreadExitWait } else if (targetType == BfTargetType_BeefWindowsApplication) - { + { SmallVector paramTypes; paramTypes.push_back(nullPtrType); // hInstance paramTypes.push_back(nullPtrType); // hPrevInstance @@ -1796,14 +1794,14 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) mainFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false); mainFunc = bfModule->mBfIRBuilder->CreateFunction(mainFuncType, BfIRLinkageType_External, "WinMain"); if (mOptions.mMachineType == BfMachineType_x86) - bfModule->mBfIRBuilder->SetFuncCallingConv(mainFunc, BfIRCallingConv_StdCall); + bfModule->mBfIRBuilder->SetFuncCallingConv(mainFunc, BfIRCallingConv_StdCall); bfModule->SetupIRMethod(NULL, mainFunc, false); - } + } else { BfIRFunction combinedFunc; - SmallVector paramTypes; + SmallVector paramTypes; if (mainHasArgs) { paramTypes.push_back(int32Type); @@ -1843,7 +1841,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) bfModule->mBfIRBuilder->SetActiveFunction(mainFunc); auto entryBlock = bfModule->mBfIRBuilder->CreateBlock("entry", true); bfModule->mBfIRBuilder->SetInsertPoint(entryBlock); - + if (rtFlags != 0) { auto addRtFlagMethod = bfModule->GetInternalMethod("AddRtFlags", 1); @@ -1868,10 +1866,10 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) SmallVector args; args.push_back(bfModule->mBfIRBuilder->GetArgument(0)); - args.push_back(bfModule->mBfIRBuilder->GetArgument(1)); + args.push_back(bfModule->mBfIRBuilder->GetArgument(1)); bfModule->mBfIRBuilder->CreateCall(setCmdLineFunc, args); } - + BfIRBlock initSkipBlock; if (isDllMain) { @@ -1909,9 +1907,9 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) continue; if (staticInitEntry.mPriority < 100) - _CheckSharedLibLoad(); + _CheckSharedLibLoad(); for (auto& methodGroup : typeInst->mMethodInstanceGroups) - { + { auto methodInstance = methodGroup.mDefault; if ((methodInstance != NULL) && (methodInstance->mMethodDef->mIsStatic) && @@ -1953,7 +1951,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) BF_ASSERT((type != NULL) || (mPassInstance->HasFailed())); if (type != NULL) { - BfType* stringType = vdataContext->mUnreifiedModule->ResolveTypeDef(mStringTypeDef); + BfType* stringType = vdataContext->mUnreifiedModule->ResolveTypeDef(mStringTypeDef); BfType* int32Type = bfModule->GetPrimitiveType(BfTypeCode_Int32); BfType* intType = bfModule->GetPrimitiveType(BfTypeCode_IntPtr); @@ -1973,7 +1971,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) mPassInstance->Fail("Main method must be static", methodDef->GetRefNode()); hadValidMainMethod = false; } - + if ((moduleMethodInst.mMethodInstance->mReturnType != int32Type) && (moduleMethodInst.mMethodInstance->mReturnType != intType) && (moduleMethodInst.mMethodInstance->mReturnType != voidType)) @@ -1981,7 +1979,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) mPassInstance->Fail("Main method must return void, int, or int32", methodDef->GetRefNode()); hadValidMainMethod = false; } - + if (moduleMethodInst.mMethodInstance->GetParamCount() == 0) { // No params @@ -1997,24 +1995,24 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } } } - + if (moduleMethodInst) { if (hadValidMainMethod) { bool hasArgs = moduleMethodInst.mMethodInstance->GetParamCount() != 0; - + BfIRType intType = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_IntPtr)); BfIRType int32Type = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_Int32)); // Create BeefEntry thunk - SmallVector paramTypes; + SmallVector paramTypes; if (hasArgs) { paramTypes.push_back(bfModule->mBfIRBuilder->MapType(moduleMethodInst.mMethodInstance->GetParamType(0))); } BfIRFunctionType thunkFuncType = bfModule->mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, false); - + BfIRFunction thunkMainFunc = bfModule->mBfIRBuilder->CreateFunction(thunkFuncType, BfIRLinkageType_External, "BeefStartProgram"); bfModule->SetupIRMethod(NULL, thunkMainFunc, false); bfModule->mBfIRBuilder->SetActiveFunction(thunkMainFunc); @@ -2041,8 +2039,8 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) hadRet = true; - auto internalType = bfModule->ResolveTypeDef(mInternalTypeDef); - + auto internalType = bfModule->ResolveTypeDef(mInternalTypeDef); + args.clear(); // Call BeefEntry thunk @@ -2050,11 +2048,11 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) if (hasArgs) { auto createParamsMethodInstance = bfModule->GetMethodByName(internalType->ToTypeInstance(), "CreateParamsArray"); - auto callValue = bfModule->mBfIRBuilder->CreateCall(createParamsMethodInstance.mFunc, SmallVector()); + auto callValue = bfModule->mBfIRBuilder->CreateCall(createParamsMethodInstance.mFunc, SmallVector()); args.push_back(callValue); } - retValue = bfModule->mBfIRBuilder->CreateCall(thunkMainFunc, args); + retValue = bfModule->mBfIRBuilder->CreateCall(thunkMainFunc, args); if (hasArgs) { @@ -2092,7 +2090,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) if (targetType == BfTargetType_BeefTest) EmitTestMethod(bfModule, testMethods, retValue); - + BfIRBlock deinitSkipBlock; if (isDllMain) { @@ -2166,25 +2164,25 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) SmallVector startArgs; bfModule->mBfIRBuilder->CreateCall(mainFunc, startArgs); - bfModule->mBfIRBuilder->CreateRetVoid(); + bfModule->mBfIRBuilder->CreateRetVoid(); ////////////////////////////////////////////////////////////////////////// - + func = bfModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_Internal, "BfDynLib__Shutdown"); bfModule->mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_Destructor); bfModule->mBfIRBuilder->SetActiveFunction(func); entryBlock = bfModule->mBfIRBuilder->CreateBlock("main", true); bfModule->mBfIRBuilder->SetInsertPoint(entryBlock); - SmallVector stopArgs; + SmallVector stopArgs; bfModule->mBfIRBuilder->CreateCall(shutdownFunc, startArgs); bfModule->mBfIRBuilder->CreateRetVoid(); } } - - // Generate "System.GC.MarkAllStaticMembers" + + // Generate "System.GC.MarkAllStaticMembers" auto gcType = vdataContext->mUnreifiedModule->ResolveTypeDef(mGCTypeDef); if (bfModule->IsMethodImplementedAndReified(gcType->ToTypeInstance(), "MarkAllStaticMembers")) - { + { bfModule->PopulateType(gcType); auto moduleMethodInstance = bfModule->GetMethodByName(gcType->ToTypeInstance(), "MarkAllStaticMembers"); bfModule->mBfIRBuilder->SetActiveFunction(moduleMethodInstance.mFunc); @@ -2203,7 +2201,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) auto typeInst = mapEntry.mTypeInstance; if (typeInst->IsUnspecializedType()) continue; - + for (auto& methodGroup : typeInst->mMethodInstanceGroups) { auto methodInstance = methodGroup.mDefault; @@ -2265,7 +2263,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) } bfModule->mBfIRBuilder->CreateRetVoid(); } - } + } if (bfModule->mHadBuildError) { @@ -2276,7 +2274,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule) // This method clears out unused generic types AFTER compilation of reified types has occurred void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) { - BP_ZONE("BfCompiler::UpdateDependencyMap"); + BP_ZONE("BfCompiler::UpdateDependencyMap"); BfLogSysM("Compiler::UpdateDependencyMap %d\n", deleteUnusued); bool madeFullPass = true; @@ -2284,12 +2282,12 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) madeFullPass = false; if ((mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty())) madeFullPass = false; - + SetAndRestoreValue prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass); if ((deleteUnusued) && (madeFullPass)) { - // Work queues should be empty if we're not canceling + // Work queues should be empty if we're not canceling BF_ASSERT(mContext->mPopulateTypeWorkList.size() == 0); BF_ASSERT(mContext->mMethodWorkList.size() == 0); } @@ -2297,13 +2295,13 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) // Remove old data in dependency maps, and find types which don't have any references (direct or indirect) // to a non-generic type and remove them for (int pass = 0; true; pass++) - { + { // This assert can fail if we have a dependency error, where deleting a type causes a dependent type // to be rebuilt BF_ASSERT(pass < 100); - bool foundNew = false; - + bool foundNew = false; + for (auto type : mContext->mResolvedTypes) { if (type != NULL) @@ -2318,14 +2316,14 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) #ifdef _DEBUG for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end(); ++itr) { - auto dependentType = itr->mKey; + auto dependentType = itr->mKey; if (dependentType->IsIncomplete()) - { + { BF_ASSERT(dependentType->IsDeleting() || dependentType->IsOnDemand() || !dependentType->HasBeenReferenced() || mCanceling || !madeFullPass || dependentType->IsSpecializedByAutoCompleteMethod()); } } #endif - + depType->mDependencyMap.mFlagsUnion = BfDependencyMap::DependencyFlag_None; // Not combined with previous loop because PopulateType could modify typeInst->mDependencyMap @@ -2334,16 +2332,16 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) auto dependentType = itr->mKey; auto depTypeInst = dependentType->ToTypeInstance(); auto& depData = itr->mValue; - + bool isInvalidVersion = (dependentType->mRevision > depData.mRevision);// && (deleteUnusued) && (madeFullPass); - + //TODO: Just to cause crash if dependentType is deleted bool isIncomplete = dependentType->IsIncomplete(); if ((isInvalidVersion) && (!dependentType->IsDeleting())) { if (!dependentType->HasBeenReferenced()) - { + { BfLogSysM("Skipping remove of old dependent %p from %p\n", dependentType, typeInst); //BF_ASSERT(dependentType->IsGenericTypeInstance()); // We have a pending type rebuild but we're not sure whether we're being deleted or not yet... @@ -2353,7 +2351,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) } if ((dependentType->IsDeleting()) || (isInvalidVersion)) - { + { if (dependentType->IsDeleting() || ((deleteUnusued) && (madeFullPass))) { // If we're deleting the type, OR the dependency of the type has been removed. @@ -2368,10 +2366,10 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) else { // There needs to be more usage than just being used as part of the method specialization's MethodGenericArg. - // Keep in mind that actually invoking a generic method creates a DependencyFlag_LocalUsage dependency. The + // Keep in mind that actually invoking a generic method creates a DependencyFlag_LocalUsage dependency. The // DependencyFlag_MethodGenericArg is just used by the owner during creation of the method specialization bool isDependentUsage = (depData.mFlags & BfDependencyMap::DependencyFlag_DependentUsageMask) != 0; - + // We need to consider specialized generic types separately, to remove unused specializations if (typeInst != NULL) { @@ -2379,10 +2377,10 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) if ((depTypeInst != NULL) && (typeInst->mLastNonGenericUsedRevision != mRevision) && (isDependentUsage) && ((isDirectReference) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision))) - { + { typeInst->mLastNonGenericUsedRevision = mRevision; foundNew = true; - + if (!typeInst->HasBeenReferenced()) { mContext->AddTypeToWorkList(typeInst); @@ -2390,19 +2388,19 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) } } } - + ++itr; } depType->mDependencyMap.mFlagsUnion = (BfDependencyMap::DependencyFlags)(depType->mDependencyMap.mFlagsUnion | depData.mFlags); } - if ((!depType->IsGenericTypeInstance() && (!depType->IsBoxed())) || + if ((!depType->IsGenericTypeInstance() && (!depType->IsBoxed())) || (depType->IsUnspecializedType()) || - ((typeInst != NULL) && (typeInst->mLastNonGenericUsedRevision == mRevision))) + ((typeInst != NULL) && (typeInst->mLastNonGenericUsedRevision == mRevision))) { if ((depType->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) != 0) - { + { mContext->MarkAsReferenced(depType); } } @@ -2411,7 +2409,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) } if (mCanceling) - madeFullPass = false; + madeFullPass = false; if (!madeFullPass) { @@ -2428,8 +2426,8 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) didWork |= DoWorkLoop(false, false); } else if (deleteUnusued) - { - // Work queues should be empty if we're not canceling + { + // Work queues should be empty if we're not canceling BF_ASSERT(mContext->mPopulateTypeWorkList.size() == 0); BF_ASSERT(mContext->mMethodWorkList.size() == 0); @@ -2438,16 +2436,16 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) // deletion, so we must set BfTypeRebuildFlag_DeleteQueued first to avoid that Array deleteQueue; - // We bubble out + // We bubble out for (auto type : mContext->mResolvedTypes) - { + { auto depType = type->ToDependedType(); // Delete if we're a generic if ((depType != NULL) && (!depType->IsDeleting())) { auto typeInst = depType->ToTypeInstance(); - + bool wantDelete = false; if (typeInst != NULL) { @@ -2463,7 +2461,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) depType->mRebuildFlags = (BfTypeRebuildFlags)(depType->mRebuildFlags | BfTypeRebuildFlag_DeleteQueued); foundNew = true; } - } + } } for (auto depType : deleteQueue) @@ -2477,16 +2475,16 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) mContext->ValidateDependencies(); mContext->UpdateAfterDeletingTypes(); mContext->ValidateDependencies(); - } + } } if (!foundNew) break; - } + } #ifdef _DEBUG if (deleteUnusued) - { + { for (auto type : mContext->mResolvedTypes) { // This flag should be handled by now @@ -2495,7 +2493,6 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) } #endif - BP_ZONE("UpdateDependencyMap QueuedSpecializedMethodRebuildTypes"); HashSet specializerSet; @@ -2518,7 +2515,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork) if ((depData.mFlags & BfDependencyMap::DependencyFlag_Calls) != 0) { specializerSet.Add(depTypeInst); - } + } } } } @@ -2545,8 +2542,8 @@ void BfCompiler::SanitizeDependencyMap() { if (type == NULL) continue; - - auto depType = type->ToDependedType(); + + auto depType = type->ToDependedType(); if (depType == NULL) continue; @@ -2554,16 +2551,16 @@ void BfCompiler::SanitizeDependencyMap() for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end();) { auto dependentType = itr->mKey; - auto depTypeInst = dependentType->ToTypeInstance(); + auto depTypeInst = dependentType->ToTypeInstance(); if (dependentType->IsDeleting()) { BfLogSysM("SanitizeDependencyMap removing old dependent %p from %p\n", dependentType, depType); - itr = depType->mDependencyMap.erase(itr); + itr = depType->mDependencyMap.erase(itr); } else ++itr; } - } + } mContext->RemoveInvalidWorkItems(); mDepsMayHaveDeletedTypes = false; @@ -2576,20 +2573,20 @@ void BfCompiler::SanitizeDependencyMap() // 3) It stays undefined and we need to build it here bool BfCompiler::ProcessPurgatory(bool reifiedOnly) { - BP_ZONE("BfCompiler::ProcessPurgatory"); + BP_ZONE("BfCompiler::ProcessPurgatory"); bool didWork = false; while (true) - { - mContext->RemoveInvalidWorkItems(); - + { + mContext->RemoveInvalidWorkItems(); + //for (auto type : mGenericInstancePurgatory) for (int i = 0; i < (int)mGenericInstancePurgatory.size(); i++) { auto type = mGenericInstancePurgatory[i]; if ((reifiedOnly) && (!type->IsReified())) - continue; + continue; if ((reifiedOnly) && ((type->mRebuildFlags & BfTypeRebuildFlag_AwaitingReference) != 0)) continue; @@ -2598,9 +2595,9 @@ bool BfCompiler::ProcessPurgatory(bool reifiedOnly) { auto module = type->GetModule(); if (module != NULL) - { + { if (!module->mIsModuleMutable) - module->StartExtension(); + module->StartExtension(); module->PopulateType(type, BfPopulateType_Full); } } @@ -2626,9 +2623,9 @@ bool BfCompiler::ProcessPurgatory(bool reifiedOnly) bool BfCompiler::VerifySlotNums() { - BP_ZONE("BfCompiler::VerifySlotNums"); + BP_ZONE("BfCompiler::VerifySlotNums"); - SmallVector isSlotUsed; + SmallVector isSlotUsed; for (auto type : mContext->mResolvedTypes) { if (!type->IsReified()) @@ -2660,7 +2657,7 @@ bool BfCompiler::VerifySlotNums() auto checkType = typeInst; while (checkType != NULL) - { + { for (auto iface : checkType->mInterfaces) { int slotNum = iface.mInterfaceType->mSlotNum; @@ -2671,17 +2668,17 @@ bool BfCompiler::VerifySlotNums() isSlotUsed[slotNum] = iface.mInterfaceType; } } - + checkType = checkType->mBaseType; } - } + } return true; } bool BfCompiler::QuickGenerateSlotNums() -{ - /*SmallVector isSlotUsed; +{ + /*SmallVector isSlotUsed; for (auto globalTypeEntry : mResolvedTypes) { BfType* type = globalTypeEntry->mType; @@ -2699,7 +2696,7 @@ bool BfCompiler::QuickGenerateSlotNums() } continue; - } + } } return VerifySlotNums();*/ @@ -2713,7 +2710,7 @@ class BfSlotEntry public: BfTypeInstance* mTypeInstance; int mRefCount; - Array mConcurrentRefs; + Array mConcurrentRefs; }; typedef std::pair InterfacePair; @@ -2726,7 +2723,7 @@ static BfSlotEntry* GetSlotEntry(SlotEntryMap& slotEntryMap, BfTypeInstance* typ BfSlotEntry** slotEntryPtr = NULL; if (!slotEntryMap.TryAdd(typeInst, NULL, &slotEntryPtr)) return *slotEntryPtr; - + BfSlotEntry* slotEntry = new BfSlotEntry(); slotEntry->mTypeInstance = typeInst; slotEntry->mRefCount = 0; @@ -2743,7 +2740,7 @@ static InterfacePair MakeInterfacePair(BfTypeInstance* iface1, BfTypeInstance* i } struct InterfacePairHash -{ +{ size_t operator()(const InterfacePair& val) const { return (((size_t)val.first) >> 2) ^ ((size_t)val.second); @@ -2752,13 +2749,13 @@ struct InterfacePairHash bool BfCompiler::SlowGenerateSlotNums() { - BP_ZONE("BfCompiler::SlowGenerateSlotNums"); - + BP_ZONE("BfCompiler::SlowGenerateSlotNums"); + SlotEntryMap ifaceUseMap; - + std::unordered_set concurrentInterfaceSet; HashSet foundIFaces; - + if (mMaxInterfaceSlots < 0) { mMaxInterfaceSlots = 0; @@ -2767,7 +2764,7 @@ bool BfCompiler::SlowGenerateSlotNums() bool isHotCompile = IsHotCompile(); for (auto type : mContext->mResolvedTypes) - { + { if (!type->IsReified()) continue; @@ -2792,7 +2789,7 @@ bool BfCompiler::SlowGenerateSlotNums() } foundIFaces.Clear(); - auto checkTypeInst = typeInst; + auto checkTypeInst = typeInst; while (checkTypeInst != NULL) { for (auto iface : checkTypeInst->mInterfaces) @@ -2823,7 +2820,7 @@ bool BfCompiler::SlowGenerateSlotNums() { auto iface1 = *itr1; auto iface2 = *itr2; - + InterfacePair ifacePair = MakeInterfacePair(iface1, iface2); if (concurrentInterfaceSet.insert(ifacePair).second) { @@ -2831,29 +2828,29 @@ bool BfCompiler::SlowGenerateSlotNums() BfSlotEntry* entry2 = GetSlotEntry(ifaceUseMap, iface2); entry1->mConcurrentRefs.push_back(iface2); entry2->mConcurrentRefs.push_back(iface1); - } + } } - } - } - - Array sortedIfaceUseMap; + } + } + + Array sortedIfaceUseMap; for (auto& entry : ifaceUseMap) { if (!isHotCompile) BF_ASSERT(entry.mValue->mTypeInstance->mSlotNum == -1); sortedIfaceUseMap.push_back(entry.mValue); - } - - std::sort(sortedIfaceUseMap.begin(), sortedIfaceUseMap.end(), [] (BfSlotEntry* lhs, BfSlotEntry* rhs) - { + } + + std::sort(sortedIfaceUseMap.begin(), sortedIfaceUseMap.end(), [] (BfSlotEntry* lhs, BfSlotEntry* rhs) + { if (lhs->mRefCount != rhs->mRefCount) - return lhs->mRefCount > rhs->mRefCount; + return lhs->mRefCount > rhs->mRefCount; return lhs->mTypeInstance->mTypeId < rhs->mTypeInstance->mTypeId; }); bool failed = false; - SmallVector isSlotUsed; + SmallVector isSlotUsed; for (auto slotEntry : sortedIfaceUseMap) { BfTypeInstance* iface = slotEntry->mTypeInstance; @@ -2865,7 +2862,7 @@ bool BfCompiler::SlowGenerateSlotNums() isSlotUsed.clear(); if (mMaxInterfaceSlots > 0) - isSlotUsed.resize(mMaxInterfaceSlots); + isSlotUsed.resize(mMaxInterfaceSlots); BF_ASSERT(iface->mSlotNum == -1); @@ -2941,8 +2938,8 @@ bool BfCompiler::SlowGenerateSlotNums() void BfCompiler::GenerateSlotNums() { - BP_ZONE("BfCompiler::GenerateSlotNums"); - + BP_ZONE("BfCompiler::GenerateSlotNums"); + if (mMaxInterfaceSlots < 0) { if (mOptions.mIncrementalBuild) @@ -2952,16 +2949,16 @@ void BfCompiler::GenerateSlotNums() } bool isHotCompile = IsHotCompile(); - + for (auto type : mContext->mResolvedTypes) - { + { if (!type->IsInterface()) continue; auto typeInstance = type->ToTypeInstance(); if ((typeInstance->mSlotNum <= 0) || (!isHotCompile)) { - if ((mContext->mReferencedIFaceSlots.Contains(typeInstance)) || + if ((mContext->mReferencedIFaceSlots.Contains(typeInstance)) || (typeInstance->mHasBeenInstantiated) || (typeInstance->IncludeAllMethods())) { if (typeInstance->mSlotNum == -2) @@ -2972,11 +2969,11 @@ void BfCompiler::GenerateSlotNums() } } - if (VerifySlotNums()) + if (VerifySlotNums()) return; - + if (!QuickGenerateSlotNums()) - SlowGenerateSlotNums(); + SlowGenerateSlotNums(); BfLogSysM("GenerateSlotNums mMaxInterfaceSlots: %d\n", mMaxInterfaceSlots); } @@ -2992,17 +2989,17 @@ void BfCompiler::GenerateDynCastData() nextSiblingIds.Resize(mCurTypeId); for (auto type : mContext->mResolvedTypes) - { + { if (type->IsBoxed()) continue; auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) continue; - + if (typeInst->mBaseType == NULL) continue; - + int baseId = typeInst->mBaseType->mTypeId; int firstDerivedId = firstDerivedIds[baseId]; @@ -3045,8 +3042,8 @@ void BfCompiler::GenerateDynCastData() void BfCompiler::UpdateRevisedTypes() { BfLogSysM("BfCompiler::UpdateRevisedTypes\n"); - BP_ZONE("BfCompiler::UpdateRevisedTypes"); - + BP_ZONE("BfCompiler::UpdateRevisedTypes"); + // See if we have any name conflicts and remove those auto typeDefItr = mSystem->mTypeDefs.begin(); while (typeDefItr != mSystem->mTypeDefs.end()) @@ -3059,7 +3056,7 @@ void BfCompiler::UpdateRevisedTypes() { ++typeDefItr; continue; - } + } typeDef->mDupDetectedRevision = -1; if ((typeDef->mIsCombinedPartial) || (typeDef->mDefState == BfTypeDef::DefState_Deleted) || (typeDef->mTypeCode == BfTypeCode_Extension)) @@ -3070,16 +3067,16 @@ void BfCompiler::UpdateRevisedTypes() if ((!typeDef->IsGlobalsContainer()) && (mSystem->ContainsNamespace(typeDef->mFullName, typeDef->mProject))) { - mPassInstance->Fail(StrFormat("The name '%s' is already defined to be a namespace name", typeDef->mFullName.ToString().c_str()), typeDef->mTypeDeclaration->mNameNode); + mPassInstance->Fail(StrFormat("The name '%s' is already defined to be a namespace name", typeDef->mFullName.ToString().c_str()), typeDef->mTypeDeclaration->mNameNode); } - + bool removedElement = false; auto nextTypeDefItr = typeDefItr; nextTypeDefItr.MoveToNextHashMatch(); while (nextTypeDefItr) { - auto nextTypeDef = *nextTypeDefItr; + auto nextTypeDef = *nextTypeDefItr; if (nextTypeDef->mNextRevision != NULL) nextTypeDef = nextTypeDef->mNextRevision; if ((nextTypeDef->mIsCombinedPartial) || (nextTypeDef->mDefState == BfTypeDef::DefState_Deleted) || (nextTypeDef->mTypeCode == BfTypeCode_Extension) || @@ -3087,9 +3084,9 @@ void BfCompiler::UpdateRevisedTypes() { nextTypeDefItr.MoveToNextHashMatch(); continue; - } + } - if ((typeDef->mIsPartial) && (nextTypeDef->mIsPartial) && + if ((typeDef->mIsPartial) && (nextTypeDef->mIsPartial) && (!typeDef->IsGlobalsContainer()) && (typeDef->mProject != nextTypeDef->mProject)) { @@ -3110,15 +3107,15 @@ void BfCompiler::UpdateRevisedTypes() if (typeA != NULL) { - error = mPassInstance->Fail(StrFormat("Partial type in project '%s' cannot extend a type from a referenced project", typeA->mProject->mName.c_str()).c_str(), + error = mPassInstance->Fail(StrFormat("Partial type in project '%s' cannot extend a type from a referenced project", typeA->mProject->mName.c_str()).c_str(), typeA->mTypeDeclaration->mNameNode); - mPassInstance->MoreInfo(StrFormat("Previous definition in project '%s'", typeB->mProject->mName.c_str()), + mPassInstance->MoreInfo(StrFormat("Previous definition in project '%s'", typeB->mProject->mName.c_str()), typeB->mTypeDeclaration->mNameNode); } if (error != NULL) error->mIsPersistent = true; } - + if (((!typeDef->mIsPartial) || (!nextTypeDef->mIsPartial)) && (!typeDef->IsGlobalsContainer()) && (!nextTypeDef->IsGlobalsContainer()) && (typeDef->mProject->ReferencesOrReferencedBy(nextTypeDef->mProject))) @@ -3127,17 +3124,17 @@ void BfCompiler::UpdateRevisedTypes() BfError* error = NULL; /*if ((typeDef->mIsPartial) && (typeDef->mTypeCode != BfTypeCode_Extension)) - { + { error = mPassInstance->Fail("Missing 'partial' modifier; another partial definition of this type exists", nextTypeDef->mTypeDeclaration->mNameNode); mPassInstance->MoreInfo("Previous definition", typeDef->mTypeDeclaration->mNameNode); } else if ((nextTypeDef->mIsPartial) && (nextTypeDef->mTypeCode != BfTypeCode_Extension)) - { + { error = mPassInstance->Fail("Missing 'partial' modifier; another partial definition of this type exists", typeDef->mTypeDeclaration->mNameNode); - mPassInstance->MoreInfo("Previous definition", nextTypeDef->mTypeDeclaration->mNameNode); + mPassInstance->MoreInfo("Previous definition", nextTypeDef->mTypeDeclaration->mNameNode); } else */if (nextTypeDef->mOuterType != NULL) - { + { error = mPassInstance->Fail(StrFormat("The type '%s.%s' already has a definition for '%s'", nextTypeDef->mOuterType->mNamespace.ToString().c_str(), nextTypeDef->mOuterType->mName->mString.mPtr, nextTypeDef->mName->mString.mPtr), nextTypeDef->mTypeDeclaration->mNameNode); mPassInstance->MoreInfo("Previous definition", typeDef->mTypeDeclaration->mNameNode); @@ -3149,35 +3146,35 @@ void BfCompiler::UpdateRevisedTypes() mPassInstance->MoreInfo("Previous definition", typeDef->mTypeDeclaration->mNameNode); } else - { - error = mPassInstance->Fail(StrFormat("The global namespace already has a definition for '%s'", + { + error = mPassInstance->Fail(StrFormat("The global namespace already has a definition for '%s'", nextTypeDef->mName->mString.mPtr), nextTypeDef->mTypeDeclaration->mNameNode); mPassInstance->MoreInfo("Previous definition", typeDef->mTypeDeclaration->mNameNode); } if (error != NULL) error->mIsPersistent = true; } - + nextTypeDefItr.MoveToNextHashMatch(); } ++typeDefItr; } - - mContext->PreUpdateRevisedTypes(); + + mContext->PreUpdateRevisedTypes(); // If we missed out on required types previously, now we should be 'okay' mInInvalidState = false; // We can't do any yields in here - the compiler state is invalid from the time we inject a new - // typedef revision up until we finish the associated RebuildType + // typedef revision up until we finish the associated RebuildType int compositeBucket = 0; - + // These are "extension" defs that were unmatched last run through Array prevSoloExtensions; mSystem->mTypeDefs.CheckRehash(); - + Array corlibProjects; // { @@ -3199,11 +3196,11 @@ void BfCompiler::UpdateRevisedTypes() { bool hadPartials = false; bool hadChanges = false; - + if (mSystem->mTypeDefs.mHashHeads == NULL) break; - // Partials combiner + // Partials combiner auto outerTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; while (outerTypeDefEntryIdx != -1) { @@ -3221,20 +3218,20 @@ void BfCompiler::UpdateRevisedTypes() } if (outerTypeDef->mNextRevision != NULL) - hadChanges = true; + hadChanges = true; BfTypeDefMap::Entry* rootTypeDefEntry = NULL; BfTypeDef* rootTypeDef = NULL; BfTypeDef* compositeTypeDef = NULL; BfProject* compositeProject = NULL; - + auto latestOuterTypeDef = outerTypeDef->GetLatest(); if ((outerTypeDef->mTypeCode == BfTypeCode_Extension) && (!outerTypeDef->mIsPartial)) { prevSoloExtensions.Add(outerTypeDef); outerTypeDef->mIsPartial = true; } - + if ((outerTypeDef->mIsPartial) || (outerTypeDef->mIsCombinedPartial)) { // Initialize mPartialUsed flags @@ -3242,7 +3239,7 @@ void BfCompiler::UpdateRevisedTypes() { auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; while (checkTypeDefEntryIdx != -1) - { + { // This clears the mPartialUsed flag for the whole bucket auto checkTypeDef = mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx].mValue; if ((checkTypeDef->mIsPartial) || (checkTypeDef->mIsCombinedPartial)) @@ -3256,11 +3253,11 @@ void BfCompiler::UpdateRevisedTypes() bool isExplicitPartial = outerTypeDef->mIsExplicitPartial; bool failedToFindRootType = false; if ((outerTypeDef->mTypeCode == BfTypeCode_Extension) && (!outerTypeDef->mPartialUsed)) - { + { // Find root type, and we assume the composite type follows this auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; while (checkTypeDefEntryIdx != -1) - { + { auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; auto checkTypeDef = checkTypeDefEntry->mValue; if ((checkTypeDefEntry->mHashCode != outerTypeDefEntry->mHashCode) || @@ -3277,16 +3274,16 @@ void BfCompiler::UpdateRevisedTypes() } // Only allow extending structs, objects, and interfaces - if ((checkTypeDef->mTypeCode == BfTypeCode_Struct) || + if ((checkTypeDef->mTypeCode == BfTypeCode_Struct) || (checkTypeDef->mTypeCode == BfTypeCode_Object) || (checkTypeDef->mTypeCode == BfTypeCode_Enum) || (checkTypeDef->mTypeCode == BfTypeCode_Interface)) - { + { rootTypeDef = checkTypeDef; rootTypeDefEntry = checkTypeDefEntry; compositeProject = rootTypeDef->mProject; } - + checkTypeDefEntryIdx = checkTypeDefEntry->mNext; if (compositeTypeDef != NULL) @@ -3297,26 +3294,26 @@ void BfCompiler::UpdateRevisedTypes() if (rootTypeDef == NULL) { - failedToFindRootType = true; + failedToFindRootType = true; isExplicitPartial = true; } } - + if ((isExplicitPartial) && (!outerTypeDef->mPartialUsed)) { // For explicit partials there is no 'root type' so we want to select any partial in the 'innermost' project - rootTypeDef = outerTypeDef; + rootTypeDef = outerTypeDef; rootTypeDefEntry = outerTypeDefEntry; compositeProject = rootTypeDef->mProject; - + // Find composite type, there is no explicit position for this auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; while (checkTypeDefEntryIdx != -1) - { + { auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; auto checkTypeDef = checkTypeDefEntry->mValue; - if ((checkTypeDefEntry->mHashCode != outerTypeDefEntry->mHashCode) || + if ((checkTypeDefEntry->mHashCode != outerTypeDefEntry->mHashCode) || (checkTypeDef->mPartialUsed) || (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted) || (!checkTypeDef->NameEquals(outerTypeDef)) || @@ -3342,7 +3339,7 @@ void BfCompiler::UpdateRevisedTypes() compositeProject = rootTypeDef->mProject; } else - { + { // Try 'corlib' for (auto corlibProject : corlibProjects) { @@ -3410,10 +3407,10 @@ void BfCompiler::UpdateRevisedTypes() compositeTypeDef->mNameEx->Ref(); compositeTypeDef->mProtection = rootTypeDef->mProtection; compositeTypeDef->mNamespace = rootTypeDef->mNamespace; - if (rootTypeDef->mTypeCode == BfTypeCode_Extension) - compositeTypeDef->mTypeCode = BfTypeCode_Struct; + if (rootTypeDef->mTypeCode == BfTypeCode_Extension) + compositeTypeDef->mTypeCode = BfTypeCode_Struct; else - compositeTypeDef->mTypeCode = rootTypeDef->mTypeCode; + compositeTypeDef->mTypeCode = rootTypeDef->mTypeCode; compositeTypeDef->mFullName = rootTypeDef->mFullName; compositeTypeDef->mFullNameEx = rootTypeDef->mFullNameEx; compositeTypeDef->mIsFunction = rootTypeDef->mIsFunction; @@ -3445,8 +3442,8 @@ void BfCompiler::UpdateRevisedTypes() if (compositeTypeDef->mNextRevision != NULL) { // This is an old 'next revision' - mSystem->InjectNewRevision(compositeTypeDef); - BF_ASSERT(compositeTypeDef->mNextRevision == NULL); + mSystem->InjectNewRevision(compositeTypeDef); + BF_ASSERT(compositeTypeDef->mNextRevision == NULL); } } } @@ -3462,11 +3459,11 @@ void BfCompiler::UpdateRevisedTypes() } } } - + // Collect the partials BfSizedVector typeParts; typeParts.push_back(rootTypeDef); - auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; + auto checkTypeDefEntryIdx = mSystem->mTypeDefs.mHashHeads[bucketIdx]; while (checkTypeDefEntryIdx != -1) { auto checkTypeDefEntry = &mSystem->mTypeDefs.mEntries[checkTypeDefEntryIdx]; @@ -3487,7 +3484,7 @@ void BfCompiler::UpdateRevisedTypes() continue; } } - + if (checkTypeDef->mTypeCode == BfTypeCode_Extension) { // This was an extension that was orphaned but now we're taking it back @@ -3496,13 +3493,13 @@ void BfCompiler::UpdateRevisedTypes() compositeTypeDef->mPartialUsed = true; checkTypeDef->mPartialUsed = true; - + if (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted) { - partialsHadChanges = true; + partialsHadChanges = true; hadSignatureChange = true; - } - else + } + else { if (checkTypeDef != rootTypeDef) typeParts.push_back(checkTypeDef); @@ -3521,7 +3518,7 @@ void BfCompiler::UpdateRevisedTypes() } // Set this down here, because the InjectNewRevision will clear this flag rootTypeDef->mIsPartial = true; - + if (partialsHadChanges) { BF_ASSERT(compositeTypeDef->mNextRevision == NULL); @@ -3575,7 +3572,7 @@ void BfCompiler::UpdateRevisedTypes() } } - // We use the root typedef's namespace search for the composite, but this should only be + // We use the root typedef's namespace search for the composite, but this should only be // used for cases where we CANNOT specify a typeref on an extension. IE: custom attributes // for a type can only be added on the root typedef. If this changes then we need to make // sure that we attach a definingType to attributes @@ -3588,7 +3585,7 @@ void BfCompiler::UpdateRevisedTypes() if (rootTypeDef != NULL) compositeTypeDef->mNamespaceSearch = rootTypeDef->mNamespaceSearch; else - compositeTypeDef->mNamespaceSearch.Clear(); + compositeTypeDef->mNamespaceSearch.Clear(); //BfLogSysM("Composite type %p updating. isNew: %d\n", compositeTypeDef, compositeIsNew); @@ -3624,13 +3621,13 @@ void BfCompiler::UpdateRevisedTypes() compositeTypeDef->mTypeCode = BfTypeCode_Object; }*/ - auto latestCompositeTypeDef = compositeTypeDef->GetLatest(); + auto latestCompositeTypeDef = compositeTypeDef->GetLatest(); if (latestCompositeTypeDef->mTypeCode == BfTypeCode_Extension) { BF_ASSERT(rootTypeDef == NULL); latestCompositeTypeDef->mTypeCode = BfTypeCode_Struct; } - + BfLogSysM("Partial combined type typedef %p updated from parser %p\n", compositeTypeDef, latestCompositeTypeDef->mTypeDeclaration->GetSourceData()); } @@ -3648,13 +3645,13 @@ void BfCompiler::UpdateRevisedTypes() } } } - } + } outerTypeDefEntryIdx = outerTypeDefEntry->mNext; } // Handle unused partials, apply any new revisions, process pending deletes - + if ((hadPartials) || (hadChanges)) { BfTypeDef* checkMasterTypeDef = NULL; @@ -3716,7 +3713,7 @@ void BfCompiler::UpdateRevisedTypes() outerTypeDef->mDefState = BfTypeDef::DefState_New; } } - } + } } outerTypeDefEntryIdx = nextTypeDefEntryIdx; @@ -3728,27 +3725,27 @@ void BfCompiler::UpdateRevisedTypes() { // If this got added to a composite partial then delete the previous solo type if (typeDef->mIsPartial) - { + { BfLogSysM("Solo partial going back to normal partial %p\n", typeDef); typeDef->mIsPartial = false; auto type = mContext->mScratchModule->ResolveTypeDef(typeDef, BfPopulateType_Identity); mContext->DeleteType(type); - typeDef->mIsPartial = true; + typeDef->mIsPartial = true; } } - + mContext->UpdateRevisedTypes(); - mContext->VerifyTypeLookups(); - + mContext->VerifyTypeLookups(); + mContext->ValidateDependencies(); if (mStats.mTypesDeleted != 0) { mContext->UpdateAfterDeletingTypes(); mContext->ValidateDependencies(); } - mContext->RemoveInvalidWorkItems(); - + mContext->RemoveInvalidWorkItems(); + mSystem->mNeedsTypesHandledByCompiler = false; //TODO: @@ -3785,7 +3782,7 @@ void BfCompiler::VisitAutocompleteExteriorIdentifiers() BF_ASSERT(mContext->mScratchModule->mCurTypeInstance == NULL); SetAndRestoreValue prevCurTypeInstance(mContext->mScratchModule->mCurTypeInstance, NULL); - SetAndRestoreValue prevIgnoreErrors(mContext->mScratchModule->mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreErrors(mContext->mScratchModule->mIgnoreErrors, true); mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, NULL); if (mResolvePassData->mAutoComplete != NULL) mResolvePassData->mAutoComplete->CheckTypeRef(usingDirective->mTypeRef, false, isUsingDirective); @@ -3800,7 +3797,7 @@ void BfCompiler::VisitAutocompleteExteriorIdentifiers() if (mResolvePassData->mAutoComplete != NULL) mResolvePassData->mAutoComplete->CheckIdentifier(checkIdentifier, false, isUsingDirective); - + if (auto sourceClassifier = mResolvePassData->GetSourceClassifier(checkIdentifier)) { if (isUsingDirective) @@ -3845,7 +3842,7 @@ void BfCompiler::VisitSourceExteriorNodes() if (!_AddName(qualifedTypeRef->mRight, wantErrors)) return false; return true; - } + } else if ((node->IsA()) || (node->IsA())) { srcNodes.Add(node); @@ -3891,7 +3888,7 @@ void BfCompiler::VisitSourceExteriorNodes() prevNamespace.mParts = &namespaceParts[0]; prevNamespace.mSize = i; if (wantErrors) - { + { if (i == 0) mPassInstance->Fail(StrFormat("The namespace '%s' does not exist", namespaceParts[i]->mString.ToString().c_str()), srcNodes[i]); else @@ -3908,7 +3905,7 @@ void BfCompiler::VisitSourceExteriorNodes() while (parser->mNextRevision != NULL) parser = parser->mNextRevision; if (parser->mAwaitingDelete) - return; + return; if (parser->mParserData == NULL) return; @@ -3917,7 +3914,7 @@ void BfCompiler::VisitSourceExteriorNodes() bool failed = false; for (auto& node : parser->mParserData->mExteriorNodes) - { + { SetAndRestoreValue*> prevCurNamespaceNodes(mContext->mCurNamespaceNodes, &node.mNamespaceNodes); auto exteriorAstNode = node.mNode; @@ -3926,7 +3923,7 @@ void BfCompiler::VisitSourceExteriorNodes() { srcNodes.Clear(); namespaceParts.Clear(); - bool success = _AddName(usingDirective->mNamespace, true); + bool success = _AddName(usingDirective->mNamespace, true); _CheckNamespace(parser, true, failed); } else if (auto usingDirective = BfNodeDynCast(exteriorAstNode)) @@ -3972,7 +3969,7 @@ void BfCompiler::VisitSourceExteriorNodes() for (auto parser : mResolvePassData->mParsers) _CheckParser(parser); } - else + else { for (auto parser : mSystem->mParsers) { @@ -3983,18 +3980,18 @@ void BfCompiler::VisitSourceExteriorNodes() void BfCompiler::ProcessAutocompleteTempType() { - BP_ZONE_F("BfCompiler::ProcessAutocompleteTempType %d", mResolvePassData->mResolveType); + BP_ZONE_F("BfCompiler::ProcessAutocompleteTempType %d", mResolvePassData->mResolveType); String& autoCompleteResultString = *gTLStrReturn.Get(); autoCompleteResultString.clear(); - + if (mContext->mBfObjectType == NULL) return; // Not initialized yet auto module = mContext->mScratchModule; auto autoComplete = mResolvePassData->mAutoComplete; BfLogSysM("ProcessAutocompleteTempType %d\n", autoComplete->mResolveType); - + SetAndRestoreValue prevCanceling(mCanceling, false); BF_ASSERT(mResolvePassData->mAutoComplete->mDefMethod == NULL); @@ -4021,7 +4018,7 @@ void BfCompiler::ProcessAutocompleteTempType() } for (auto tempTypeDef : mResolvePassData->mAutoCompleteTempTypes) - { + { String typeName = tempTypeDef->ToString(); BfLogSysM("BfResolveType_GetNavigationData TypeDef:%p %s\n", tempTypeDef, typeName.c_str()); @@ -4051,7 +4048,7 @@ void BfCompiler::ProcessAutocompleteTempType() String methodText; for (auto methodDef : tempTypeDef->mMethods) - { + { if (((methodDef->mMethodType == BfMethodType_Normal) || (methodDef->mMethodType == BfMethodType_Operator) || (methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mMethodType == BfMethodType_Mixin) || (methodDef->mMethodType == BfMethodType_Extension)) && @@ -4059,7 +4056,7 @@ void BfCompiler::ProcessAutocompleteTempType() { methodText = methodDef->ToString(); if (typeName != "@") - methodText = typeName + "." + methodText; + methodText = typeName + "." + methodText; if (!autoCompleteResultString.empty()) autoCompleteResultString += "\n"; @@ -4093,7 +4090,7 @@ void BfCompiler::ProcessAutocompleteTempType() if (!autoCompleteResultString.empty()) autoCompleteResultString += "\n"; - BfAstNode* refNode = propDeclaration->mNameNode; + BfAstNode* refNode = propDeclaration->mNameNode; module->UpdateSrcPos(refNode, (BfSrcPosFlags)(BfSrcPosFlag_NoSetDebugLoc | BfSrcPosFlag_Force)); propText += StrFormat("\tproperty\t%d\t%d", module->mCurFilePosition.mCurLine, module->mCurFilePosition.mCurColumn); @@ -4118,7 +4115,7 @@ void BfCompiler::ProcessAutocompleteTempType() autoCompleteResultString = typeName; for (auto methodDef : tempTypeDef->mMethods) - { + { BfAstNode* defNode = methodDef->mMethodDeclaration; if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) defNode = propertyDeclaration; @@ -4130,7 +4127,7 @@ void BfCompiler::ProcessAutocompleteTempType() if ((parser == NULL) || (parser->mCursorIdx == -1)) continue; - if ((defNode != NULL) && + if ((defNode != NULL) && (defNode->Contains(parser->mCursorIdx))) { String methodText = methodDef->ToString(); @@ -4140,7 +4137,7 @@ void BfCompiler::ProcessAutocompleteTempType() autoCompleteResultString = methodText; break; } - } + } } if (mResolvePassData->mAutoCompleteTempTypes.IsEmpty()) @@ -4160,17 +4157,17 @@ void BfCompiler::ProcessAutocompleteTempType() if (mResolvePassData->mParsers.IsEmpty()) break; - + autoCompleteResultString = mContext->mScratchModule->TypeToString(typeInst); for (auto methodDef : typeInst->mTypeDef->mMethods) - { + { BfAstNode* defNode = methodDef->mMethodDeclaration; if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) defNode = propertyDeclaration; if (defNode == NULL) - continue; + continue; if ((defNode != NULL) && (defNode->Contains(kv.mValue.mCursorIdx))) @@ -4181,9 +4178,9 @@ void BfCompiler::ProcessAutocompleteTempType() if (!defParser->mIsEmitted) continue; - + autoCompleteResultString += "."; - autoCompleteResultString += methodDef->ToString(); + autoCompleteResultString += methodDef->ToString(); break; } } @@ -4203,16 +4200,16 @@ void BfCompiler::ProcessAutocompleteTempType() // >>> VisitExteriorIdentifiers mResolvePassData->mAutoComplete->SetModule(module); - { - BP_ZONE("VisitExteriorIdentifiers"); + { + BP_ZONE("VisitExteriorIdentifiers"); VisitAutocompleteExteriorIdentifiers(); - } + } VisitSourceExteriorNodes(); if (autoComplete->mResolveType == BfResolveType_GetFixits) { BfAstNode* conflictStart = NULL; - BfAstNode* conflictSplit = NULL; + BfAstNode* conflictSplit = NULL; for (auto parser : mResolvePassData->mParsers) { @@ -4265,7 +4262,6 @@ void BfCompiler::ProcessAutocompleteTempType() } } } - } if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo) @@ -4276,7 +4272,7 @@ void BfCompiler::ProcessAutocompleteTempType() for (auto parser : mResolvePassData->mParsers) namespaceVisitor.Visit(parser->mRootNode); } - + auto _FindAcutalTypeDef = [&](BfTypeDef* tempTypeDef) { auto typeName = tempTypeDef->mFullName; @@ -4365,7 +4361,7 @@ void BfCompiler::ProcessAutocompleteTempType() GenerateAutocompleteInfo(); BfLogSysM("ProcessAutocompleteTempType - no tempTypeDef\n"); return; - } + } if (tempTypeDef->mProject->mDisabled) { @@ -4405,7 +4401,7 @@ void BfCompiler::ProcessAutocompleteTempType() if (mSystem->ParseAtomComposite(checkNamespaceStr, checkNamespace)) { if (mSystem->ContainsNamespace(checkNamespace, tempTypeDef->mProject)) - { + { internalAccessSet->mNamespaces.Add(checkNamespace); continue; } @@ -4424,10 +4420,10 @@ void BfCompiler::ProcessAutocompleteTempType() internalAccessSet->mTypes.Add(typeInst); } } - } + } if (tempTypeDef->mTypeCode == BfTypeCode_Extension) - { + { BfTypeInstance* outerTypeInstance = NULL; if (tempTypeDef->mOuterType != NULL) @@ -4446,25 +4442,25 @@ void BfCompiler::ProcessAutocompleteTempType() auto autoComplete = mResolvePassData->mAutoComplete; if (autoComplete->IsAutocompleteNode(tempTypeDef->mTypeDeclaration->mNameNode)) { - BfIdentifierNode* nameNode = tempTypeDef->mTypeDeclaration->mNameNode; + BfIdentifierNode* nameNode = tempTypeDef->mTypeDeclaration->mNameNode; autoComplete->AddTopLevelNamespaces(nameNode); autoComplete->AddTopLevelTypes(nameNode); autoComplete->mInsertStartIdx = nameNode->GetSrcStart(); - autoComplete->mInsertEndIdx = nameNode->GetSrcEnd(); + autoComplete->mInsertEndIdx = nameNode->GetSrcEnd(); } } - + // while (actualTypeDef == NULL) // { // checkT // } if ((actualTypeDef == NULL) || (actualTypeDef->mTypeDeclaration == NULL)) - { + { GenerateAutocompleteInfo(); return; } - + auto sourceClassifier = mResolvePassData->GetSourceClassifier(tempTypeDef->mTypeDeclaration); if (tempTypeDef->mTypeCode == BfTypeCode_Extension) sourceClassifier->SetElementType(tempTypeDef->mTypeDeclaration->mNameNode, actualTypeDef->mTypeCode); @@ -4473,7 +4469,7 @@ void BfCompiler::ProcessAutocompleteTempType() BfTypeInstance* typeInst; { - BP_ZONE("ProcessAutocompleteTempType.ResolveTypeDef"); + BP_ZONE("ProcessAutocompleteTempType.ResolveTypeDef"); typeInst = (BfTypeInstance*)module->ResolveTypeDef(actualTypeDef, BfPopulateType_IdentityNoRemapAlias); if ((typeInst != NULL) && (typeInst->IsIncomplete())) @@ -4481,8 +4477,8 @@ void BfCompiler::ProcessAutocompleteTempType() } if (typeInst == NULL) - { - return; + { + return; } BF_ASSERT((typeInst->mSize != -1) || (typeInst->IsTypeAlias())); @@ -4491,17 +4487,17 @@ void BfCompiler::ProcessAutocompleteTempType() if ((typeInst->mModule != NULL) && (!typeInst->mModule->mIsScratchModule)) mLastAutocompleteModule = typeInst->mModule; #endif - + SetAndRestoreValue prevType(module->mCurTypeInstance, typeInst); typeState.mType = typeInst; - + BfGenericExtensionEntry* genericExEntry = NULL; bool hadTempExtensionInfo = false; if ((tempTypeDef->IsExtension()) && (actualTypeDef->mIsCombinedPartial) && (typeInst->IsGenericTypeInstance())) { // Add to our extension info map and then take it out at the end... auto genericTypeInst = (BfTypeInstance*)typeInst; - module->BuildGenericExtensionInfo(genericTypeInst, tempTypeDef); + module->BuildGenericExtensionInfo(genericTypeInst, tempTypeDef); genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(tempTypeDef, &genericExEntry); BF_ASSERT(genericExEntry != NULL); hadTempExtensionInfo = true; @@ -4520,7 +4516,7 @@ void BfCompiler::ProcessAutocompleteTempType() autoComplete->AddTopLevelTypes(tempTypeDef->mTypeDeclaration->mNameNode); autoComplete->SetDefinitionLocation(actualTypeDef->mTypeDeclaration->mNameNode); } - else + else autoComplete->SetDefinitionLocation(nameNode); autoComplete->mDefType = actualTypeDef; autoComplete->mInsertStartIdx = nameNode->GetSrcStart(); @@ -4531,8 +4527,8 @@ void BfCompiler::ProcessAutocompleteTempType() autoComplete->mResultString = ":"; autoComplete->mResultString += module->TypeToString(typeInst, (BfTypeNameFlags)(BfTypeNameFlag_ExtendedInfo | BfTypeNameFlag_ResolveGenericParamNames)); } - } - } + } + } autoComplete->CheckInterfaceFixit(typeInst, tempTypeDef->mTypeDeclaration->mNameNode); if (tempTypeDef->mTypeCode == BfTypeCode_TypeAlias) @@ -4554,9 +4550,9 @@ void BfCompiler::ProcessAutocompleteTempType() auto customAttrs = module->GetCustomAttributes(tempTypeDef); delete customAttrs; } - + for (int genericParamIdx = 0; genericParamIdx < (int)tempTypeDef->mGenericParamDefs.size(); genericParamIdx++) - { + { auto genericParamDef = tempTypeDef->mGenericParamDefs[genericParamIdx]; auto genericParamInstance = new BfGenericTypeParamInstance(tempTypeDef, genericParamIdx); @@ -4564,16 +4560,16 @@ void BfCompiler::ProcessAutocompleteTempType() module->ResolveGenericParamConstraints(genericParamInstance, true); delete genericParamInstance; - for (auto nameNode : genericParamDef->mNameNodes) - module->HandleTypeGenericParamRef(nameNode, tempTypeDef, genericParamIdx); + for (auto nameNode : genericParamDef->mNameNodes) + module->HandleTypeGenericParamRef(nameNode, tempTypeDef, genericParamIdx); } //TODO: Do extern constraint stuff here for (auto fieldDef : tempTypeDef->mFields) { - BP_ZONE("ProcessAutocompleteTempType.CheckField"); - + BP_ZONE("ProcessAutocompleteTempType.CheckField"); + if (BfNodeIsA(fieldDef->mFieldDeclaration)) continue; // Don't process auto-generated property fields @@ -4587,14 +4583,14 @@ void BfCompiler::ProcessAutocompleteTempType() module->ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity, flags); } mResolvePassData->mAutoComplete->CheckTypeRef(fieldDef->mTypeRef, true); - + actualTypeDef->PopulateMemberSets(); - BfFieldDef* actualFieldDef = NULL; + BfFieldDef* actualFieldDef = NULL; BfMemberSetEntry* memberSetEntry = NULL; if (actualTypeDef->mFieldSet.TryGetWith((StringImpl&)fieldDef->mName, &memberSetEntry)) { - auto checkFieldDef = (BfFieldDef*)memberSetEntry->mMemberDef; + auto checkFieldDef = (BfFieldDef*)memberSetEntry->mMemberDef; if ((checkFieldDef->mIsConst == fieldDef->mIsConst) && (checkFieldDef->mIsStatic == fieldDef->mIsStatic)) { @@ -4628,18 +4624,18 @@ void BfCompiler::ProcessAutocompleteTempType() } else if (autoComplete->mResolveType == BfResolveType_GetResultString) { - auto fieldInstance = &typeInst->mFieldInstances[actualFieldDef->mIdx]; + auto fieldInstance = &typeInst->mFieldInstances[actualFieldDef->mIdx]; if (fieldInstance->mConstIdx != -1) - { + { auto constant = typeInst->mConstHolder->GetConstantById(fieldInstance->mConstIdx); auto retVal = module->ConstantToCurrent(constant, typeInst->mConstHolder, fieldInstance->mResolvedType); BfTypedValue typedValue = BfTypedValue(retVal, fieldInstance->mResolvedType); - autoComplete->CheckResult(fieldDef->GetRefNode(), typedValue); + autoComplete->CheckResult(fieldDef->GetRefNode(), typedValue); } } break; } - } + } } BfFieldDeclaration* fieldDecl = fieldDef->GetFieldDeclaration(); @@ -4650,20 +4646,20 @@ void BfCompiler::ProcessAutocompleteTempType() } if (fieldDef->mIsConst) - { - module->ResolveConstField(typeInst, NULL, fieldDef); + { + module->ResolveConstField(typeInst, NULL, fieldDef); } - + if (fieldDef->GetInitializer() == NULL) { if (BfNodeIsA(fieldDef->mTypeRef)) - { + { if ((fieldDef->mTypeRef->IsA()) || (fieldDef->mTypeRef->IsA())) - mPassInstance->Fail("Implicitly-typed fields must be initialized", fieldDef->GetRefNode()); + mPassInstance->Fail("Implicitly-typed fields must be initialized", fieldDef->GetRefNode()); } } } - + auto checkTypeDef = tempTypeDef; while (checkTypeDef != NULL) { @@ -4674,9 +4670,9 @@ void BfCompiler::ProcessAutocompleteTempType() } checkTypeDef = checkTypeDef->mOuterType; } - + for (auto propDef : tempTypeDef->mProperties) - { + { auto fieldDecl = propDef->GetFieldDeclaration(); if ((fieldDecl != NULL) && (fieldDecl->mAttributes != NULL)) @@ -4687,16 +4683,22 @@ void BfCompiler::ProcessAutocompleteTempType() auto customAttrs = module->GetCustomAttributes(fieldDecl->mAttributes, target); delete customAttrs; } - + auto propDeclaration = BfNodeDynCast(fieldDecl); if (propDeclaration != NULL) autoComplete->CheckProperty(propDeclaration); - module->ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef); + + if (BfNodeIsA(propDef->mTypeRef)) + { + // This is only valid for ConstEval properties + } + else + module->ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef); if (auto indexerDeclaration = BfNodeDynCast(propDef->mFieldDeclaration)) { for (auto paramDecl : indexerDeclaration->mParams) - { + { module->ResolveTypeRef(paramDecl->mTypeRef, BfPopulateType_Identity); } } @@ -4724,11 +4726,11 @@ void BfCompiler::ProcessAutocompleteTempType() if (checkType != NULL) checkType = checkType->mBaseType; - } + } } } - - Array methodInstances; + + Array methodInstances; for (auto methodDef : tempTypeDef->mMethods) { @@ -4737,7 +4739,7 @@ void BfCompiler::ProcessAutocompleteTempType() autoComplete->CheckMethod(methodDeclaration, false); if (!methodDef->mWantsBody) - { + { if (methodDeclaration != NULL) { if (methodDeclaration->mAttributes != NULL) @@ -4749,16 +4751,16 @@ void BfCompiler::ProcessAutocompleteTempType() else if (auto methodPropertyDeclaration = methodDef->GetPropertyMethodDeclaration()) { if (methodPropertyDeclaration->mAttributes != NULL) - { + { auto customAttrs = module->GetCustomAttributes(methodPropertyDeclaration->mAttributes, BfAttributeTargets_Method); - delete customAttrs; - } + delete customAttrs; + } } - + continue; } - BP_ZONE("ProcessAutocompleteTempType.CheckMethod"); + BP_ZONE("ProcessAutocompleteTempType.CheckMethod"); BfMethodInstanceGroup methodInstanceGroup; methodInstanceGroup.mOwner = typeInst; methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; @@ -4771,13 +4773,13 @@ void BfCompiler::ProcessAutocompleteTempType() methodInstanceGroup.mDefault = methodInstance; defer(methodInstanceGroup.mDefault = NULL); - + for (int genericParamIdx = 0; genericParamIdx < (int)methodDef->mGenericParams.size(); genericParamIdx++) { auto genericParamType = module->GetGenericParamType(BfGenericParamKind_Method, genericParamIdx); methodInstance->GetMethodInfoEx()->mMethodGenericArguments.push_back(genericParamType); - auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx); + auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx); methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance); } @@ -4790,14 +4792,14 @@ void BfCompiler::ProcessAutocompleteTempType() bool wantsProcess = !actualTypeDef->mIsFunction; SetAndRestoreValue prevFilePos(module->mCurFilePosition); - SetAndRestoreValue prevMethodInst(module->mCurMethodInstance, methodInstance); + SetAndRestoreValue prevMethodInst(module->mCurMethodInstance, methodInstance); module->DoMethodDeclaration(methodDeclaration, true, wantsProcess); if (wantsProcess) { module->mIncompleteMethodCount++; module->ProcessMethod(methodInstance); } - + if (methodInstance->mIRFunction) { BfLogSysM("Autocomplete removing IRFunction %d\n", methodInstance->mIRFunction.mId); @@ -4805,10 +4807,10 @@ void BfCompiler::ProcessAutocompleteTempType() module->mBfIRBuilder->Func_SafeRename(methodInstance->mIRFunction); } } - - if ((mResolvePassData->mAutoComplete->mDefType != NULL) && (mResolvePassData->mAutoComplete->mDefType->GetDefinition() == actualTypeDef) && + + if ((mResolvePassData->mAutoComplete->mDefType != NULL) && (mResolvePassData->mAutoComplete->mDefType->GetDefinition() == actualTypeDef) && (mResolvePassData->mAutoComplete->mDefMethod != NULL)) - { + { BfMethodDef* tempDefMethod = NULL; for (auto checkMethod : tempTypeDef->mMethods) { @@ -4850,7 +4852,7 @@ void BfCompiler::ProcessAutocompleteTempType() for (auto checkNode : mResolvePassData->mExteriorAutocompleteCheckNodes) { - BP_ZONE("ProcessAutocompleteTempType.CheckIdentifier"); + BP_ZONE("ProcessAutocompleteTempType.CheckIdentifier"); bool isUsingDirective = false; BfIdentifierNode* checkIdentifier = NULL; @@ -4862,26 +4864,26 @@ void BfCompiler::ProcessAutocompleteTempType() else checkIdentifier = BfNodeDynCast(checkNode); mResolvePassData->mAutoComplete->CheckIdentifier(checkIdentifier, false, isUsingDirective); - } + } GenerateAutocompleteInfo(); for (auto methodInstance : methodInstances) delete methodInstance; - methodInstances.Clear(); - - module->CleanupFileInstances(); + methodInstances.Clear(); - prevTypeInstance.Restore(); + module->CleanupFileInstances(); + + prevTypeInstance.Restore(); if (module->mCurTypeInstance == NULL) module->ClearConstData(); - + BfLogSysM("ProcessAutocompleteTempType end\n"); } BfType* BfCompiler::CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef) { - //auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration, + //auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration, //(BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue | BfResolveTypeRefFlag_AllowGenericTypeParamConstValue)); auto resolvedType = module->ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowRef); if ((resolvedType != NULL) && (resolvedType->IsTypeInstance())) @@ -4927,8 +4929,8 @@ void BfCompiler::AddDepsToRebuildTypeList(BfTypeInstance* replaceTypeInst, HashS if (depTypeInst == NULL) continue; - AddToRebuildTypeList(depTypeInst, rebuildTypeInstList); - } + AddToRebuildTypeList(depTypeInst, rebuildTypeInstList); + } } void BfCompiler::GetSymbolReferences() @@ -4941,11 +4943,11 @@ void BfCompiler::GetSymbolReferences() auto context = mContext; if (context->mBfObjectType == NULL) return; // Not initialized yet - auto module = context->mScratchModule; + auto module = context->mScratchModule; if (mResolvePassData->mAutoComplete != NULL) mResolvePassData->mAutoComplete->SetModule(module); - + BfTypeDef* typeDef = NULL; HashSet rebuildTypeInstList; if (!mResolvePassData->mQueuedSymbolReferenceNamespace.IsEmpty()) @@ -4957,10 +4959,10 @@ void BfCompiler::GetSymbolReferences() { auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) - continue; + continue; for (auto& lookupKV : typeInst->mLookupResults) - { + { auto typeDef = lookupKV.mValue.mTypeDef; if ((typeDef != NULL) && (typeDef->mNamespace.StartsWith(mResolvePassData->mSymbolReferenceNamespace))) { @@ -4989,7 +4991,7 @@ void BfCompiler::GetSymbolReferences() auto replaceType = module->ResolveTypeDef(typeDef, BfPopulateType_IdentityNoRemapAlias); module->PopulateType(replaceType); auto replaceTypeInst = replaceType->ToTypeInstance(); - + if (mResolvePassData->mGetSymbolReferenceKind != BfGetSymbolReferenceKind_Local) { AddDepsToRebuildTypeList(replaceTypeInst, rebuildTypeInstList); @@ -5022,11 +5024,11 @@ void BfCompiler::GetSymbolReferences() while (attrib != NULL) { if (attrib->mAttributeTypeRef != NULL) - { + { auto attrType = module->ResolveTypeRef(attrib->mAttributeTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_Attribute); BfTypeDef* attrTypeDef = NULL; if ((attrType != NULL) && (attrType->IsTypeInstance())) - attrTypeDef = attrType->ToTypeInstance()->mTypeDef; + attrTypeDef = attrType->ToTypeInstance()->mTypeDef; if (attrTypeDef != NULL) { mResolvePassData->HandleTypeReference(attrib->mAttributeTypeRef, attrTypeDef); @@ -5048,7 +5050,7 @@ void BfCompiler::GetSymbolReferences() } } } - } + } } attrib = attrib->mNextAttribute; @@ -5056,7 +5058,7 @@ void BfCompiler::GetSymbolReferences() }; for (auto rebuildTypeInst : rebuildTypeInstList) - { + { // These never have a definition. Also note that BfGenericDelegateType does not have proper generic defs if (rebuildTypeInst->IsOnDemand()) continue; @@ -5079,7 +5081,7 @@ void BfCompiler::GetSymbolReferences() for (auto parser : mResolvePassData->mParsers) { if (nameNode->IsFromParser(parser)) - { + { mResolvePassData->HandleTypeReference(nameNode, typeDef); break; } @@ -5094,7 +5096,7 @@ void BfCompiler::GetSymbolReferences() { BfTypeState typeState; typeState.mCurTypeDef = checkTypeDef; - SetAndRestoreValue prevTypeState(module->mContext->mCurTypeState, &typeState); + SetAndRestoreValue prevTypeState(module->mContext->mCurTypeState, &typeState); for (auto baseTypeRef : checkTypeDef->mBaseTypes) CheckSymbolReferenceTypeRef(module, baseTypeRef); @@ -5119,7 +5121,7 @@ void BfCompiler::GetSymbolReferences() } } else - { + { mResolvePassData->HandleTypeReference(typeDef->mTypeDeclaration->mNameNode, typeDef); } } @@ -5136,13 +5138,13 @@ void BfCompiler::GetSymbolReferences() { if ((typeDef->mTypeDeclaration != NULL) && (typeDef->mTypeDeclaration->mAttributes != NULL)) _CheckAttributes(typeDef->mTypeDeclaration->mAttributes, typeDef); - } + } if (auto typeAliasDeclaration = BfNodeDynCast(typeDef->mTypeDeclaration)) { CheckSymbolReferenceTypeRef(module, typeAliasDeclaration->mAliasToType); } - + if (mResolvePassData != NULL) { if (rebuildTypeInst->IsGenericTypeInstance()) @@ -5162,24 +5164,23 @@ void BfCompiler::GetSymbolReferences() } rebuildModule->ResolveGenericParamConstraints(&genericParamInstance, genericTypeInstance->IsGenericTypeInstance()); - } + } } } - if (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) { - for (auto baseTypeRef : typeDef->mBaseTypes) + for (auto baseTypeRef : typeDef->mBaseTypes) CheckSymbolReferenceTypeRef(module, baseTypeRef); } BfTypeState typeState; - SetAndRestoreValue prevTypeState(module->mContext->mCurTypeState, &typeState); + SetAndRestoreValue prevTypeState(module->mContext->mCurTypeState, &typeState); if (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) { for (auto propDef : typeDef->mProperties) - { + { BfPropertyDef* checkPropDef = propDef; BfTypeInstance* checkTypeInst = rebuildTypeInst; typeState.mCurTypeDef = propDef->mDeclaringType; @@ -5190,7 +5191,7 @@ void BfCompiler::GetSymbolReferences() } if (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) - { + { for (auto fieldDef : typeDef->mFields) { if (auto nameNode = fieldDef->GetNameNode()) @@ -5200,7 +5201,7 @@ void BfCompiler::GetSymbolReferences() } } } - + for (auto& fieldInst : rebuildTypeInst->mFieldInstances) { auto fieldDef = fieldInst.GetFieldDef(); @@ -5214,8 +5215,8 @@ void BfCompiler::GetSymbolReferences() { BfMethodState methodState; methodState.mTempKind = BfMethodState::TempKind_Static; - SetAndRestoreValue prevMethodState(module->mCurMethodState, &methodState); - BfConstResolver constResolver(module); + SetAndRestoreValue prevMethodState(module->mCurMethodState, &methodState); + BfConstResolver constResolver(module); constResolver.Resolve(fieldDef->GetInitializer()); } @@ -5232,8 +5233,8 @@ void BfCompiler::GetSymbolReferences() typeState.mCurTypeDef = propDef->mDeclaringType; if (propDef->mTypeRef != NULL) CheckSymbolReferenceTypeRef(module, propDef->mTypeRef); - } - + } + if (rebuildModule == NULL) continue; rebuildModule->EnsureIRBuilder(); @@ -5241,12 +5242,12 @@ void BfCompiler::GetSymbolReferences() for (auto& methodInstGroup : rebuildTypeInst->mMethodInstanceGroups) { - // Run through all methods + // Run through all methods bool isDefault = true; - + BfMethodInstanceGroup::MapType::iterator methodItr; if (methodInstGroup.mMethodSpecializationMap != NULL) - methodItr = methodInstGroup.mMethodSpecializationMap->begin(); + methodItr = methodInstGroup.mMethodSpecializationMap->begin(); while (true) { BfMethodInstance* rebuildMethodInstance; @@ -5270,23 +5271,23 @@ void BfCompiler::GetSymbolReferences() // rebuildMethodInstance = methodItr->mValue; // ++methodItr; } - + if ((rebuildMethodInstance->IsOrInUnspecializedVariation()) || (rebuildMethodInstance->IsSpecializedGenericMethod())) - continue; - + continue; + SetAndRestoreValue prevTypeInstance(rebuildModule->mCurMethodInstance, rebuildMethodInstance); auto methodDef = rebuildMethodInstance->mMethodDef; auto methodDeclaration = methodDef->GetMethodDeclaration(); typeState.mCurTypeDef = methodDef->mDeclaringType; - + if ((methodDeclaration != NULL) && (methodDeclaration->mAttributes != NULL)) - _CheckAttributes(methodDeclaration->mAttributes, methodDef->mDeclaringType); + _CheckAttributes(methodDeclaration->mAttributes, methodDef->mDeclaringType); if ((mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) || (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) || (mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_TypeGenericParam)) - { + { if (methodDef->mExplicitInterface != NULL) CheckSymbolReferenceTypeRef(rebuildModule, methodDef->mExplicitInterface); @@ -5305,7 +5306,7 @@ void BfCompiler::GetSymbolReferences() if (methodDeclaration != NULL) mResolvePassData->HandleMethodReference(methodDeclaration->mNameNode, typeDef, methodDef); - for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) { auto param = methodDef->mParams[paramIdx]; if (param->mParamDeclaration != NULL) @@ -5325,14 +5326,14 @@ void BfCompiler::GetSymbolReferences() } else { - for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) { - auto param = methodDef->mParams[paramIdx]; + auto param = methodDef->mParams[paramIdx]; if ((param->mParamDeclaration != NULL) && (param->mParamDeclaration->mInitializer != NULL)) { auto paramType = rebuildMethodInstance->GetParamType(paramIdx); - BfConstResolver constResolver(rebuildModule); + BfConstResolver constResolver(rebuildModule); constResolver.Resolve(param->mParamDeclaration->mInitializer, paramType); } } @@ -5340,7 +5341,7 @@ void BfCompiler::GetSymbolReferences() if (rebuildMethodInstance->mHasBeenProcessed) { if (rebuildMethodInstance->mIRFunction) - rebuildModule->mBfIRBuilder->Func_DeleteBody(rebuildMethodInstance->mIRFunction); + rebuildModule->mBfIRBuilder->Func_DeleteBody(rebuildMethodInstance->mIRFunction); rebuildMethodInstance->mHasBeenProcessed = false; rebuildModule->mIncompleteMethodCount++; } @@ -5351,7 +5352,7 @@ void BfCompiler::GetSymbolReferences() BF_FATAL("Shouldn't be processing this method"); } } - + for (int genericParamIdx = 0; genericParamIdx < (int)rebuildMethodInstance->GetNumGenericArguments(); genericParamIdx++) { BfGenericMethodParamInstance genericParamInstance(rebuildMethodInstance->mMethodDef, genericParamIdx); @@ -5374,7 +5375,7 @@ void BfCompiler::GetSymbolReferences() CheckSymbolReferenceTypeRef(module, externConstraintDef.mTypeRef); rebuildModule->ResolveGenericParamConstraints(&genericParamInstance, rebuildMethodInstance->mIsUnspecialized); } - + rebuildModule->ProcessMethod(rebuildMethodInstance); } } @@ -5388,7 +5389,7 @@ void BfCompiler::UpdateCompletion() return; float typeScale = 10.0f; - float methodScale = 1.0f; + float methodScale = 1.0f; float queueModuleScale = 50.0f; float genModuleScale = 50.0f; @@ -5398,9 +5399,9 @@ void BfCompiler::UpdateCompletion() BF_ASSERT(mStats.mModulesFinished <= mStats.mModulesStarted); BF_ASSERT(mCodeGen.mCompletionCount <= mStats.mModulesStarted); - float numerator = ((mStats.mQueuedTypesProcessed * typeScale) + //(mStats.mMethodsProcessed * methodScale) + + float numerator = ((mStats.mQueuedTypesProcessed * typeScale) + //(mStats.mMethodsProcessed * methodScale) + (mStats.mModulesFinished * queueModuleScale) + (mCodeGen.mCompletionCount * genModuleScale)); - float divisor = ((mStats.mTypesQueued * typeScale) + //(mStats.mMethodsQueued * methodScale) + + float divisor = ((mStats.mTypesQueued * typeScale) + //(mStats.mMethodsQueued * methodScale) + (mStats.mModulesStarted * queueModuleScale) + (mStats.mReifiedModuleCount * genModuleScale)); float checkPct = 0; if (divisor > 0) @@ -5421,8 +5422,8 @@ void BfCompiler::UpdateCompletion() void BfCompiler::MarkStringPool(BfModule* module) { for (int stringId : module->mStringPoolRefs) - { - BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; + { + BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId]; stringPoolEntry.mLastUsedRevision = mRevision; } @@ -5464,11 +5465,11 @@ void BfCompiler::MarkStringPool(BfIRConstHolder* constHolder, BfIRValue irValue) void BfCompiler::ClearUnusedStringPoolEntries() { BF_ASSERT(!IsHotCompile()); - + for (auto module : mContext->mModules) - { + { MarkStringPool(module); - } + } for (auto type : mContext->mResolvedTypes) { @@ -5493,14 +5494,14 @@ void BfCompiler::ClearUnusedStringPoolEntries() int strId = itr->mKey; BfStringPoolEntry& stringPoolEntry = itr->mValue; if (stringPoolEntry.mLastUsedRevision != mRevision) - { + { CompileLog("Clearing unused string: %d %s\n", itr->mKey, stringPoolEntry.mString.c_str()); mContext->mStringObjectPool.Remove(stringPoolEntry.mString); itr = mContext->mStringObjectIdMap.Remove(itr); } else ++itr; - } + } } void BfCompiler::ClearBuildCache() @@ -5514,7 +5515,7 @@ void BfCompiler::ClearBuildCache() } int BfCompiler::GetDynCastVDataCount() -{ +{ int dynElements = 1 + mMaxInterfaceSlots; return ((dynElements * 4) + mSystem->mPtrSize - 1) / mSystem->mPtrSize; } @@ -5531,7 +5532,7 @@ bool BfCompiler::IsDataResolvePass() bool BfCompiler::WantsClassifyNode(BfAstNode* node) { - return (mResolvePassData != NULL) && (mResolvePassData->GetSourceClassifier(node) != NULL); + return (mResolvePassData != NULL) && (mResolvePassData->GetSourceClassifier(node) != NULL); } BfAutoComplete* BfCompiler::GetAutoComplete() @@ -5561,10 +5562,10 @@ int BfCompiler::GetVTableMethodOffset() bool BfCompiler::DoWorkLoop(bool onlyReifiedTypes, bool onlyReifiedMethods) { bool hadAnyWork = false; - + while (true) { - bool didWork = false; + bool didWork = false; didWork |= mContext->ProcessWorkList(onlyReifiedTypes, onlyReifiedMethods); if (!didWork) break; @@ -5583,7 +5584,6 @@ BfMangler::MangleKind BfCompiler::GetMangleKind() ////////////////////////////////////////////////////////////////////////// - int ArrTest() { //SizedArray intArr; @@ -5596,12 +5596,12 @@ int ArrTest() intArr.push_back(123); intArr.pop_back(); intArr.push_back(234); - + intArr.push_back(345); //intArr.push_back(567); //auto itr = std::find(intArr.begin(), intArr.end(), 234); - //intArr.erase(itr); + //intArr.erase(itr); for (auto itr = intArr.begin(); itr != intArr.end(); ) { @@ -5632,7 +5632,7 @@ void BfCompiler::PopulateReified() while (true) { BP_ZONE("Compile_PopulateTypes"); - + int startTypeInitCount = mTypeInitCount; bool didWork = false; @@ -5668,7 +5668,7 @@ void BfCompiler::PopulateReified() } auto typeInst = type->ToTypeInstance(); - + if ((typeInst != NULL) && (typeInst->IsGenericTypeInstance()) && (!typeInst->IsUnspecializedType()) && (!typeInst->IsDelegateFromTypeRef()) && (!typeInst->IsFunctionFromTypeRef()) && (!typeInst->IsTuple())) { @@ -5746,7 +5746,7 @@ void BfCompiler::PopulateReified() { auto& checkMethodInstanceGroup = typeInst->mMethodInstanceGroups[checkMethodDef->mIdx]; auto checkMethodInstance = checkMethodInstanceGroup.mDefault; - if (checkMethodInstance != NULL) + if (checkMethodInstance != NULL) { if ((checkMethodDef->mIsExtern) && (checkMethodInstance->IsReifiedAndImplemented())) forceMethod = true; @@ -5805,8 +5805,9 @@ void BfCompiler::PopulateReified() if ((typeInst->HasBeenInstantiated()) && (!mCanceling)) { // If we have any virtual methods overrides that are unreified but the declaring virtual method is reified then we also need to reify - for (auto&& vEntry : typeInst->mVirtualMethodTable) + for (int virtIdx = 0; virtIdx < typeInst->mVirtualMethodTable.mSize; virtIdx++) { + auto& vEntry = typeInst->mVirtualMethodTable[virtIdx]; if ((vEntry.mDeclaringMethod.mTypeInstance == NULL) || (vEntry.mDeclaringMethod.mTypeInstance->IsIncomplete()) || (vEntry.mImplementingMethod.mTypeInstance == NULL) || @@ -5819,13 +5820,53 @@ void BfCompiler::PopulateReified() if ((declaringMethod->mIsReified) && (declaringMethod->mMethodInstanceGroup->IsImplemented())) { - BfMethodInstance* implMethod = vEntry.mImplementingMethod; - if ((implMethod != NULL) && ((!implMethod->mMethodInstanceGroup->IsImplemented()) || (!implMethod->mIsReified))) + if (vEntry.mImplementingMethod.mKind == BfMethodRefKind_AmbiguousRef) { - didWork = true; - if (!typeInst->mModule->mIsModuleMutable) - typeInst->mModule->StartExtension(); - typeInst->mModule->GetMethodInstance(implMethod); + auto checkTypeInst = typeInst; + + while (checkTypeInst != NULL) + { + BfMemberSetEntry* memberSetEntry; + if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(String(declaringMethod->mMethodDef->mName), &memberSetEntry)) + { + BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef; + while (methodDef != NULL) + { + if ((methodDef->mIsOverride) && (methodDef->mParams.mSize == declaringMethod->mMethodDef->mParams.mSize)) + { + auto implMethod = typeInst->mModule->GetRawMethodInstance(typeInst, methodDef); + if (typeInst->mModule->CompareMethodSignatures(declaringMethod, implMethod)) + { + if ((implMethod != NULL) && ((!implMethod->mMethodInstanceGroup->IsImplemented()) || (!implMethod->mIsReified))) + { + didWork = true; + if (!typeInst->mModule->mIsModuleMutable) + typeInst->mModule->StartExtension(); + typeInst->mModule->GetMethodInstance(implMethod); + } + } + } + + methodDef = methodDef->mNextWithSameName; + } + } + + if (checkTypeInst == declaringMethod->GetOwner()) + break; + + checkTypeInst = checkTypeInst->mBaseType; + } + } + else + { + BfMethodInstance* implMethod = vEntry.mImplementingMethod; + if ((implMethod != NULL) && ((!implMethod->mMethodInstanceGroup->IsImplemented()) || (!implMethod->mIsReified))) + { + didWork = true; + if (!typeInst->mModule->mIsModuleMutable) + typeInst->mModule->StartExtension(); + typeInst->mModule->GetMethodInstance(implMethod); + } } } } @@ -5856,7 +5897,7 @@ void BfCompiler::PopulateReified() if (typeInst->IsObject()) { - // If the implementor is an object then this can be dynamically dispatched + // If the implementor is an object then this can be dynamically dispatched } else { @@ -5899,7 +5940,7 @@ void BfCompiler::PopulateReified() if ((depMethod->mIsReified) && (depMethod->mMethodInstanceGroup->IsImplemented())) { auto methodDef = typeInst->mTypeDef->mMethods[reifyDep.mMethodIdx]; - typeInst->mModule->GetMethodInstance(typeInst, methodDef, BfTypeVector()); + typeInst->mModule->GetMethodInstance(typeInst, methodDef, BfTypeVector()); } } } @@ -5996,12 +6037,12 @@ void BfCompiler::HotCommit() mHotState->mCommittedHotCompileIdx = mOptions.mHotCompileIdx; for (auto type : mContext->mResolvedTypes) - { + { auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) continue; if (typeInst->mHotTypeData == NULL) - continue; + continue; for (int typeIdx = (int)typeInst->mHotTypeData->mTypeVersions.size() - 1; typeIdx >= 0; typeIdx--) { @@ -6015,9 +6056,9 @@ void BfCompiler::HotCommit() if ((hotVersionHead != hotVersion) && (hotVersionHead->mDataHash == hotVersion->mDataHash)) { // When we have a slot failure, the data hash will match but we actually do need to use the new mInterfaceMapping entries - // So we copy them over to the + // So we copy them over to the hotVersionHead->mInterfaceMapping = hotVersion->mInterfaceMapping; - } + } } } } @@ -6026,11 +6067,11 @@ void BfCompiler::HotCommit() void BfCompiler::HotResolve_Start(HotResolveFlags flags) { BfLogSysM("BfCompiler::HotResolve_Start\n"); - + delete mHotResolveData; mHotResolveData = new HotResolveData(); mHotResolveData->mFlags = flags; - + mHotResolveData->mHotTypeIdFlags.Resize(mCurTypeId); mHotResolveData->mReasons.Resize(mCurTypeId); @@ -6054,7 +6095,7 @@ bool BfCompiler::HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFl HotResolve_PopulateMethodNameMap(); String* namePtr = NULL; if (mHotData->mMethodNameMap.TryGetValue(hotMethod, &namePtr)) - { + { } #endif @@ -6064,7 +6105,7 @@ bool BfCompiler::HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFl hotMethod->mRefCount++; } else - { + { hotReachableData->mTypeFlags = (HotTypeFlags)(hotReachableData->mTypeFlags | flags); if ((!devirtualized) && (!hotReachableData->mHadNonDevirtualizedCall)) { @@ -6078,14 +6119,14 @@ bool BfCompiler::HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFl hotReachableData->mTypeFlags = (HotTypeFlags)(hotReachableData->mTypeFlags | flags); if (!devirtualized) hotReachableData->mHadNonDevirtualizedCall = true; - + for (auto hotDepData : hotMethod->mReferences) { if (hotDepData->mDataKind == BfHotDepDataKind_ThisType) { auto hotThisType = (BfHotThisType*)hotDepData; auto hotTypeVersion = hotThisType->mTypeVersion; - + HotTypeFlags hotTypeFlags = mHotResolveData->mHotTypeIdFlags[hotTypeVersion->mTypeId]; bool isAllocated = (hotTypeFlags & (HotTypeFlag_Heap | HotTypeFlag_CanAllocate)) != 0; if (!isAllocated) @@ -6109,11 +6150,11 @@ bool BfCompiler::HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFl auto hotAllocation = (BfHotAllocation*)hotDepData; auto hotTypeVersion = hotAllocation->mTypeVersion; HotResolve_ReportType(hotTypeVersion, flags, hotMethod); - HotResolve_ReportType(hotTypeVersion, HotTypeFlag_CanAllocate, hotMethod); + HotResolve_ReportType(hotTypeVersion, HotTypeFlag_CanAllocate, hotMethod); } else if (hotDepData->mDataKind == BfHotDepDataKind_TypeVersion) { - auto hotTypeVersion = (BfHotTypeVersion*)hotDepData; + auto hotTypeVersion = (BfHotTypeVersion*)hotDepData; HotResolve_ReportType(hotTypeVersion, flags, hotMethod); } else if (hotDepData->mDataKind == BfHotDepDataKind_Method) @@ -6125,7 +6166,7 @@ bool BfCompiler::HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFl { auto checkMethod = (BfHotDevirtualizedMethod*)hotDepData; HotResolve_AddReachableMethod(checkMethod->mMethod, flags, true); - } + } else if (hotDepData->mDataKind == BfHotDepDataKind_DupMethod) { auto checkMethod = (BfHotDupMethod*)hotDepData; @@ -6183,13 +6224,13 @@ void BfCompiler::HotResolve_AddActiveMethod(BfHotMethod* hotMethod) if ((hotMethod->mFlags & BfHotDepDataFlag_HasDup) != 0) { for (auto depData : hotMethod->mReferences) - { + { if (depData->mDataKind != BfHotDepDataKind_DupMethod) continue; auto hotDupMethod = (BfHotDupMethod*)depData; HotResolve_AddActiveMethod(hotDupMethod->mMethod); } - } + } } void BfCompiler::HotResolve_AddActiveMethod(const StringImpl& methodName) @@ -6198,7 +6239,7 @@ void BfCompiler::HotResolve_AddActiveMethod(const StringImpl& methodName) StringT<512> mangledName; int hotCompileIdx = 0; - + int tabIdx = (int)methodName.IndexOf('\t'); if (tabIdx != -1) { @@ -6207,8 +6248,8 @@ void BfCompiler::HotResolve_AddActiveMethod(const StringImpl& methodName) } else mangledName = methodName; - - bool isDelegateRef = false; + + bool isDelegateRef = false; BfHotMethod** hotMethodPtr; if (!mHotData->mMethodMap.TryGetValue(mangledName, &hotMethodPtr)) { @@ -6239,13 +6280,13 @@ void BfCompiler::HotResolve_AddDelegateMethod(const StringImpl& methodName) BfLogSysM("Hot method not found\n"); return; } - + BfHotMethod* hotMethod = *hotMethodPtr; HotResolve_AddReachableMethod(hotMethod, HotTypeFlag_Delegate, true); } void BfCompiler::HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotTypeFlags flags, BfHotDepData* reason) -{ +{ auto& flagsRef = mHotResolveData->mHotTypeFlags[hotTypeVersion]; if (flagsRef == (flagsRef | flags)) return; @@ -6253,7 +6294,7 @@ void BfCompiler::HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotType bool applyFlags = true; if ((flags & (BfCompiler::HotTypeFlag_ActiveFunction | BfCompiler::HotTypeFlag_Delegate | BfCompiler::HotTypeFlag_FuncPtr)) != 0) - { + { applyFlags = (hotTypeVersion->mCommittedHotCompileIdx != -1) && (mHotState->mPendingDataChanges.Contains(hotTypeVersion->mTypeId)); if ((!applyFlags) && (hotTypeVersion->mCommittedHotCompileIdx != -1)) @@ -6266,21 +6307,21 @@ void BfCompiler::HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotType } } if (applyFlags) - { + { auto& flagsIdRef = mHotResolveData->mHotTypeIdFlags[hotTypeVersion->mTypeId]; - flagsIdRef = (HotTypeFlags)(flags | flagsIdRef); + flagsIdRef = (HotTypeFlags)(flags | flagsIdRef); } - + BfLogSysM("HotResolve_ReportType %p %s Flags:%X DeclHotIdx:%d\n", hotTypeVersion, mContext->TypeIdToString(hotTypeVersion->mTypeId).c_str(), flags, hotTypeVersion->mDeclHotCompileIdx); - + for (auto member : hotTypeVersion->mMembers) { HotResolve_ReportType(member, flags, reason); - } + } } void BfCompiler::HotResolve_ReportType(int typeId, HotTypeFlags flags) -{ +{ if ((uint)typeId >= mHotResolveData->mHotTypeIdFlags.size()) { BF_DBG_FATAL("Invalid typeId"); @@ -6297,7 +6338,7 @@ void BfCompiler::HotResolve_ReportType(int typeId, HotTypeFlags flags) BF_ASSERT(hotTypeVersion != NULL); if (hotTypeVersion != NULL) HotResolve_ReportType(hotTypeVersion, flags, NULL); - } + } mHotResolveData->mHotTypeIdFlags[typeId] = (HotTypeFlags)(flags | mHotResolveData->mHotTypeIdFlags[typeId]); } @@ -6306,7 +6347,7 @@ void BfCompiler::HotResolve_PopulateMethodNameMap() { if (!mHotData->mMethodNameMap.IsEmpty()) return; - + for (auto& kv : mHotData->mMethodMap) { auto hotMethod = kv.mValue; @@ -6315,7 +6356,7 @@ void BfCompiler::HotResolve_PopulateMethodNameMap() mHotData->mMethodNameMap[hotMethod] = &kv.mKey; hotMethod = hotMethod->mPrevVersion; } - } + } } String BfCompiler::HotResolve_Finish() @@ -6338,7 +6379,7 @@ String BfCompiler::HotResolve_Finish() { BF_ASSERT(mHotState->mPendingDataChanges.IsEmpty() && mHotState->mPendingFailedSlottings.IsEmpty()); } - + if ((mHotResolveData->mFlags & HotResolveFlag_HadDataChanges) != 0) { auto _AddUsedType = [&](BfTypeDef* typeDef) @@ -6346,7 +6387,7 @@ String BfCompiler::HotResolve_Finish() auto type = mContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef); if (type != NULL) HotResolve_ReportType(type->mTypeId, BfCompiler::HotTypeFlag_Heap); - }; + }; // We have some types that can be allocated in a read-only section- pretend they are on the heap _AddUsedType(mReflectTypeInstanceTypeDef); @@ -6355,9 +6396,9 @@ String BfCompiler::HotResolve_Finish() // Find any virtual method overrides that may have been called. // These can cause new reachable virtual methods to be called, which may take more than one iteration to fully resolve for (int methodPass = 0; true; methodPass++) - { + { bool didWork = false; - + for (auto hotMethod : mHotResolveData->mDeferredThisCheckMethods) { if (HotResolve_AddReachableMethod(hotMethod, BfCompiler::HotTypeFlag_ActiveFunction, true, true)) @@ -6369,17 +6410,17 @@ String BfCompiler::HotResolve_Finish() { String& methodName = kv.mKey; auto hotMethod = kv.mValue; - + bool doCall = false; - bool forceAdd = false; - + bool forceAdd = false; + if (mHotResolveData->mReachableMethods.ContainsKey(hotMethod)) continue; for (auto ref : hotMethod->mReferences) { - if (ref->mDataKind == BfHotDepDataKind_ThisType) - continue; + if (ref->mDataKind == BfHotDepDataKind_ThisType) + continue; if (ref->mDataKind != BfHotDepDataKind_VirtualDecl) break; @@ -6391,7 +6432,7 @@ String BfCompiler::HotResolve_Finish() HotResolve_PopulateMethodNameMap(); String* namePtr = NULL; if (mHotData->mMethodNameMap.TryGetValue(hotVirtualDecl->mMethod, &namePtr)) - { + { } #endif @@ -6402,7 +6443,7 @@ String BfCompiler::HotResolve_Finish() } } } - + if (!doCall) { if ((hotMethod->mFlags & BfHotDepDataFlag_AlwaysCalled) != 0) @@ -6433,7 +6474,7 @@ String BfCompiler::HotResolve_Finish() Dictionary methodNameMap; - if ((flags > BfCompiler::HotTypeFlag_UserNotUsed) && + if ((flags > BfCompiler::HotTypeFlag_UserNotUsed) && ((mHotState->mPendingDataChanges.Contains(typeId)) || (mHotState->mPendingFailedSlottings.Contains(typeId)))) { bool isBadTypeUsed = false; @@ -6443,8 +6484,8 @@ String BfCompiler::HotResolve_Finish() { // If we detect an old version being used, it's only an issue if this type can actually be allocated if ((flags & HotTypeFlag_CanAllocate) != 0) - { - isBadTypeUsed = true; + { + isBadTypeUsed = true; } } @@ -6469,7 +6510,7 @@ String BfCompiler::HotResolve_Finish() errorCount++; if (errorCount >= 1000) - { + { result += "\n (more errors)..."; break; } @@ -6480,7 +6521,7 @@ String BfCompiler::HotResolve_Finish() result += mContext->TypeIdToString(typeId); result += "'"; if ((flags & BfCompiler::HotTypeFlag_Heap) != 0) - result += " allocated on the heap"; + result += " allocated on the heap"; else if ((flags & BfCompiler::HotTypeFlag_ActiveFunction) != 0) { if (reasonIsActiveMethod) @@ -6524,14 +6565,14 @@ String BfCompiler::HotResolve_Finish() typeInstance->mHotTypeData->mPendingDataChange = false; typeInstance->mHotTypeData->mHadDataChange = true; typeInstance->mHotTypeData->mVTableOrigLength = -1; - typeInstance->mHotTypeData->mOrigInterfaceMethodsLength = -1; + typeInstance->mHotTypeData->mOrigInterfaceMethodsLength = -1; BfLogSysM("Pending data change applied to type %p\n", typeInstance); } mHotState->mPendingDataChanges.Clear(); - mHotState->mPendingFailedSlottings.Clear(); - } + mHotState->mPendingFailedSlottings.Clear(); + } } ClearOldHotData(); @@ -6568,7 +6609,7 @@ String BfCompiler::HotResolve_Finish() delete mHotResolveData; mHotResolveData = NULL; - + return result; } @@ -6579,17 +6620,17 @@ void BfCompiler::ClearOldHotData() // TODO: Get rid of old hot data during hot compiles, too // if (IsHotCompile()) -// return; +// return; BP_ZONE("BfCompiler::ClearOldHotData"); - + bool isHotCompile = IsHotCompile(); auto itr = mHotData->mMethodMap.begin(); while (itr != mHotData->mMethodMap.end()) { String& methodName = itr->mKey; - auto hotMethod = itr->mValue; + auto hotMethod = itr->mValue; bool doDelete = false; @@ -6602,7 +6643,7 @@ void BfCompiler::ClearOldHotData() BF_ASSERT((mHotResolveData != NULL) && (mHotResolveData->mActiveMethods.Contains(prevMethod))); break; } - + hotMethod->mPrevVersion = prevMethod->mPrevVersion; prevMethod->mPrevVersion = NULL; prevMethod->Deref(); @@ -6610,7 +6651,7 @@ void BfCompiler::ClearOldHotData() BF_ASSERT(hotMethod->mRefCount >= 1); if (hotMethod->mPrevVersion == NULL) - { + { if (hotMethod->mRefCount <= 1) { doDelete = true; @@ -6623,8 +6664,8 @@ void BfCompiler::ClearOldHotData() bool doRemove = doDelete; if ((hotMethod->mFlags & BfHotDepDataFlag_HasDup) != 0) - { - bool hasDupMethod = false; + { + bool hasDupMethod = false; for (int idx = 0; idx < (int)hotMethod->mReferences.size(); idx++) { auto depData = hotMethod->mReferences[idx]; @@ -6633,13 +6674,13 @@ void BfCompiler::ClearOldHotData() auto dupMethod = (BfHotDupMethod*)depData; if (doDelete) { - doRemove = false; + doRemove = false; dupMethod->mMethod->mRefCount++; itr->mValue = dupMethod->mMethod; } else { - if ((dupMethod->mMethod->mRefCount == 1) || + if ((dupMethod->mMethod->mRefCount == 1) || ((!IsHotCompile()) && (dupMethod->mMethod->mFlags & BfHotDepDataFlag_IsBound) == 0)) { dupMethod->Deref(); @@ -6652,14 +6693,14 @@ void BfCompiler::ClearOldHotData() } if (doDelete) - { + { BfLogSysM("Deleting hot method %p %s\n", hotMethod, methodName.c_str()); //BF_ASSERT(hotMethod->mRefCount == 1); hotMethod->Clear(); - hotMethod->Deref(); + hotMethod->Deref(); if (doRemove) itr = mHotData->mMethodMap.Remove(itr); - } + } else ++itr; } @@ -6676,7 +6717,7 @@ void BfCompiler::ClearOldHotData() bool foundCommittedVersion = false; - auto latestVersionHead = typeInst->mHotTypeData->GetLatestVersionHead(); + auto latestVersionHead = typeInst->mHotTypeData->GetLatestVersionHead(); for (int typeIdx = (int)typeInst->mHotTypeData->mTypeVersions.size() - 1; typeIdx >= 0; typeIdx--) { auto hotVersion = typeInst->mHotTypeData->mTypeVersions[typeIdx]; @@ -6748,7 +6789,7 @@ void BfCompiler::CompileReified() deferTypeDefs.Add(typeDef); continue; } - + scratchModule->ResolveTypeDef(typeDef, BfPopulateType_Full); } @@ -6767,8 +6808,8 @@ void BfCompiler::CompileReified() mContext->mUnreifiedModule->PopulateType(typeInst, BfPopulateType_Interfaces_Direct); if (typeInst->mCustomAttributes == NULL) continue; - - bool alwaysInclude = false; + + bool alwaysInclude = false; for (auto& customAttribute : typeInst->mCustomAttributes->mAttributes) { if (customAttribute.mType->mAttributeData != NULL) @@ -6778,18 +6819,18 @@ void BfCompiler::CompileReified() if ((customAttribute.mType->mAttributeData->mFlags & BfAttributeFlag_AlwaysIncludeTarget) != 0) alwaysInclude = true; } - } + } if (alwaysInclude) mContext->mScratchModule->PopulateType(typeInst, BfPopulateType_Full); } - - PopulateReified(); + + PopulateReified(); } bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { BP_ZONE("BfCompiler::Compile"); - + if (mSystem->mTypeDefs.mCount == 0) { // No-source bailout @@ -6801,7 +6842,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mPassInstance->Fail(mOptions.mErrorString); return false; } - + { String hotSwapErrors; String toolsetErrors; @@ -6815,13 +6856,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { if (!hotSwapErrors.IsEmpty()) hotSwapErrors += ", "; - hotSwapErrors += project->mName; + hotSwapErrors += project->mName; } if (mOptions.mToolsetType != BfToolsetType_LLVM) { if (!toolsetErrors.IsEmpty()) toolsetErrors += ", "; - toolsetErrors += project->mName; + toolsetErrors += project->mName; } } } @@ -6856,8 +6897,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mRevision++; mHasComptimeRebuilds = false; int revision = mRevision; - BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision, - (mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty()), + BfLogSysM("Compile Start. Revision: %d. HasParser:%d AutoComplete:%d\n", revision, + (mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty()), (mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL)); if (mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) @@ -6916,8 +6957,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) // This will get rid of any old method data so we don't have any more mPrevVersions ClearOldHotData(); } - - int prevUnfinishedModules = mStats.mModulesStarted - mStats.mModulesFinished; + + int prevUnfinishedModules = mStats.mModulesStarted - mStats.mModulesFinished; mCompletionPct = 0; memset(&mStats, 0, sizeof(mStats)); mCodeGen.ClearResults(); @@ -6931,7 +6972,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (module->mAddedToCount) { if (module->mIsReified) - mStats.mReifiedModuleCount++; + mStats.mReifiedModuleCount++; } }; @@ -6944,11 +6985,10 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } } } - if (IsHotCompile()) { - mContext->EnsureHotMangledVirtualMethodNames(); + mContext->EnsureHotMangledVirtualMethodNames(); } mOutputDirectory = outputDirectory; @@ -6966,17 +7006,17 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } #endif - BfTypeDef* typeDef; + BfTypeDef* typeDef; - BfLogSysM("UpdateRevisedTypes Revision %d. ResolvePass:%d CursorIdx:%d\n", mRevision, mIsResolveOnly, + BfLogSysM("UpdateRevisedTypes Revision %d. ResolvePass:%d CursorIdx:%d\n", mRevision, mIsResolveOnly, ((mResolvePassData == NULL) || (mResolvePassData->mParsers.IsEmpty())) ? - 1 : mResolvePassData->mParsers[0]->mCursorIdx); - + mCompileState = CompileState_Normal; - UpdateRevisedTypes(); + UpdateRevisedTypes(); // We need to defer processing the graveyard until here, because mLookupResults contain atom references so we need to make sure // those aren't deleted until we can properly handle it. mSystem->ProcessAtomGraveyard(); - + BpEnter("Compile_Start"); mHasRequiredTypes = true; @@ -6985,18 +7025,17 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) auto _GetRequiredType = [&](const StringImpl& typeName, int genericArgCount = 0) { - auto typeDef = mSystem->FindTypeDef(typeName, genericArgCount); + auto typeDef = mSystem->FindTypeDef(typeName, genericArgCount); if (typeDef == NULL) { mPassInstance->Fail(StrFormat("Unable to find system type: %s", typeName.c_str())); mHasRequiredTypes = false; - } + } return typeDef; }; - _GetRequiredType("System.Void"); - _GetRequiredType("System.Boolean"); + _GetRequiredType("System.Boolean"); _GetRequiredType("System.Int"); _GetRequiredType("System.Int8"); _GetRequiredType("System.Int16"); @@ -7006,7 +7045,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) _GetRequiredType("System.UInt8"); _GetRequiredType("System.UInt16"); _GetRequiredType("System.UInt32"); - _GetRequiredType("System.UInt64"); + _GetRequiredType("System.UInt64"); _GetRequiredType("System.Char8"); _GetRequiredType("System.Char16"); mChar32TypeDef = _GetRequiredType("System.Char32"); @@ -7014,7 +7053,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mDoubleTypeDef = _GetRequiredType("System.Double"); mMathTypeDef = _GetRequiredType("System.Math"); - mBfObjectTypeDef = _GetRequiredType("System.Object"); + mBfObjectTypeDef = _GetRequiredType("System.Object"); mArray1TypeDef = _GetRequiredType("System.Array1", 1); mArray2TypeDef = _GetRequiredType("System.Array2", 1); mArray3TypeDef = _GetRequiredType("System.Array3", 1); @@ -7025,7 +7064,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mIndexTypeDef = _GetRequiredType("System.Index"); mIndexRangeTypeDef = _GetRequiredType("System.IndexRange"); mAttributeTypeDef = _GetRequiredType("System.Attribute"); - mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute"); + mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute"); mClassVDataTypeDef = _GetRequiredType("System.ClassVData"); mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute"); mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute"); @@ -7049,11 +7088,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute"); mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute"); mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute"); - mResultTypeDef = _GetRequiredType("System.Result", 1); - mGCTypeDef = _GetRequiredType("System.GC"); + mResultTypeDef = _GetRequiredType("System.Result", 1); + mGCTypeDef = _GetRequiredType("System.GC"); mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1); mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1); - mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1); + mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1); mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute"); mThreadTypeDef = _GetRequiredType("System.Threading.Thread"); mInternalTypeDef = _GetRequiredType("System.Internal"); @@ -7066,7 +7105,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mIPrintableTypeDef = _GetRequiredType("System.IPrintable"); mIHashableTypeDef = _GetRequiredType("System.IHashable"); mIComptimeTypeApply = _GetRequiredType("System.IComptimeTypeApply"); - mIComptimeMethodApply = _GetRequiredType("System.IComptimeMethodApply"); + mIComptimeMethodApply = _GetRequiredType("System.IComptimeMethodApply"); mIOnTypeInitTypeDef = _GetRequiredType("System.IOnTypeInit"); mIOnTypeDoneTypeDef = _GetRequiredType("System.IOnTypeDone"); mIOnFieldInitTypeDef = _GetRequiredType("System.IOnFieldInit"); @@ -7096,7 +7135,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mReflectUnspecializedGenericType = _GetRequiredType("System.Reflection.UnspecializedGenericType"); mReflectFieldInfoTypeDef = _GetRequiredType("System.Reflection.FieldInfo"); mReflectMethodInfoTypeDef = _GetRequiredType("System.Reflection.MethodInfo"); - mSizedArrayTypeDef = _GetRequiredType("System.SizedArray", 2); + mSizedArrayTypeDef = _GetRequiredType("System.SizedArray", 2); mStaticInitAfterAttributeTypeDef = _GetRequiredType("System.StaticInitAfterAttribute"); mStaticInitPriorityAttributeTypeDef = _GetRequiredType("System.StaticInitPriorityAttribute"); mStringTypeDef = _GetRequiredType("System.String"); @@ -7104,7 +7143,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mTestAttributeTypeDef = _GetRequiredType("System.TestAttribute"); mThreadStaticAttributeTypeDef = _GetRequiredType("System.ThreadStaticAttribute"); mTypeTypeDef = _GetRequiredType("System.Type"); - mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute"); + mUnboundAttributeTypeDef = _GetRequiredType("System.UnboundAttribute"); mValueTypeTypeDef = _GetRequiredType("System.ValueType"); mObsoleteAttributeTypeDef = _GetRequiredType("System.ObsoleteAttribute"); mErrorAttributeTypeDef = _GetRequiredType("System.ErrorAttribute"); @@ -7125,13 +7164,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) // Force rebuilding BfLogSysM("Compile missing required types\n"); mOptions.mForceRebuildIdx++; - } - + } + mSystem->CheckLockYield(); if (mBfObjectTypeDef != NULL) mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef); - VisitSourceExteriorNodes(); + VisitSourceExteriorNodes(); if (!mIsResolveOnly) { @@ -7186,7 +7225,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mVDataModules.push_back(module); foundVDataModuleSet.Add(module); - } + } } // Remove old vdata @@ -7198,18 +7237,18 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) delete module; mVDataModules.erase(mVDataModules.begin() + moduleIdx); moduleIdx--; - + mContext->mModules.Remove(module); } } } if (mIsResolveOnly) - VisitAutocompleteExteriorIdentifiers(); - + VisitAutocompleteExteriorIdentifiers(); + mStats.mTypesQueued = 0; mStats.mMethodsQueued = 0; - + mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size(); mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size(); @@ -7248,7 +7287,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) bool didWork = false; UpdateDependencyMap(mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_ResolveUnused, didWork); - + // If UpdateDependencyMap caused methods to be reified, then we need to run PopulateReified again- // because those methods may be virtual and we need to reify overrides (for example). // We use the DoWorkLoop result to determine if there were actually any changes from UpdateDependencyMap @@ -7263,7 +7302,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) BfLogSysM("DoCompile looping over CompileReified due to mHasReifiedQueuedRebuildTypes\n"); } - + // Handle purgatory (ie: old generic types) { bool didWork = ProcessPurgatory(true); @@ -7345,22 +7384,22 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) HashSet projectSet; for (auto type : mContext->mResolvedTypes) - { + { auto typeInstance = type->ToTypeInstance(); if (typeInstance != NULL) - { + { for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups) { if (methodInstanceGroup.mDefault != NULL) { auto methodInstance = methodInstanceGroup.mDefault; - auto project = methodInstance->mMethodDef->mDeclaringType->mProject; + auto project = methodInstance->mMethodDef->mDeclaringType->mProject; if (project->mTargetType != BfTargetType_BeefTest) continue; if ((methodInstance->GetCustomAttributes() != NULL) && (methodInstance->GetCustomAttributes()->Contains(mTestAttributeTypeDef))) { - projectSet.Add(project); + projectSet.Add(project); } } } @@ -7385,9 +7424,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if ((!mIsResolveOnly) && (!mCanceling)) { if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes)) - { + { int prevSlotCount = mMaxInterfaceSlots; - GenerateSlotNums(); + GenerateSlotNums(); if ((prevSlotCount != -1) && (prevSlotCount != mMaxInterfaceSlots)) { mInterfaceSlotCountChanged = true; @@ -7400,18 +7439,18 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) // Resolve unused types if ((mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_ResolveUnused) && (!mCanceling)) { - // Finish off any outstanding modules so we can code generate in parallel with handling the unreified stuff + // Finish off any outstanding modules so we can code generate in parallel with handling the unreified stuff for (auto module : mContext->mModules) { if (!module->mIsSpecialModule) { if ((module->HasCompiledOutput()) && (module->mIsModuleMutable)) - { + { module->Finish(); } } - } - + } + DoWorkLoop(); BfLogSysM("Compile QueueUnused\n"); @@ -7427,7 +7466,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) bool queuedMoreMethods = false; int startTypeInitCount = mTypeInitCount; - + for (auto typeDef : mSystem->mTypeDefs) { mSystem->CheckLockYield(); @@ -7439,19 +7478,19 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (typeDef->mProject->mDisabled) continue; - + if (typeDef->mIsPartial) continue; if (typeDef->mTypeCode == BfTypeCode_Extension) continue; - + mContext->mUnreifiedModule->ResolveTypeDef(typeDef, BfPopulateType_Full); } Array typeWorkList; for (auto type : mContext->mResolvedTypes) - { + { auto module = type->GetModule(); if (module == NULL) @@ -7466,13 +7505,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) continue; - + if (typeInst->IsUnspecializedTypeVariation()) continue; if (!typeInst->IsSpecializedType()) - { - typeWorkList.Add(typeInst); + { + typeWorkList.Add(typeInst); } } @@ -7505,8 +7544,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if ((!queuedMoreMethods) && (startTypeInitCount == mTypeInitCount)) break; - - DoWorkLoop(); + + DoWorkLoop(); } bool didWork = false; @@ -7520,19 +7559,19 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { DoWorkLoop(); } - + ProcessPurgatory(false); // ProcessPurgatory MAY cause type rebuilds which we need to handle DoWorkLoop(); - + BfLogSysM("Checking mDepsMayHaveDeletedTypes for SanitizeDependencyMap\n"); if (mDepsMayHaveDeletedTypes) - SanitizeDependencyMap(); + SanitizeDependencyMap(); - // Old Mark used modules + // Old Mark used modules if (!mIsResolveOnly) - { + { // if ((!mPassInstance->HasFailed()) && (!mCanceling)) // { // if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes)) @@ -7547,8 +7586,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { if (!mOptions.mAllowHotSwapping) { - GenerateDynCastData(); - mContext->ProcessWorkList(false, false); + GenerateDynCastData(); + mContext->ProcessWorkList(false, false); } mCompileState = BfCompiler::CompileState_VData; @@ -7565,11 +7604,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) // to still be the same pointer if it's erased and then put back if ((!IsHotCompile()) && (!mCanceling)) ClearUnusedStringPoolEntries(); - + mContext->ValidateDependencies(); - mContext->UpdateAfterDeletingTypes(); + mContext->UpdateAfterDeletingTypes(); } - + // We need to check the specialized errors before writing out modules -- // this call is responsible for deleting dead method specializations that contained errors, or for setting // the mHadBuildErrors on the module if there was a method specialization error that didn't die @@ -7577,12 +7616,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mContext->Finish(); if ((!mIsResolveOnly) && (!IsHotCompile())) ClearOldHotData(); - + mPassInstance->TryFlushDeferredError(); BpLeave(); BpEnter("Compile_Finish"); - + //TODO:!! //mCanceling = true; @@ -7593,7 +7632,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (!mIsResolveOnly) { int idx = 0; - + BF_ASSERT(mContext->mMethodWorkList.IsEmpty()); //bfContext->mLockModules = true; @@ -7602,7 +7641,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) //bool clearModule = false; auto mainModule = mContext->mModules[moduleIdx]; BfModule* bfModule = mainModule; - if (bfModule->mIsReified) + if (bfModule->mIsReified) { auto itr = mainModule->mSpecializedMethodModules.begin(); while (true) @@ -7645,39 +7684,39 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } } } - + mainModule->ClearModule(); } - //bfContext->mLockModules = false; + //bfContext->mLockModules = false; } else { bool isTargeted = (mResolvePassData != NULL) && (!mResolvePassData->mParsers.IsEmpty()); if (!isTargeted) - { + { for (auto bfModule : mContext->mModules) { if (bfModule->mIsModuleMutable) { - bfModule->Finish(); + bfModule->Finish(); bfModule->mRevision = std::max(bfModule->mRevision, bfModule->mRevision); bfModule->ClearModuleData(); } - } + } } } } /*if (!moduleListStr.empty()) mPassInstance->OutputLine(StrFormat("%d modules generated: %s", numModulesWritten, moduleListStr.c_str()));*/ - + //CompileLog("%d object files written: %s\n", numModulesWritten, moduleListStr.c_str()); - + //printf("Compile done, waiting for finish\n"); - + while (true) - { + { if (mCanceling) mCodeGen.Cancel(); bool isDone = mCodeGen.Finish(); @@ -7689,8 +7728,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mCeMachine->CompileDone(); - // This has to happen after codegen because we may delete modules that are referenced in codegen - mContext->Cleanup(); + // This has to happen after codegen because we may delete modules that are referenced in codegen + mContext->Cleanup(); if ((!IsHotCompile()) && (!mIsResolveOnly) && (!mCanceling)) { // Only save 'saved type data' for temporarily-deleted types like on-demand types. @@ -7740,15 +7779,15 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } libManager->mErrors.Clear(); } -#endif - +#endif + int numObjFilesWritten = 0; for (auto& fileEntry : mCodeGen.mCodeGenFiles) { if (!fileEntry.mWasCached) numObjFilesWritten++; } - mPassInstance->OutputLine(StrFormat(":low %d module%s built, %d object file%s generated", + mPassInstance->OutputLine(StrFormat(":low %d module%s built, %d object file%s generated", numModulesWritten, (numModulesWritten != 1) ? "s" : "", numObjFilesWritten, (numObjFilesWritten != 1) ? "s" : "")); @@ -7756,8 +7795,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { mPassInstance->OutputLine(StrFormat(":med Comptime execution time: %0.2fs", mCeMachine->mRevisionExecuteTime / 1000.0f)); } - - BpLeave(); + + BpLeave(); mPassInstance->WriteErrorSummary(); if ((mCanceling) && (!mIsResolveOnly)) @@ -7767,19 +7806,19 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) CompileLog("Compile canceled\n"); } - BfLogSysM("Compile Done. Revision:%d TypesPopulated:%d MethodsDeclared:%d MethodsProcessed:%d Canceled? %d\n", revision, mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling); - + BfLogSysM("Compile Done. Revision:%d TypesPopulated:%d MethodsDeclared:%d MethodsProcessed:%d Canceled? %d\n", revision, mStats.mTypesPopulated, mStats.mMethodDeclarations, mStats.mMethodsProcessed, mCanceling); + UpdateCompletion(); if ((!mIsResolveOnly) && (!mPassInstance->HasFailed()) && (!mCanceling)) { //BF_ASSERT(mCompletionPct >= 0.99999f); } - + if (mCompileLogFP != NULL) { fclose(mCompileLogFP); mCompileLogFP = NULL; - } + } UpdateCompletion(); mStats.mTotalTypes = mContext->mResolvedTypes.GetCount(); @@ -7797,7 +7836,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) for (auto& fileEntry : mCodeGen.mCodeGenFiles) { if (fileEntry.mWasCached) - continue; + continue; mHotState->mQueuedOutFiles.Add(fileEntry); } @@ -7807,7 +7846,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mHotState->mNewlySlottedTypeIds.Clear(); mHotState->mSlotDefineTypeIds.Clear(); } - } + } mCompileState = BfCompiler::CompileState_None; @@ -7831,7 +7870,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) if (didCancel) mLastHadComptimeRebuilds = mHasComptimeRebuilds || mLastHadComptimeRebuilds; else - mLastHadComptimeRebuilds = mHasComptimeRebuilds; + mLastHadComptimeRebuilds = mHasComptimeRebuilds; return !didCancel && !mHasQueuedTypeRebuilds; } @@ -7848,7 +7887,7 @@ bool BfCompiler::Compile(const StringImpl& outputDirectory) BfLogSysM("Interface slot count increased. Rebuilding relevant modules.\n"); mPassInstance->OutputLine("Interface slot count increased. Rebuilding relevant modules."); // Recompile with the increased slot count - success = DoCompile(outputDirectory); + success = DoCompile(outputDirectory); BF_ASSERT(!mInterfaceSlotCountChanged); return success; } @@ -7871,7 +7910,7 @@ void BfCompiler::Cancel() mHadCancel = true; if (mCeMachine != NULL) { - AutoCrit autoCrit(mCeMachine->mCritSect); + AutoCrit autoCrit(mCeMachine->mCritSect); mCeMachine->mSpecialCheck = true; mFastFinish = true; } @@ -7893,12 +7932,12 @@ void BfCompiler::RequestFastFinish() void BfCompiler::CompileLog(const char* fmt ...) { #ifdef WANT_COMPILE_LOG - if (mCompileLogFP == NULL) + if (mCompileLogFP == NULL) return; //static int lineNum = 0; //lineNum++; - + va_list argList; va_start(argList, fmt); String aResult = vformat(fmt, argList); @@ -7906,7 +7945,7 @@ void BfCompiler::CompileLog(const char* fmt ...) //aResult = StrFormat("%d ", lineNum) + aResult; - fwrite(aResult.c_str(), 1, aResult.length(), mCompileLogFP); + fwrite(aResult.c_str(), 1, aResult.length(), mCompileLogFP); #endif } @@ -7925,23 +7964,22 @@ void BfCompiler::ReportMemory(MemReporter* memReporter) type->ReportMemory(memReporter); } - for (auto module : mContext->mModules) { AutoMemReporter autoMemReporter(memReporter, "Modules"); module->ReportMemory(memReporter); - } + } { AutoMemReporter autoMemReporter(memReporter, "ScratchModule"); mContext->mScratchModule->ReportMemory(memReporter); - } - + } + for (auto vdataModule : mVDataModules) { AutoMemReporter autoMemReporter(memReporter, "VDataModules"); vdataModule->ReportMemory(memReporter); - } + } if (mHotData != NULL) { @@ -7968,18 +8006,18 @@ void BfCompiler::ReportMemory(MemReporter* memReporter) { memReporter->AddStr(kv.mKey, false); } - } + } } ////////////////////////////////////////////////////////////////////////// void BfCompiler::GenerateAutocompleteInfo() -{ - BP_ZONE("BfCompiler::GetAutocompleteInfo"); - +{ + BP_ZONE("BfCompiler::GetAutocompleteInfo"); + String& autoCompleteResultString = *gTLStrReturn.Get(); autoCompleteResultString.Clear(); - + auto bfModule = mResolvePassData->mAutoComplete->mModule; if (bfModule != NULL) { @@ -7997,7 +8035,7 @@ void BfCompiler::GenerateAutocompleteInfo() autoCompleteResultString += "uncertain\n"; if (autoComplete->mDefaultSelection.length() != 0) - autoCompleteResultString += StrFormat("select\t%s\n", autoComplete->mDefaultSelection.c_str()); + autoCompleteResultString += StrFormat("select\t%s\n", autoComplete->mDefaultSelection.c_str()); auto _EncodeTypeDef = [] (BfTypeDef* typeDef) { @@ -8010,7 +8048,7 @@ void BfCompiler::GenerateAutocompleteInfo() }; if (autoComplete->mResolveType == BfResolveType_GetSymbolInfo) - { + { if (autoComplete->mDefTypeGenericParamIdx != -1) { autoCompleteResultString += StrFormat("typeGenericParam\t%d\n", autoComplete->mDefTypeGenericParamIdx); @@ -8119,7 +8157,7 @@ void BfCompiler::GenerateAutocompleteInfo() int idx = 0; for (auto& methodEntry : methodMatchInfo->mInstanceList) - { + { String methodText; if (methodEntry.mPayloadEnumField != NULL) { @@ -8156,7 +8194,7 @@ void BfCompiler::GenerateAutocompleteInfo() { BfMethodInstance* methodInstance = NULL; if (methodEntry.mMethodDef->mIdx < 0) - { + { for (auto localMethod : mContext->mLocalMethodGraveyard) { if (localMethod->mMethodDef == methodEntry.mMethodDef) @@ -8164,12 +8202,12 @@ void BfCompiler::GenerateAutocompleteInfo() methodInstance = localMethod->mMethodInstanceGroup->mDefault; break; } - } + } } else methodInstance = bfModule->GetRawMethodInstanceAtIdx(methodEntry.mTypeInstance, methodEntry.mMethodDef->mIdx); auto curMethodInstance = methodInstance; - curMethodInstance = methodMatchInfo->mCurMethodInstance; + curMethodInstance = methodMatchInfo->mCurMethodInstance; SetAndRestoreValue prevTypeInstance(bfModule->mCurTypeInstance, methodMatchInfo->mCurTypeInstance); SetAndRestoreValue prevMethodInstance(bfModule->mCurMethodInstance, curMethodInstance); @@ -8229,7 +8267,7 @@ void BfCompiler::GenerateAutocompleteInfo() } methodText += ">"; } - + //TODO: Show default param values also methodText += "(\x1"; if (methodInstance->GetParamCount() == 0) @@ -8254,7 +8292,7 @@ void BfCompiler::GenerateAutocompleteInfo() { auto paramKind = methodInstance->GetParamKind(paramIdx); if ((paramKind == BfParamKind_ImplicitCapture) || (paramKind == BfParamKind_AppendIdx)) - continue; + continue; if (dispParamIdx > 0) methodText += ",\x1 "; @@ -8262,7 +8300,7 @@ void BfCompiler::GenerateAutocompleteInfo() if ((paramIdx == 0) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Extension)) continue; - auto type = methodInstance->GetParamType(paramIdx); + auto type = methodInstance->GetParamType(paramIdx); BfExpression* paramInitializer = methodInstance->GetParamInitializer(paramIdx); if (paramInitializer != NULL) @@ -8365,7 +8403,7 @@ void BfCompiler::GenerateAutocompleteInfo() return lhs->mScore > rhs->mScore; }); - + String docString; for (auto entry : entries) { @@ -8412,7 +8450,7 @@ String BfCompiler::GetTypeDefList() Dictionary projectIds; for (auto typeDef : mSystem->mTypeDefs) - { + { if (typeDef->mProject != curProject) { curProject = typeDef->mProject; @@ -8431,7 +8469,7 @@ String BfCompiler::GetTypeDefList() result += str; } } - + if (((!typeDef->mIsPartial) || (typeDef->mIsCombinedPartial))) { if (typeDef->IsGlobalsContainer()) @@ -8459,7 +8497,7 @@ String BfCompiler::GetTypeDefList() } String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args) -{ +{ if (typeInst == NULL) { auto type = mContext->mUnreifiedModule->ResolveTypeDef(typeDef, BfPopulateType_BaseType); @@ -8502,7 +8540,7 @@ void BfCompiler::HandleGeneratorErrors(StringImpl& result) return; result.Clear(); - + for (auto& msg : mPassInstance->mOutStream) { String error = msg; @@ -8519,9 +8557,9 @@ String BfCompiler::GetGeneratorTypeDefList() BfProject* curProject = NULL; Dictionary projectIds; - - BfResolvePassData resolvePassData; - SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); + + BfResolvePassData resolvePassData; + SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); BfPassInstance passInstance(mSystem); SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); @@ -8544,7 +8582,7 @@ String BfCompiler::GetGeneratorTypeDefList() result += BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName); String nameString = GetGeneratorString(typeDef, typeInst, "GetName", NULL); if (!nameString.IsEmpty()) - result += "\t" + nameString; + result += "\t" + nameString; result += "\n"; } } @@ -8557,7 +8595,7 @@ String BfCompiler::GetGeneratorTypeDefList() String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args) { - BfResolvePassData resolvePassData; + BfResolvePassData resolvePassData; SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); BfPassInstance passInstance(mSystem); SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); @@ -8567,7 +8605,7 @@ String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const String String result; for (auto typeDef : typeDefs) - { + { result += GetGeneratorString(typeDef, NULL, "InitUI", &args); if (!result.IsEmpty()) break; @@ -8590,7 +8628,7 @@ String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringI String result; for (auto typeDef : typeDefs) - { + { result += GetGeneratorString(typeDef, NULL, "Generate", &args); if (!result.IsEmpty()) break; @@ -8691,7 +8729,7 @@ public: } void AddPropertyDef(BfTypeDef* typeDef, BfPropertyDef* propDef) - { + { if (propDef->mName == "[]") { mResult += "["; @@ -8818,7 +8856,7 @@ public: if (countIdx > 0) { int genericCount = atoi(str.mPtr + countIdx + 1); - genericMatches = ((genericCount == search.mGenericCount) || (search.mGenericCount == 1)) && + genericMatches = ((genericCount == search.mGenericCount) || (search.mGenericCount == 1)) && (countIdx == (int)search.mStr.length()); } } @@ -8837,19 +8875,19 @@ public: bool CheckCompletesMatch(BfAtomComposite& name) { for (int i = 0; i < name.mSize; i++) - { + { CheckMatch(name.mParts[i]->mString); if (mFoundCount == mSearch.mSize) return true; } - return false; + return false; } bool IsFullMatch() { return mFoundCount == mSearch.mSize; } - + bool CheckMemberMatch(BfTypeDef* typeDef, const StringView& str) { if (CheckMatch(str) == 0) @@ -8888,14 +8926,14 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) { int spacePos = (int)searchStr.IndexOf(' ', searchIdx); String str; - if (spacePos == -1) - str = searchStr.Substring(searchIdx); - else + if (spacePos == -1) + str = searchStr.Substring(searchIdx); + else str = searchStr.Substring(searchIdx, (int)(spacePos - searchIdx)); str.Trim(); - + TypeDefMatchHelper::SearchEntry searchEntry; - + for (int i = 0; i < (int)str.length(); i++) { char c = str[i]; @@ -8908,7 +8946,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) { if (c == ',') searchEntry.mGenericCount++; - } + } } if (searchEntry.mStr.IsEmpty()) searchEntry.mStr = str; @@ -8920,7 +8958,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (openParenIdx == -1) openParenIdx = matchHelper.mSearch.mSize; } - + if (!searchEntry.mStr.IsEmpty()) matchHelper.mSearch.Add(searchEntry); if (str.Contains('.')) @@ -8930,7 +8968,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) searchIdx = spacePos + 1; } - //// We sort from longest to shortest to make sure longer strings match before shorter, which + //// We sort from longest to shortest to make sure longer strings match before shorter, which //// matters when the shorter string is a subset of the longer string //matchHelper.mSearch.Sort([](const String& lhs, const String& rhs) // { @@ -8953,13 +8991,13 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) Array projectInfos; projectInfos.Resize(mSystem->mProjects.size()); - + String typeName; String foundName; int partialIdx = 0; for (auto typeDef : mSystem->mTypeDefs) - { + { if (typeDef->mIsPartial) continue; @@ -8969,14 +9007,14 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) { matchHelper.mCurTypeName.Clear(); typeDef->mFullNameEx.ToString(matchHelper.mCurTypeName); - + matchHelper.ClearResults(); matchHelper.CheckMatch(matchHelper.mCurTypeName); - fullyMatchesName = matchHelper.IsFullMatch(); + fullyMatchesName = matchHelper.IsFullMatch(); } int matchIdx = -1; - + String tempStr; if (!fullyMatchesName) @@ -9010,7 +9048,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) matchHelper.AddPropertyDef(typeDef, propDef); } } - + for (auto methodDef : typeDef->mMethods) { if ((methodDef->mMethodType != BfMethodType_Normal) && @@ -9021,7 +9059,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (methodDef->mMethodDeclaration == NULL) continue; - + matchHelper.ClearResults(); bool matches = matchHelper.CheckMemberMatch(typeDef, methodDef->mName); bool hasTypeString = false; @@ -9038,7 +9076,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (BfTypeUtils::TypeToString(tempStr, typeDef, (BfTypeNameFlags)(BfTypeNameFlag_HideGlobalName | BfTypeNameFlag_InternalName))) tempStr += "."; } - matchHelper.GetMethodDefString(methodDef, tempStr, &genericMethodParamIdx); + matchHelper.GetMethodDefString(methodDef, tempStr, &genericMethodParamIdx); matchHelper.CheckMatch(tempStr, openParenIdx); matches = matchHelper.IsFullMatch(); } @@ -9071,7 +9109,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) matchHelper.AddMethodDef(methodDef); } } - + uint32 matchFlags = 0; for (int atomIdx = typeDef->mFullNameEx.mSize - 1; atomIdx >= 0; atomIdx--) { @@ -9095,9 +9133,9 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) if (!matchHelper.MergeFlags(matchFlags)) { continue; - } + } } - + if (typeDef->mProject != curProject) { curProject = typeDef->mProject; @@ -9137,7 +9175,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) break; } - dotCount++; + dotCount++; } } @@ -9149,13 +9187,13 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) else { result += StrFormat("<%d@", *matchIdxPtr); - } + } } else { result += ":"; } - + if (typeDef->IsGlobalsContainer()) { result += "g"; @@ -9173,7 +9211,7 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr) result += "c"; else result += "v"; - result += typeName + "\n"; + result += typeName + "\n"; } return result; @@ -9237,8 +9275,8 @@ void BfCompiler::GetTypeDefs(const StringImpl& inTypeName, Array& ty for (int i = 0; i < (int)typeName.length(); i++) if (typeName[i] == '+') typeName[i] = '.'; - - BfAtomComposite nameComposite; + + BfAtomComposite nameComposite; if ((typeName.IsEmpty()) || (mSystem->ParseAtomComposite(typeName, nameComposite))) { auto itr = mSystem->mTypeDefs.TryGet(nameComposite); @@ -9263,11 +9301,11 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName) { Array typeDefs; GetTypeDefs(inTypeName, typeDefs); - + String result; TypeDefMatchHelper matchHelper(result); - - for (auto typeDef : typeDefs) + + for (auto typeDef : typeDefs) { auto refNode = typeDef->GetRefNode(); result += "S"; @@ -9282,12 +9320,12 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName) } for (auto propDef : typeDef->mProperties) - { + { if (propDef->GetRefNode() == NULL) continue; result += "P"; - matchHelper.AddPropertyDef(typeDef, propDef); + matchHelper.AddPropertyDef(typeDef, propDef); } for (auto methodDef : typeDef->mMethods) @@ -9299,17 +9337,17 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName) continue; if (methodDef->mMethodDeclaration == NULL) - continue; + continue; result += "M"; - matchHelper.AddMethodDef(methodDef); + matchHelper.AddMethodDef(methodDef); } } return result; } int BfCompiler::GetTypeId(const StringImpl& typeName) -{ +{ auto type = GetType(typeName); if (type != NULL) return type->mTypeId; @@ -9323,7 +9361,7 @@ BfType* BfCompiler::GetType(const StringImpl& fullTypeName) BfPassInstance passInstance(mSystem); BfProject* activeProject = NULL; - + String typeName = fullTypeName; int colonPos = (int)typeName.LastIndexOf(':'); if (colonPos != -1) @@ -9363,7 +9401,8 @@ BfType* BfCompiler::GetType(const StringImpl& fullTypeName) SetAndRestoreValue prevIgnoreWarnings(mContext->mScratchModule->mIgnoreWarnings, true); SetAndRestoreValue prevResolvePass(mResolvePassData, &resolvePass); - auto type = mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_AllowUnboundGeneric)); + auto type = mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)( + BfResolveTypeRefFlag_NoCreate | BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_AllowGlobalContainer)); if (type != NULL) return type; @@ -9371,12 +9410,12 @@ BfType* BfCompiler::GetType(const StringImpl& fullTypeName) } int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer) -{ +{ int lastDollarPos = (int)fileName.LastIndexOf('$'); if (lastDollarPos == -1) - return -1; - - String typeName = fileName.Substring(lastDollarPos + 1); + return -1; + + String typeName = fileName.Substring(lastDollarPos + 1); int typeId = GetTypeId(typeName); if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize)) return -1; @@ -9399,7 +9438,7 @@ int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer) return typeInst->mRevision; } -String BfCompiler::GetEmitLocation(const StringImpl& typeName, int emitLine, int& outEmbedLine, int& outEmbedLineChar) +String BfCompiler::GetEmitLocation(const StringImpl& typeName, int emitLine, int& outEmbedLine, int& outEmbedLineChar, uint64& outHash) { outEmbedLine = 0; @@ -9443,8 +9482,10 @@ String BfCompiler::GetEmitLocation(const StringImpl& typeName, int emitLine, int int endLineChar = 0; emitParser->GetLineCharAtIdx(kv.mValue.mSrcEnd - 1, endLine, endLineChar); + outHash = Hash64(emitParser->mSrc + kv.mValue.mSrcStart, kv.mValue.mSrcEnd - kv.mValue.mSrcStart); + if ((emitLine >= startLine) && (emitLine <= endLine)) - { + { origParser->GetLineCharAtIdx(charIdx, outEmbedLine, outEmbedLineChar); return origParser->mFileName; } @@ -9502,7 +9543,7 @@ PerfManager* BfGetPerfManager(BfParser* bfParser); BF_EXPORT bool BF_CALLTYPE BfCompiler_Compile(BfCompiler* bfCompiler, BfPassInstance* bfPassInstance, const char* outputPath) { BP_ZONE("BfCompiler_Compile"); - + SetAndRestoreValue prevPassInstance(bfCompiler->mPassInstance, bfPassInstance); bfCompiler->mPassInstance = bfPassInstance; bfCompiler->Compile(outputPath); @@ -9516,29 +9557,29 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_ClearResults(BfCompiler* bfCompiler) BF_EXPORT bool BF_CALLTYPE BfCompiler_ClassifySource(BfCompiler* bfCompiler, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData) { - BP_ZONE("BfCompiler_ClassifySource"); - + BP_ZONE("BfCompiler_ClassifySource"); + bfCompiler->mSystem->AssertWeHaveLock(); String& autoCompleteResultString = *gTLStrReturn.Get(); autoCompleteResultString.clear(); - + bfPassInstance->mCompiler = bfCompiler; for (auto parser : resolvePassData->mParsers) - bfPassInstance->mFilterErrorsTo.Add(parser->mSourceData); + bfPassInstance->mFilterErrorsTo.Add(parser->mSourceData); bfPassInstance->mTrimMessagesToCursor = true; SetAndRestoreValue prevCompilerResolvePassData(bfCompiler->mResolvePassData, resolvePassData); SetAndRestoreValue prevPassInstance(bfCompiler->mPassInstance, bfPassInstance); bool canceled = false; - + if ((resolvePassData->mAutoComplete != NULL) && (!resolvePassData->mParsers.IsEmpty())) { bfCompiler->ProcessAutocompleteTempType(); } else canceled = !bfCompiler->Compile(""); - + return !canceled; } @@ -9548,7 +9589,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo String& outString = *gTLStrReturn.Get(); outString.Clear(); - + class CollapseVisitor : public BfElementVisitor { public: @@ -9588,7 +9629,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } void FlushSeries() - { + { if (mStartSeriesIdx != -1) { bool ownsLine = true; @@ -9673,12 +9714,12 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo void Add(BfAstNode* anchor, BfAstNode* end, char kind = '?', int minLines = 2) { if ((anchor == NULL) || (end == NULL)) - return; + return; Add(anchor->mSrcStart, end->mSrcEnd - 1, kind, minLines); } - + virtual void Visit(BfMethodDeclaration* methodDeclaration) override - { + { int anchorIdx = methodDeclaration->mSrcStart; if (methodDeclaration->mNameNode != NULL) @@ -9686,14 +9727,14 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo if (methodDeclaration->mCloseParen != NULL) anchorIdx = methodDeclaration->mCloseParen->mSrcEnd - 1; - if (methodDeclaration->mBody != NULL) + if (methodDeclaration->mBody != NULL) Add(anchorIdx, methodDeclaration->mBody->mSrcEnd - 1, 'M'); BfElementVisitor::Visit(methodDeclaration); } virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override - { + { Add(namespaceDeclaration->mNamespaceNode, namespaceDeclaration->mBody, 'N'); BfElementVisitor::Visit(namespaceDeclaration); @@ -9717,7 +9758,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfPropertyDeclaration* properyDeclaration) override - { + { Add(properyDeclaration->mNameNode, properyDeclaration->mDefinitionBlock, 'P'); BfElementVisitor::Visit(properyDeclaration); @@ -9731,14 +9772,14 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfPropertyMethodDeclaration* methodDeclaration) override - { + { Add(methodDeclaration->mNameNode, methodDeclaration->mBody); BfElementVisitor::Visit(methodDeclaration); } virtual void Visit(BfIfStatement* ifStatement) override - { + { Add(ifStatement->mCloseParen, ifStatement->mTrueStatement); if (auto elseBlock = BfNodeDynCast(ifStatement->mFalseStatement)) Add(ifStatement->mElseToken, elseBlock); @@ -9768,13 +9809,13 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfForStatement* forStatement) override - { + { Add(forStatement->mCloseParen, forStatement->mEmbeddedStatement); BfElementVisitor::Visit(forStatement); } virtual void Visit(BfForEachStatement* forStatement) override - { + { Add(forStatement->mCloseParen, forStatement->mEmbeddedStatement); BfElementVisitor::Visit(forStatement); } @@ -9786,7 +9827,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfSwitchStatement* switchStatement) override - { + { Add(switchStatement->mOpenParen, switchStatement->mCloseBrace); BfElementVisitor::Visit(switchStatement); } @@ -9798,7 +9839,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } virtual void Visit(BfBlock* block) override - { + { Add(block->mOpenBrace, block->mCloseBrace); BfElementVisitor::Visit(block); } @@ -9823,65 +9864,68 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo BfAstNode* regionStart = NULL; BfPreprocessorNode* prevPreprocessorNode = NULL; int ignoredSectionStart = -1; - - for (auto element : bfParser->mSidechannelRootNode->mChildArr) + + if (bfParser->mSidechannelRootNode != NULL) { - if (auto preprocessorNode = BfNodeDynCast(element)) + for (auto element : bfParser->mSidechannelRootNode->mChildArr) { - if ((ignoredSectionStart != -1) && (prevPreprocessorNode != NULL) && (prevPreprocessorNode->mCommand != NULL)) + if (auto preprocessorNode = BfNodeDynCast(element)) { - collapseVisitor.Add(prevPreprocessorNode->mCommand->mSrcStart, preprocessorNode->mSrcEnd - 1); - ignoredSectionStart = -1; - } - - StringView sv = preprocessorNode->mCommand->ToStringView(); - if (sv == "region") - regionStart = preprocessorNode->mCommand; - else if (sv == "endregion") - { - if (regionStart != NULL) - collapseVisitor.Add(regionStart->mSrcStart, preprocessorNode->mCommand->mSrcStart, 'R'); - regionStart = NULL; - } - else if (sv == "if") - { - condStart = preprocessorNode->mCommand; - } - else if (sv == "endif") - { - if (condStart != NULL) - collapseVisitor.Add(condStart->mSrcStart, preprocessorNode->mCommand->mSrcStart); - condStart = NULL; - } - else if ((sv == "else") || (sv == "elif")) - { - if (condStart != NULL) - collapseVisitor.Add(condStart->mSrcStart, collapseVisitor.GetLineEndBefore(preprocessorNode->mSrcStart)); - condStart = preprocessorNode->mCommand; - } - - prevPreprocessorNode = preprocessorNode; - } - - if (auto preprocessorNode = BfNodeDynCast(element)) - { - if (ignoredSectionStart == -1) - { - for (int i = preprocessorNode->mSrcStart; i < preprocessorNode->mSrcEnd - 1; i++) + if ((ignoredSectionStart != -1) && (prevPreprocessorNode != NULL) && (prevPreprocessorNode->mCommand != NULL)) { - if (bfParser->mSrc[i] == '\n') - { - ignoredSectionStart = i + 1; - break; - } - } - } - } + collapseVisitor.Add(prevPreprocessorNode->mCommand->mSrcStart, preprocessorNode->mSrcEnd - 1); + ignoredSectionStart = -1; + } - char kind = 0; - if (auto commentNode = BfNodeDynCast(element)) - { - collapseVisitor.UpdateSeries(commentNode, 'C'); + StringView sv = preprocessorNode->mCommand->ToStringView(); + if (sv == "region") + regionStart = preprocessorNode->mCommand; + else if (sv == "endregion") + { + if (regionStart != NULL) + collapseVisitor.Add(regionStart->mSrcStart, preprocessorNode->mCommand->mSrcStart, 'R'); + regionStart = NULL; + } + else if (sv == "if") + { + condStart = preprocessorNode->mCommand; + } + else if (sv == "endif") + { + if (condStart != NULL) + collapseVisitor.Add(condStart->mSrcStart, preprocessorNode->mCommand->mSrcStart); + condStart = NULL; + } + else if ((sv == "else") || (sv == "elif")) + { + if (condStart != NULL) + collapseVisitor.Add(condStart->mSrcStart, collapseVisitor.GetLineEndBefore(preprocessorNode->mSrcStart)); + condStart = preprocessorNode->mCommand; + } + + prevPreprocessorNode = preprocessorNode; + } + + if (auto preprocessorNode = BfNodeDynCast(element)) + { + if (ignoredSectionStart == -1) + { + for (int i = preprocessorNode->mSrcStart; i < preprocessorNode->mSrcEnd - 1; i++) + { + if (bfParser->mSrc[i] == '\n') + { + ignoredSectionStart = i + 1; + break; + } + } + } + } + + char kind = 0; + if (auto commentNode = BfNodeDynCast(element)) + { + collapseVisitor.UpdateSeries(commentNode, 'C'); + } } } @@ -9916,7 +9960,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo bool mIsPrimary; }; Dictionary> emitLocMap; - + bool mayHaveMissedEmits = false; for (auto type : bfCompiler->mContext->mResolvedTypes) @@ -9924,7 +9968,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) continue; - + if (typeHashSet.Contains(typeInst->mTypeDef->GetDefinition()->GetLatest())) { if (typeInst->mCeTypeInfo == NULL) @@ -9944,7 +9988,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo auto typeDef = typeInst->mTypeDef; if (partialIdx > 0) typeDef = typeDef->mPartials[partialIdx]; - + auto emitParser = typeInst->mTypeDef->GetLastSource()->ToParser(); Dictionary* map = NULL; @@ -9983,7 +10027,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo else { int dollarPos = (int)emitParser->mFileName.LastIndexOf('$'); - if (dollarPos != -1) + if (dollarPos != -1) outString += emitParser->mFileName.Substring(dollarPos + 1); } outString += "\n"; @@ -10063,7 +10107,14 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo int endLineChar = 0; if (srcEnd >= 0) emitParser->GetLineCharAtIdx(srcEnd, endLine, endLineChar); - outString += StrFormat("e%d,%d,%d,%d,%d\n", embedId, charIdx, startLine, endLine + 1, typeInst->mTypeDef->mTypeDeclaration->GetParser()->mTextVersion); + + int textVersion = -1; + auto declParser = typeInst->mTypeDef->mTypeDeclaration->GetParser(); + if (declParser != NULL) + textVersion = declParser->mTextVersion; + + char emitChar = (kv.mValue.mKind == BfCeTypeEmitSourceKind_Type) ? 't' : 'm'; + outString += StrFormat("%c%d,%d,%d,%d,%d\n", emitChar, embedId, charIdx, startLine, endLine + 1, textVersion); } } @@ -10083,7 +10134,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo Dictionary* map = NULL; if (emitLocMap.TryGetValue(typeDef, &map)) { - for (auto kv : *map) + for (auto& kv : *map) { if (kv.mValue.mIsPrimary) continue; @@ -10092,7 +10143,8 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo if (embedId == -1) continue; - outString += StrFormat("e%d,%d,%d,%d,%d\n", embedId, kv.mKey, 0, 0, -1); + char emitChar = 't'; + outString += StrFormat("%c%d,%d,%d,%d,%d\n", emitChar, embedId, kv.mKey, 0, 0, -1); } } }; @@ -10103,7 +10155,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetCollapseRegions(BfCompiler* bfCo } } } - + return outString.c_str(); } @@ -10122,7 +10174,7 @@ BF_EXPORT bool BF_CALLTYPE BfCompiler_VerifyTypeName(BfCompiler* bfCompiler, cha BfPassInstance passInstance(bfCompiler->mSystem); BfParser parser(bfCompiler->mSystem); - parser.SetSource(typeName.c_str(), (int)typeName.length()); + parser.SetSource(typeName.c_str(), (int)typeName.length()); parser.Parse(&passInstance); parser.mCursorIdx = cursorPos; parser.mCursorCheckIdx = cursorPos; @@ -10131,7 +10183,7 @@ BF_EXPORT bool BF_CALLTYPE BfCompiler_VerifyTypeName(BfCompiler* bfCompiler, cha reducer.mAlloc = parser.mAlloc; reducer.mPassInstance = &passInstance; reducer.mAllowTypeWildcard = true; - + if (parser.mRootNode->mChildArr.mSize == 0) return false; @@ -10160,7 +10212,7 @@ BF_EXPORT bool BF_CALLTYPE BfCompiler_VerifyTypeName(BfCompiler* bfCompiler, cha reducer.mVisitorPos.MoveNext(); } } - + reducer.mVisitorPos.MoveNext(); auto typeRef = reducer.CreateTypeRef(firstNode); if (typeRef == NULL) @@ -10170,15 +10222,15 @@ BF_EXPORT bool BF_CALLTYPE BfCompiler_VerifyTypeName(BfCompiler* bfCompiler, cha if (cursorPos != -1) { resolvePassData.mResolveType = BfResolveType_Autocomplete; - parser.mParserFlags = (BfParserFlag)(parser.mParserFlags | ParserFlag_Autocomplete); - resolvePassData.mAutoComplete = new BfAutoComplete(); + parser.mParserFlags = (BfParserFlag)(parser.mParserFlags | ParserFlag_Autocomplete); + resolvePassData.mAutoComplete = new BfAutoComplete(); resolvePassData.mAutoComplete->mResolveType = BfResolveType_VerifyTypeName; resolvePassData.mAutoComplete->mSystem = bfCompiler->mSystem; resolvePassData.mAutoComplete->mCompiler = bfCompiler; resolvePassData.mAutoComplete->mModule = bfCompiler->mContext->mScratchModule; } resolvePassData.mParsers.Add(&parser); - + SetAndRestoreValue prevCompilerResolvePassData(bfCompiler->mResolvePassData, &resolvePassData); SetAndRestoreValue prevPassInstance(bfCompiler->mPassInstance, &passInstance); @@ -10264,13 +10316,13 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_WriteBuildCache(BfCompiler* bfCompiler, ch } BF_EXPORT void BF_CALLTYPE BfCompiler_Delete(BfCompiler* bfCompiler) -{ - delete bfCompiler; +{ + delete bfCompiler; } BF_EXPORT void BF_CALLTYPE BfCompiler_ProgramDone() { -#ifdef BF_PLATFORM_WINDOWS +#ifdef BF_PLATFORM_WINDOWS BeLibManager::Get()->Clear(); #endif } @@ -10325,7 +10377,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefInfo(BfCompiler* bfCompil BF_EXPORT int BF_CALLTYPE BfCompiler_GetTypeId(BfCompiler* bfCompiler, const char* name) { - return bfCompiler->GetTypeId(name); + return bfCompiler->GetTypeId(name); } BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, const char* name) @@ -10391,7 +10443,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, BfResolvePassData resolvePass; SetAndRestoreValue prevIgnoreError(bfCompiler->mContext->mScratchModule->mIgnoreErrors, true); SetAndRestoreValue prevIgnoreWarnings(bfCompiler->mContext->mScratchModule->mIgnoreWarnings, true); - SetAndRestoreValue prevResolvePass(bfCompiler->mResolvePassData, &resolvePass); + SetAndRestoreValue prevResolvePass(bfCompiler->mResolvePassData, &resolvePass); auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoCreate); if (type != NULL) @@ -10468,7 +10520,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGenericTypeInstances(BfCompiler* continue; if (typeInst->mTypeDef->GetDefinition()->GetLatest() == lookupTypeInst->mTypeDef->GetDefinition()->GetLatest()) - { + { outString += bfCompiler->mContext->mScratchModule->TypeToString(typeInst, BfTypeNameFlag_AddProjectName); outString += "\n"; } @@ -10485,40 +10537,40 @@ enum BfUsedOutputFlags }; BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(BfCompiler* bfCompiler, BfProject* bfProject, BfUsedOutputFlags flags, bool* hadOutputChanges) -{ +{ bfCompiler->mSystem->AssertWeHaveLock(); BP_ZONE("BfCompiler_GetUsedOutputFileNames"); - + *hadOutputChanges = false; String& outString = *gTLStrReturn.Get(); outString.clear(); - + Array moduleList; moduleList.Reserve(bfProject->mUsedModules.size()); if (bfCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) { for (auto mainModule : bfCompiler->mContext->mModules) - { + { if ((!mainModule->mIsReified) || (mainModule->mIsScratchModule)) continue; if (bfCompiler->mOptions.mHotProject != NULL) continue; // Only add new objs from mCodeGen.mCodeGenFiles during hot reload if (!bfCompiler->IsModuleAccessible(mainModule, bfProject)) continue; - + moduleList.push_back(mainModule); } } else { for (auto mainModule : bfProject->mUsedModules) - { + { if ((!mainModule->mIsReified) || (mainModule->mIsScratchModule)) continue; if (bfCompiler->mOptions.mHotProject != NULL) - continue; // Only add new objs from mCodeGen.mCodeGenFiles during hot reload + continue; // Only add new objs from mCodeGen.mCodeGenFiles during hot reload moduleList.push_back(mainModule); } @@ -10568,19 +10620,19 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(BfCompiler* } if (!canReference) continue; - + String fileName = moduleFileName.mFileName; #ifdef BF_PLATFORM_WINDOWS if (moduleFileName.mWroteToLib) fileName = BeLibManager::GetLibFilePath(fileName); -#endif +#endif if (!usedFileNames.TryAdd(fileName, NULL)) continue; if (!outString.empty()) outString += "\n"; - outString += fileName; + outString += fileName; } } @@ -10661,7 +10713,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetSymbolReferences(BfCompiler* bfC SetAndRestoreValue prevPassInstance(bfCompiler->mPassInstance, bfPassInstance); bfCompiler->GetSymbolReferences(); - std::map sortedParserMap; + std::map sortedParserMap; for (auto& parserDataPair : resolvePassData->mFoundSymbolReferencesParserData) { if (!parserDataPair.mKey->mFileName.Contains('|')) @@ -10679,7 +10731,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetSymbolReferences(BfCompiler* bfC BF_EXPORT bool BF_CALLTYPE BfCompiler_GetHasHotPendingDataChanges(BfCompiler* bfCompiler) { - return (bfCompiler->mHotState != NULL) && + return (bfCompiler->mHotState != NULL) && ((!bfCompiler->mHotState->mPendingDataChanges.IsEmpty()) || (!bfCompiler->mHotState->mPendingFailedSlottings.IsEmpty())); } @@ -10723,7 +10775,7 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_HotResolve_Finish(BfCompiler* bfCom } static BfPlatformType GetPlatform(StringView str) -{ +{ while (!str.IsEmpty()) { char c = str[str.mLength - 1]; @@ -10734,7 +10786,7 @@ static BfPlatformType GetPlatform(StringView str) } bool hasLinux = false; - + for (auto elem : str.Split('-')) { if (elem == "linux") @@ -10763,9 +10815,9 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje BfLogSys(bfCompiler->mSystem, "BfCompiler_SetOptions\n"); //printf("BfCompiler_SetOptions Threads:%d\n", maxWorkerThreads); - - auto options = &bfCompiler->mOptions; - + + auto options = &bfCompiler->mOptions; + options->mErrorString.Clear(); options->mHotProject = hotProject; options->mHotCompileIdx = hotIdx; @@ -10795,7 +10847,7 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje if (options->mPlatformType != BfPlatformType_Windows) options->mCLongSize = 8; } - + bfCompiler->mCodeGen.SetMaxThreads(maxWorkerThreads); if (!bfCompiler->mIsResolveOnly) @@ -10805,10 +10857,10 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje // These settings only matter for code generation, they are not applicable for resolveOnly options->mCompileOnDemandKind = BfCompileOnDemandKind_ResolveUnused; - //options->mCompileOnDemandKind = BfCompileOnDemandKind_AlwaysInclude; + //options->mCompileOnDemandKind = BfCompileOnDemandKind_AlwaysInclude; options->mToolsetType = (BfToolsetType)toolsetType; options->mSIMDSetting = (BfSIMDSetting)simdSetting; - options->mIncrementalBuild = (optionFlags & BfCompilerOptionFlag_IncrementalBuild) != 0; + options->mIncrementalBuild = (optionFlags & BfCompilerOptionFlag_IncrementalBuild) != 0; options->mWriteIR = (optionFlags & BfCompilerOptionFlag_WriteIR) != 0; options->mGenerateObj = (optionFlags & BfCompilerOptionFlag_GenerateOBJ) != 0; options->mGenerateBitcode = (optionFlags & BfCompilerOptionFlag_GenerateBitcode) != 0; @@ -10831,12 +10883,12 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje // { // options->mErrorString = "Toolset 'Microsoft' is not available on this platform. Consider changing 'Workspace/General/Toolset'."; // } - BF_ASSERT(!options->mEnableRealtimeLeakCheck); + BF_ASSERT(!options->mEnableRealtimeLeakCheck); #endif options->mEmitObjectAccessCheck = (optionFlags & BfCompilerOptionFlag_EmitObjectAccessCheck) != 0; options->mArithmeticChecks = (optionFlags & BfCompilerOptionFlag_ArithmeticChecks) != 0; options->mAllocStackCount = allocStackCount; - + if (hotProject != NULL) { String errorName; @@ -10859,14 +10911,14 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje else { options->mAllowHotSwapping = allowHotSwapping; - options->mHasVDataExtender = options->mAllowHotSwapping; + options->mHasVDataExtender = options->mAllowHotSwapping; options->mMallocLinkName = mallocLinkName; options->mFreeLinkName = freeLinkName; options->mEmitDebugInfo = emitDebugInfo; options->mEmitLineInfo = (optionFlags & BfCompilerOptionFlag_EmitLineInfo) != 0;; options->mEnableCustodian = (optionFlags & BfCompilerOptionFlag_EnableCustodian) != 0; options->mEnableSideStack = (optionFlags & BfCompilerOptionFlag_EnableSideStack) != 0; - } + } } else { @@ -10874,11 +10926,11 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(BfCompiler* bfCompiler, BfProje options->mAllowHotSwapping = false; options->mObjectHasDebugFlags = false; options->mEnableRealtimeLeakCheck = false; - options->mEmitObjectAccessCheck = false; + options->mEmitObjectAccessCheck = false; options->mArithmeticChecks = false; options->mEmitDynamicCastCheck = false; options->mRuntimeChecks = (optionFlags & BfCompilerOptionFlag_RuntimeChecks) != 0; - } + } } BF_EXPORT void BF_CALLTYPE BfCompiler_ForceRebuild(BfCompiler* bfCompiler) @@ -10901,15 +10953,15 @@ BF_EXPORT int32 BF_CALLTYPE BfCompiler_GetEmitSourceVersion(BfCompiler* bfCompil return bfCompiler->GetEmitSource(fileName, NULL); } -BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetEmitLocation(BfCompiler* bfCompiler, char* typeName, int line, int& outEmbedLine, int& outEmbedLineChar) +BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetEmitLocation(BfCompiler* bfCompiler, char* typeName, int line, int& outEmbedLine, int& outEmbedLineChar, uint64& outHash) { String& outString = *gTLStrReturn.Get(); outString.clear(); - outString = bfCompiler->GetEmitLocation(typeName, line, outEmbedLine, outEmbedLineChar); + outString = bfCompiler->GetEmitLocation(typeName, line, outEmbedLine, outEmbedLineChar, outHash); return outString.c_str(); } BF_EXPORT bool BF_CALLTYPE BfCompiler_WriteEmitData(BfCompiler* bfCompiler, char* filePath, BfProject* project) { return bfCompiler->WriteEmitData(filePath, project); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index c598e2a9..5c8ca6d7 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -50,7 +50,7 @@ enum BfCompileOnDemandKind BfCompileOnDemandKind_SkipUnused }; -class BfCompiler +class BfCompiler { public: enum CompileState @@ -63,22 +63,22 @@ public: }; struct Stats - { + { int mTotalTypes; int mMethodDeclarations; int mTypesPopulated; int mMethodsProcessed; - int mUnreifiedMethodsProcessed; + int mUnreifiedMethodsProcessed; int mQueuedTypesProcessed; int mTypesQueued; int mTypesDeleted; - int mMethodsQueued; + int mMethodsQueued; int mModulesStarted; int mModulesFinished; - + int mModulesReified; int mModulesUnreified; @@ -94,19 +94,19 @@ public: { BfProject* mHotProject; int mHotCompileIdx; - + int32 mForceRebuildIdx; - BfCompileOnDemandKind mCompileOnDemandKind; + BfCompileOnDemandKind mCompileOnDemandKind; String mTargetTriple; String mTargetCPU; BfPlatformType mPlatformType; BfMachineType mMachineType; int mCLongSize; BfToolsetType mToolsetType; - BfSIMDSetting mSIMDSetting; + BfSIMDSetting mSIMDSetting; String mMallocLinkName; String mFreeLinkName; - bool mIncrementalBuild; + bool mIncrementalBuild; bool mEmitDebugInfo; bool mEmitLineInfo; @@ -116,15 +116,15 @@ public: bool mRuntimeChecks; bool mAllowStructByVal; bool mEmitDynamicCastCheck; - + bool mAllowHotSwapping; - bool mObjectHasDebugFlags; + bool mObjectHasDebugFlags; bool mEnableRealtimeLeakCheck; bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags bool mArithmeticChecks; bool mEnableCustodian; bool mEnableSideStack; - bool mHasVDataExtender; + bool mHasVDataExtender; bool mDebugAlloc; bool mOmitDebugHelpers; @@ -167,7 +167,7 @@ public: mAllowHotSwapping = false; mEmitObjectAccessCheck = false; mArithmeticChecks = false; - mObjectHasDebugFlags = false; + mObjectHasDebugFlags = false; mEnableRealtimeLeakCheck = false; mWriteIR = false; mGenerateObj = true; @@ -195,19 +195,19 @@ public: } }; Options mOptions; - + enum HotTypeFlags { HotTypeFlag_None = 0, HotTypeFlag_UserNotUsed = 1, - HotTypeFlag_UserUsed = 2, - + HotTypeFlag_UserUsed = 2, + HotTypeFlag_Heap = 4, HotTypeFlag_ActiveFunction = 8, // Only set for a type version mismatch HotTypeFlag_Delegate = 0x10, // Only set for a type version mismatch HotTypeFlag_FuncPtr = 0x20, // Only set for a type version mismatch HotTypeFlag_CanAllocate = 0x40 - }; + }; enum HotResolveFlags { @@ -237,7 +237,7 @@ public: Array mHotTypeIdFlags; Array mReasons; HashSet mDeferredThisCheckMethods; - + ~HotResolveData(); }; @@ -261,7 +261,7 @@ public: BfHotThisType* GetThisType(BfHotTypeVersion* hotVersion); BfHotAllocation* GetAllocation(BfHotTypeVersion* hotVersion); BfHotDevirtualizedMethod* GetDevirtualizedMethod(BfHotMethod* hotMethod); - BfHotFunctionReference* GetFunctionReference(BfHotMethod* hotMethod); + BfHotFunctionReference* GetFunctionReference(BfHotMethod* hotMethod); BfHotVirtualDeclaration* GetVirtualDeclaration(BfHotMethod* hotMethod); BfHotInnerMethod* GetInnerMethod(BfHotMethod* hotMethod); }; @@ -270,10 +270,10 @@ public: { public: BfProject* mHotProject; - int mLastStringId; + int mLastStringId; int mCommittedHotCompileIdx; bool mHasNewTypes; - bool mHasNewInterfaceTypes; + bool mHasNewInterfaceTypes; Array mQueuedOutFiles; // Queues up when we have failed hot compiles HashSet mSlotDefineTypeIds; HashSet mNewlySlottedTypeIds; @@ -284,7 +284,7 @@ public: public: HotState() - { + { mHotProject = NULL; mLastStringId = -1; mCommittedHotCompileIdx = 0; @@ -298,32 +298,33 @@ public: void RemovePendingChanges(BfTypeInstance* type); }; HotData* mHotData; - HotState* mHotState; + HotState* mHotState; HotResolveData* mHotResolveData; struct StringValueEntry { int mId; BfIRValue mStringVal; - }; + }; struct TestMethod { String mName; BfMethodInstance* mMethodInstance; - }; + }; -public: - BfPassInstance* mPassInstance; +public: + BfPassInstance* mPassInstance; FILE* mCompileLogFP; CeMachine* mCeMachine; int mCurCEExecuteId; - BfSystem* mSystem; + BfSystem* mSystem; bool mIsResolveOnly; BfResolvePassData* mResolvePassData; Dictionary> mAttributeTypeOptionMap; - int mRevision; + int mRevision; + int64 mUniqueId; bool mLastRevisionAborted; BfContext* mContext; BfCodeGen mCodeGen; @@ -342,13 +343,13 @@ public: bool mDepsMayHaveDeletedTypes; float mCompletionPct; int mHSPreserveIdx; - BfModule* mLastAutocompleteModule; + BfModule* mLastAutocompleteModule; CompileState mCompileState; HashSet mRebuildFileSet; HashSet mRebuildChangedFileSet; // Files we had actual changes from - Array mVDataModules; - + Array mVDataModules; + BfTypeDef* mBfObjectTypeDef; BfTypeDef* mChar32TypeDef; BfTypeDef* mFloatTypeDef; @@ -359,16 +360,16 @@ public: BfTypeDef* mArray2TypeDef; BfTypeDef* mArray3TypeDef; BfTypeDef* mArray4TypeDef; - BfTypeDef* mSpanTypeDef; + BfTypeDef* mSpanTypeDef; BfTypeDef* mRangeTypeDef; BfTypeDef* mClosedRangeTypeDef; BfTypeDef* mIndexTypeDef; BfTypeDef* mIndexRangeTypeDef; - - BfTypeDef* mClassVDataTypeDef; - + + BfTypeDef* mClassVDataTypeDef; + BfTypeDef* mDbgRawAllocDataTypeDef; - BfTypeDef* mDeferredCallTypeDef; + BfTypeDef* mDeferredCallTypeDef; BfTypeDef* mDelegateTypeDef; BfTypeDef* mFunctionTypeDef; BfTypeDef* mActionTypeDef; @@ -376,13 +377,13 @@ public: BfTypeDef* mStringTypeDef; BfTypeDef* mStringViewTypeDef; BfTypeDef* mTypeTypeDef; - BfTypeDef* mValueTypeTypeDef; - BfTypeDef* mResultTypeDef; - BfTypeDef* mGCTypeDef; + BfTypeDef* mValueTypeTypeDef; + BfTypeDef* mResultTypeDef; + BfTypeDef* mGCTypeDef; BfTypeDef* mGenericIEnumerableTypeDef; BfTypeDef* mGenericIEnumeratorTypeDef; BfTypeDef* mGenericIRefEnumeratorTypeDef; - + BfTypeDef* mThreadTypeDef; BfTypeDef* mInternalTypeDef; BfTypeDef* mPlatformTypeDef; @@ -394,15 +395,15 @@ public: BfTypeDef* mIPrintableTypeDef; BfTypeDef* mIHashableTypeDef; BfTypeDef* mIComptimeTypeApply; - BfTypeDef* mIComptimeMethodApply; + BfTypeDef* mIComptimeMethodApply; BfTypeDef* mIOnTypeInitTypeDef; BfTypeDef* mIOnTypeDoneTypeDef; BfTypeDef* mIOnFieldInitTypeDef; BfTypeDef* mIOnMethodInitTypeDef; - + BfTypeDef* mMethodRefTypeDef; BfTypeDef* mNullableTypeDef; - + BfTypeDef* mPointerTTypeDef; BfTypeDef* mPointerTypeDef; BfTypeDef* mReflectTypeIdTypeDef; @@ -419,17 +420,17 @@ public: BfTypeDef* mReflectConstExprType; BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectTypeInstanceTypeDef; - BfTypeDef* mReflectUnspecializedGenericType; + BfTypeDef* mReflectUnspecializedGenericType; BfTypeDef* mReflectFieldInfoTypeDef; BfTypeDef* mReflectMethodInfoTypeDef; - + BfTypeDef* mSizedArrayTypeDef; BfTypeDef* mAttributeTypeDef; BfTypeDef* mAttributeUsageAttributeTypeDef; BfTypeDef* mLinkNameAttributeTypeDef; BfTypeDef* mCallingConventionAttributeTypeDef; - BfTypeDef* mOrderedAttributeTypeDef; - BfTypeDef* mInlineAttributeTypeDef; + BfTypeDef* mOrderedAttributeTypeDef; + BfTypeDef* mInlineAttributeTypeDef; BfTypeDef* mCLinkAttributeTypeDef; BfTypeDef* mImportAttributeTypeDef; BfTypeDef* mExportAttributeTypeDef; @@ -445,30 +446,30 @@ public: BfTypeDef* mConstEvalAttributeTypeDef; BfTypeDef* mNoExtensionAttributeTypeDef; BfTypeDef* mCheckedAttributeTypeDef; - BfTypeDef* mUncheckedAttributeTypeDef; + BfTypeDef* mUncheckedAttributeTypeDef; BfTypeDef* mStaticInitAfterAttributeTypeDef; - BfTypeDef* mStaticInitPriorityAttributeTypeDef; + BfTypeDef* mStaticInitPriorityAttributeTypeDef; BfTypeDef* mTestAttributeTypeDef; - BfTypeDef* mThreadStaticAttributeTypeDef; + BfTypeDef* mThreadStaticAttributeTypeDef; BfTypeDef* mUnboundAttributeTypeDef; BfTypeDef* mObsoleteAttributeTypeDef; BfTypeDef* mErrorAttributeTypeDef; BfTypeDef* mWarnAttributeTypeDef; BfTypeDef* mConstSkipAttributeTypeDef; BfTypeDef* mIgnoreErrorsAttributeTypeDef; - BfTypeDef* mReflectAttributeTypeDef; + BfTypeDef* mReflectAttributeTypeDef; BfTypeDef* mOnCompileAttributeTypeDef; - int mCurTypeId; + int mCurTypeId; int mTypeInitCount; String mOutputPath; - Array mGenericInstancePurgatory; + Array mGenericInstancePurgatory; Array mTypeIdFreeList; int mMaxInterfaceSlots; bool mInterfaceSlotCountChanged; -public: +public: bool IsTypeAccessible(BfType* checkType, BfProject* curProject); bool IsTypeUsed(BfType* checkType, BfProject* curProject); bool IsModuleAccessible(BfModule* module, BfProject* curProject); @@ -478,22 +479,22 @@ public: BfIRFunction CreateLoadSharedLibraries(BfVDataModule* bfModule, Array& dllMethods); void GetTestMethods(BfVDataModule* bfModule, Array& testMethods, HashContext& vdataHashCtx); void EmitTestMethod(BfVDataModule* bfModule, Array& testMethods, BfIRValue& retValue); - void CreateVData(BfVDataModule* bfModule); + void CreateVData(BfVDataModule* bfModule); void UpdateDependencyMap(bool deleteUnusued, bool& didWork); void SanitizeDependencyMap(); bool ProcessPurgatory(bool reifiedOnly); bool VerifySlotNums(); bool QuickGenerateSlotNums(); bool SlowGenerateSlotNums(); - void GenerateSlotNums(); + void GenerateSlotNums(); void GenerateDynCastData(); void UpdateRevisedTypes(); - void VisitAutocompleteExteriorIdentifiers(); + void VisitAutocompleteExteriorIdentifiers(); void VisitSourceExteriorNodes(); void UpdateCompletion(); bool DoWorkLoop(bool onlyReifiedTypes = false, bool onlyReifiedMethods = false); BfMangler::MangleKind GetMangleKind(); - + BfTypeDef* GetArrayTypeDef(int dimensions); void GenerateAutocompleteInfo(); void MarkStringPool(BfModule* module); @@ -516,7 +517,7 @@ public: bool IsCePaused(); bool EnsureCeUnpaused(BfType* refType); - void HotCommit(); + void HotCommit(); void HotResolve_Start(HotResolveFlags flags); void HotResolve_PopulateMethodNameMap(); bool HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFlags flags, bool devirtualized, bool forceProcess = false); @@ -531,28 +532,28 @@ public: public: BfCompiler(BfSystem* bfSystem, bool isResolveOnly); - ~BfCompiler(); + ~BfCompiler(); - bool Compile(const StringImpl& outputPath); + bool Compile(const StringImpl& outputPath); bool DoCompile(const StringImpl& outputPath); void ClearResults(); - void ProcessAutocompleteTempType(); - void GetSymbolReferences(); + void ProcessAutocompleteTempType(); + void GetSymbolReferences(); void Cancel(); - void RequestFastFinish(); + void RequestFastFinish(); String GetTypeDefList(); String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args); void HandleGeneratorErrors(StringImpl& result); String GetGeneratorTypeDefList(); String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args); String GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args); - String GetTypeDefMatches(const StringImpl& searchSrc); + String GetTypeDefMatches(const StringImpl& searchSrc); void GetTypeDefs(const StringImpl& typeName, Array& typeDefs); - String GetTypeDefInfo(const StringImpl& typeName); + String GetTypeDefInfo(const StringImpl& typeName); int GetTypeId(const StringImpl& typeName); BfType* GetType(const StringImpl& typeName); int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer); - String GetEmitLocation(const StringImpl& typeName, int line, int& outEmbedLine, int& outEmbedLineChar); + String GetEmitLocation(const StringImpl& typeName, int line, int& outEmbedLine, int& outEmbedLineChar, uint64& outHash); bool WriteEmitData(const StringImpl& filePath, BfProject* project); void CompileLog(const char* fmt ...); @@ -560,4 +561,3 @@ public: }; NS_BF_END - diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index 300b0db9..0a92b9aa 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -64,25 +64,25 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo // Dot-initialized if (memberRefExpr->mTarget == NULL) arraySize = (int)invocationExpr->mArguments.size(); - } + } else if (auto indexerExpr = BfNodeDynCast(invocationExpr->mTarget)) { if (indexerExpr->mArguments.size() == 0) { // Inferred-type sized array initializer arraySize = (int)invocationExpr->mArguments.size(); - } + } } } } if (arraySize != -1) - { + { mResult = BfTypedValue(mModule->GetConstValue(arraySize), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); return mResult; } else - { + { mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_IntPtr)), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); return mResult; } @@ -103,16 +103,16 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo } SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites); - + auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock(); mNoBind = true; if (wantType != NULL) mExpectingType = wantType; VisitChildNoRef(expr); - + mResult = GetResult(); - + auto compilerVal = mModule->GetCompilerFieldValue(mResult); if (compilerVal) mResult = compilerVal; @@ -131,14 +131,14 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo (toType == mResult.mType))) { auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue); - + if (constant->mTypeCode == BfTypeCode_NullPtr) { return mModule->GetDefaultTypedValue(toType); } else { - int stringId = mModule->GetStringPoolIdx(mResult.mValue); + int stringId = mModule->GetStringPoolIdx(mResult.mValue); if (stringId != -1) { if ((flags & BfConstResolveFlag_ActualizeValues) != 0) @@ -166,9 +166,9 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo mResult = convValue; } else - { + { mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None))); - } + } } if (mResult.mKind == BfTypedValueKind_GenericConstValue) @@ -195,9 +195,9 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo isConst = false; } } - + if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0)) - { + { mModule->Fail("Expression does not evaluate to a constant value", expr); if (wantType != NULL) @@ -210,7 +210,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo { if (wantType != NULL) mResult = mModule->GetDefaultTypedValue(wantType); - } + } if (prevInsertBlock) mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); @@ -221,7 +221,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); }*/ - mModule->FixIntUnknown(mResult); + mModule->FixIntUnknown(mResult); if ((flags & BfConstResolveFlag_NoActualizeValues) == 0) { @@ -240,10 +240,10 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch int extendedParamIdx = 0; SetAndRestoreValue ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); - + llvm::SmallVector expandedParamsConstValues; BfType* expandedParamsElementType = NULL; - + // We don't do GetMethodInstance in mModule, because our module may not have init finished yet //auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule; auto targetModule = mModule->mContext->mUnreifiedModule; @@ -260,7 +260,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch auto& arguments = methodMatcher->mArguments; mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); - for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) + for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) { auto paramType = methodInstance->GetParamType(paramIdx); mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); @@ -271,7 +271,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch if (paramIdx >= (int)methodInstance->GetParamCount()) { if (argIdx < (int)arguments.size()) - { + { BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression; if (errorRef->GetSourceData() == NULL) errorRef = targetSrc; @@ -281,7 +281,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch return false; } break; - } + } BfType* wantType = NULL; if (expandedParamsElementType != NULL) @@ -351,7 +351,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch if (attributeDirective->mCtorCloseParen != NULL) refNode = attributeDirective->mCtorCloseParen; } - } + } auto autoComplete = GetAutoComplete(); if (autoComplete != NULL) @@ -361,14 +361,14 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch autoComplete->CheckEmptyStart(prevNode, wantType); } } - + if (mModule->PreFail()) mModule->Fail(StrFormat("Not enough parameters specified. Expected %d more.", methodInstance->GetParamCount() - (int)arguments.size()), refNode); return false; } auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx]; - auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue); + auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue); argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType); } @@ -387,7 +387,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch arg.mArgFlags = BfArgFlag_None; } } - + if (!argValue) return BfTypedValue(); @@ -410,14 +410,14 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch extendedParamIdx++; } else - { + { bool requiresConst = false; if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin)) requiresConst = true; if ((requiresConst) && (argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType())) - { - mModule->Fail("Expression does not evaluate to a constant value", argExpr); + { + mModule->Fail("Expression does not evaluate to a constant value", argExpr); } if (!argValue.mType->IsVar()) @@ -433,11 +433,11 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch } if (expandedParamsElementType != NULL) - { + { auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size()); auto constArray = mModule->mBfIRBuilder->CreateConstAgg(arrayType, expandedParamsConstValues); llvmArgs.push_back(constArray); - } + } return true; } \ No newline at end of file diff --git a/IDEHelper/Compiler/BfConstResolver.h b/IDEHelper/Compiler/BfConstResolver.h index 0f988c77..7f5efd60 100644 --- a/IDEHelper/Compiler/BfConstResolver.h +++ b/IDEHelper/Compiler/BfConstResolver.h @@ -24,13 +24,13 @@ enum BfConstResolveFlags class BfConstResolver : public BfExprEvaluator { public: - bool mIsInvalidConstExpr; + bool mIsInvalidConstExpr; public: virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode) override; public: - BfConstResolver(BfModule* bfModule); + BfConstResolver(BfModule* bfModule); BfTypedValue Resolve(BfExpression* expr, BfType* wantType = NULL, BfConstResolveFlags flags = BfConstResolveFlag_None); bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array& llvmArgs); diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 1ba7550d..85068be0 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -37,9 +37,9 @@ BfContext::BfContext(BfCompiler* compiler) : mTypeDefTypeRefPool(true, true) { mCompiler = compiler; - mSystem = compiler->mSystem; - mBfTypeType = NULL; - mBfClassVDataPtrType = NULL; + mSystem = compiler->mSystem; + mBfTypeType = NULL; + mBfClassVDataPtrType = NULL; mBfObjectType = NULL; mCanSkipObjectCtor = true; mCanSkipValueTypeCtor = true; @@ -53,7 +53,7 @@ BfContext::BfContext(BfCompiler* compiler) : mCurConstraintState = NULL; mResolvingVarField = false; mAssertOnPopulateType = false; - + for (int i = 0; i < BfTypeCode_Length; i++) { mPrimitiveTypes[i] = NULL; @@ -65,14 +65,14 @@ BfContext::BfContext(BfCompiler* compiler) : mScratchModule->mIsScratchModule = true; mScratchModule->mIsReified = true; mScratchModule->mGeneratesCode = false; - mScratchModule->Init(); + mScratchModule->Init(); mUnreifiedModule = new BfModule(this, ""); - mUnreifiedModule->mIsSpecialModule = true; + mUnreifiedModule->mIsSpecialModule = true; mUnreifiedModule->mIsScratchModule = true; mUnreifiedModule->mIsReified = false; mUnreifiedModule->mGeneratesCode = false; - mUnreifiedModule->Init(); + mUnreifiedModule->Init(); mValueTypeDeinitSentinel = (BfMethodInstance*)1; @@ -83,7 +83,7 @@ BfContext::BfContext(BfCompiler* compiler) : void BfReportMemory(); BfContext::~BfContext() -{ +{ BfLogSysM("Deleting Context...\n"); mDeleting = true; @@ -96,21 +96,21 @@ BfContext::~BfContext() int numTypesDeleted = 0; for (auto type : mResolvedTypes) - { + { //_CrtCheckMemory(); delete type; - } - + } + delete mScratchModule; delete mUnreifiedModule; for (auto module : mModules) delete module; - + BfReportMemory(); } void BfContext::ReportMemory(MemReporter* memReporter) -{ +{ memReporter->Add(sizeof(BfContext)); } @@ -124,7 +124,7 @@ void BfContext::ProcessMethod(BfMethodInstance* methodInstance) defModule = mUnreifiedModule; auto typeInst = methodInstance->GetOwner(); - defModule->ProcessMethod(methodInstance); + defModule->ProcessMethod(methodInstance); mCompiler->mStats.mMethodsProcessed++; if (!methodInstance->mIsReified) mCompiler->mStats.mUnreifiedMethodsProcessed++; @@ -133,7 +133,7 @@ void BfContext::ProcessMethod(BfMethodInstance* methodInstance) int BfContext::GetStringLiteralId(const StringImpl& str) { - // Note: We do need string pooling in resolve, for intrinsic names and such + // Note: We do need string pooling in resolve, for intrinsic names and such int* idPtr = NULL; if (mStringObjectPool.TryGetValue(str, &idPtr)) @@ -174,15 +174,15 @@ void BfContext::AssignModule(BfType* type) BfTypeProcessRequest* typeProcessEntry = mPopulateTypeWorkList.Alloc(); typeProcessEntry->mType = type; BF_ASSERT(typeProcessEntry->mType->mContext == this); - BfLogSysM("HandleTypeWorkItem: %p -> %p\n", type, typeProcessEntry->mType); + BfLogSysM("HandleTypeWorkItem: %p -> %p\n", type, typeProcessEntry->mType); mCompiler->mStats.mTypesQueued++; - mCompiler->UpdateCompletion(); + mCompiler->UpdateCompletion(); } else { auto typeInst = type->ToTypeInstance(); BF_ASSERT(typeInst != NULL); - + auto project = typeInst->mTypeDef->mProject; if ((project->mSingleModule) && (typeInst->mIsReified)) { @@ -200,7 +200,7 @@ void BfContext::AssignModule(BfType* type) needsModuleInit = true; } else - { + { module = *modulePtr; typeInst->mModule = module; } @@ -210,7 +210,7 @@ void BfContext::AssignModule(BfType* type) StringT<256> moduleName; GenerateModuleName(typeInst, moduleName); module = new BfModule(this, moduleName); - module->mIsReified = typeInst->mIsReified; + module->mIsReified = typeInst->mIsReified; module->mProject = project; typeInst->mModule = module; BF_ASSERT(!mLockModules); @@ -235,7 +235,7 @@ void BfContext::AssignModule(BfType* type) } void BfContext::HandleTypeWorkItem(BfType* type) -{ +{ AssignModule(type); } @@ -251,7 +251,7 @@ void BfContext::EnsureHotMangledVirtualMethodNames() BP_ZONE("BfContext::EnsureHotMangledVirtualMethodNames"); for (auto type : mResolvedTypes) - { + { auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) continue; @@ -322,11 +322,11 @@ void BfContext::CancelWorkItems() BfLogSysM("BfContext::CancelWorkItems\n"); for (int workIdx = 0; workIdx < (int)mMethodSpecializationWorkList.size(); workIdx++) - { + { auto workItemRef = mMethodSpecializationWorkList[workIdx]; - if (workItemRef != NULL) - workItemRef->mFromModule->mHadBuildError = true; - workIdx = mMethodSpecializationWorkList.RemoveAt(workIdx); + if (workItemRef != NULL) + workItemRef->mFromModule->mHadBuildError = true; + workIdx = mMethodSpecializationWorkList.RemoveAt(workIdx); } mMethodSpecializationWorkList.Clear(); @@ -350,24 +350,24 @@ void BfContext::CancelWorkItems() } bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) -{ - bool didAnyWork = false; +{ + bool didAnyWork = false; while (!mCompiler->mCanceling) - { + { BfParser* resolveParser = NULL; if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mParsers.IsEmpty())) resolveParser = mCompiler->mResolvePassData->mParsers[0]; - bool didWork = false; - + bool didWork = false; + //for (auto itr = mReifyModuleWorkList.begin(); itr != mReifyModuleWorkList.end(); ) for (int workIdx = 0; workIdx < mReifyModuleWorkList.size(); workIdx++) { - BP_ZONE("PWL_ReifyModule"); + BP_ZONE("PWL_ReifyModule"); if (IsCancellingAndYield()) - break; - + break; + BfModule* module = mReifyModuleWorkList[workIdx]; if (module == NULL) { @@ -382,7 +382,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) didWork = true; } - + // Do this before mPopulateTypeWorkList so we can populate any types that need rebuilding // in the mPopulateTypeWorkList loop next - this is required for mFinishedModuleWorkList handling for (int workIdx = 0; workIdx < (int)mMidCompileWorkList.size(); workIdx++) @@ -424,7 +424,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) { //BP_ZONE("PWL_PopulateType"); if (IsCancellingAndYield()) - break; + break; auto workItemRef = mPopulateTypeWorkList[workIdx]; if (workItemRef == NULL) @@ -437,25 +437,25 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) bool rebuildType = workItemRef->mRebuildType; if ((onlyReifiedTypes) && (!type->IsReified())) - { + { continue; } auto typeInst = type->ToTypeInstance(); if ((typeInst != NULL) && (resolveParser != NULL)) - { + { if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser)) - { + { continue; } - } - + } + workIdx = mPopulateTypeWorkList.RemoveAt(workIdx); - + if (rebuildType) RebuildType(type); - BF_ASSERT(this == type->mContext); + BF_ASSERT(this == type->mContext); auto useModule = type->GetModule(); if (useModule == NULL) { @@ -469,7 +469,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) mCompiler->mStats.mQueuedTypesProcessed++; mCompiler->UpdateCompletion(); didWork = true; - } + } for (int workIdx = 0; workIdx < (int)mTypeRefVerifyWorkList.size(); workIdx++) { @@ -481,7 +481,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) { workIdx = mTypeRefVerifyWorkList.RemoveAt(workIdx); continue; - } + } SetAndRestoreValue prevTypeInstance(workItemRef->mFromModule->mCurTypeInstance, workItemRef->mCurTypeInstance); @@ -508,14 +508,14 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) { if (IsCancellingAndYield()) break; - + auto workItemRef = mMethodSpecializationWorkList[workIdx]; if ((workItemRef == NULL) || (!IsWorkItemValid(workItemRef))) { workIdx = mMethodSpecializationWorkList.RemoveAt(workIdx); continue; } - + if (wantsReified != workItemRef->mFromModule->mIsReified) continue; @@ -523,9 +523,9 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) auto module = workItemRef->mFromModule; workIdx = mMethodSpecializationWorkList.RemoveAt(workIdx); - + auto typeInst = methodSpecializationRequest.mType->ToTypeInstance(); - + if (typeInst->IsDeleting()) continue; @@ -551,14 +551,14 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) for (int workIdx = 0; workIdx < mMethodWorkList.size(); workIdx++) { - BP_ZONE("PWL_ProcessMethod"); - + BP_ZONE("PWL_ProcessMethod"); + mSystem->CheckLockYield(); - // Don't allow canceling out of the first pass - otherwise we'll just keep reprocessing the + // Don't allow canceling out of the first pass - otherwise we'll just keep reprocessing the // head of the file over and over if ((resolveParser == NULL) && (mCompiler->mCanceling)) - break; - + break; + auto workItem = mMethodWorkList[workIdx]; if (workItem == NULL) { @@ -569,19 +569,19 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) intptr prevPopulateTypeWorkListSize = mPopulateTypeWorkList.size(); intptr prevInlineMethodWorkListSize = mInlineMethodWorkList.size(); - auto module = workItem->mFromModule; + auto module = workItem->mFromModule; auto methodInstance = workItem->mMethodInstance; - + bool wantProcessMethod = methodInstance != NULL; if ((workItem->mFromModuleRebuildIdx != -1) && (workItem->mFromModuleRebuildIdx != module->mRebuildIdx)) wantProcessMethod = false; else if (workItem->mType->IsDeleting()) wantProcessMethod = false; - if (!IsWorkItemValid(workItem)) + else if (!IsWorkItemValid(workItem)) wantProcessMethod = false; if (methodInstance != NULL) BF_ASSERT(methodInstance->mMethodProcessRequest == workItem); - + bool hasBeenProcessed = true; if (wantProcessMethod) { @@ -592,6 +592,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) auto owner = methodInstance->mMethodInstanceGroup->mOwner; + auto autoComplete = mCompiler->GetAutoComplete(); + BF_ASSERT(!module->mAwaitingFinish); if ((resolveParser != NULL) && (methodInstance->mMethodDef->mDeclaringType != NULL) && (methodInstance->mMethodDef->mDeclaringType->GetDefinition()->mSource != resolveParser)) { @@ -599,13 +601,46 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mHasCursorIdx)) { auto parser = methodInstance->mMethodDef->mDeclaringType->GetLastSource()->ToParser(); + + if ((parser != NULL) && (autoComplete != NULL) && (autoComplete->mModule == NULL)) + { + bool emitHasCursor = false; + for (auto& checkEntry : mCompiler->mResolvePassData->mEmitEmbedEntries) + { + if (checkEntry.mValue.mCursorIdx >= 0) + emitHasCursor = true; + } + + if (emitHasCursor) + { + // Go To Definition in an emit mixin? + BfParser** foundParserPtr = NULL; + if (mCompiler->mResolvePassData->mCompatParserMap.TryAdd(parser, NULL, &foundParserPtr)) + { + *foundParserPtr = NULL; + for (auto checkParser : mCompiler->mResolvePassData->mParsers) + { + if ((checkParser->mFileName == parser->mFileName) && (checkParser->mOrigSrcLength == parser->mOrigSrcLength) && + (memcmp(checkParser->mSrc, parser->mSrc, checkParser->mOrigSrcLength) == 0)) + { + *foundParserPtr = checkParser; + } + } + } + + auto* compatParser = *foundParserPtr; + if (compatParser != NULL) + allow = true; + } + } + if ((parser != NULL) && (parser->mCursorIdx >= 0)) allow = true; } if (!allow) continue; } - + hasBeenProcessed = methodInstance->mHasBeenProcessed; BF_ASSERT(module->mContext == this); @@ -617,30 +652,29 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) if (!mCompiler->mIsResolveOnly) BF_ASSERT(!methodInstance->mIsReified || methodInstance->mDeclModule->mIsModuleMutable); - auto autoComplete = mCompiler->GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->mModule == NULL)) { - autoComplete->mModule = methodInstance->mDeclModule; + autoComplete->SetModule(methodInstance->mDeclModule); ProcessMethod(methodInstance); - autoComplete->mModule = NULL; + autoComplete->SetModule(NULL); } else ProcessMethod(methodInstance); } } - + workIdx = mMethodWorkList.RemoveAt(workIdx); - + if (methodInstance != NULL) methodInstance->mMethodProcessRequest = NULL; if ((!module->mAwaitingFinish) && (module->WantsFinishModule()) && (wantProcessMethod)) - { - BfLogSysM("Module finished: %p %s HadBuildErrors:%d\n", module, module->mModuleName.c_str(), module->mHadBuildError); - QueueFinishModule(module); + { + BfLogSysM("Module finished: %p %s HadBuildErrors:%d\n", module, module->mModuleName.c_str(), module->mHadBuildError); + QueueFinishModule(module); } - didWork = true; + didWork = true; } // for (int workIdx = 0; workIdx < (int)mFinishedSlotAwaitModuleWorkList.size(); workIdx++) @@ -651,13 +685,13 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) // workIdx = mFinishedSlotAwaitModuleWorkList.RemoveAt(workIdx); // continue; // } -// +// // auto module = moduleRef; // if (mCompiler->mMaxInterfaceSlots >= 0) -// { +// { // mFinishedModuleWorkList.Add(module); // } -// +// // workIdx = mFinishedSlotAwaitModuleWorkList.RemoveAt(workIdx); // didWork = true; // } @@ -677,7 +711,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) if (!module->mAwaitingFinish) { BfLogSysM("mFinishedModuleWorkList removing old:%p\n", module); - workIdx = mFinishedModuleWorkList.RemoveAt(workIdx); + workIdx = mFinishedModuleWorkList.RemoveAt(workIdx); continue; } @@ -693,8 +727,8 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) break; } - BP_ZONE("PWL_ProcessFinishedModule"); - + BP_ZONE("PWL_ProcessFinishedModule"); + bool hasUnfinishedSpecModule = false; for (auto& specModulePair : module->mSpecializedMethodModules) { @@ -704,10 +738,10 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) } if (hasUnfinishedSpecModule) - { + { continue; } - + if (!module->mIsSpecialModule) { module->Finish(); @@ -722,10 +756,10 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) for (int workIdx = 0; workIdx < (int)mInlineMethodWorkList.size(); workIdx++) { - BP_ZONE("PWL_ProcessMethod"); + BP_ZONE("PWL_ProcessMethod"); mSystem->CheckLockYield(); - // Don't allow canceling out of the first pass - otherwise we'll just keep reprocessing the + // Don't allow canceling out of the first pass - otherwise we'll just keep reprocessing the // head of the file over and over if ((resolveParser == NULL) && (mCompiler->mCanceling)) break; @@ -737,46 +771,49 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) } auto workItem = *workItemRef; - auto owner = workItem.mMethodInstance->mMethodInstanceGroup->mOwner; auto module = workItem.mFromModule; auto methodInstance = workItem.mMethodInstance; - BF_ASSERT(module->mIsModuleMutable); - module->PrepareForIRWriting(methodInstance->GetOwner()); + bool wantProcessMethod = methodInstance != NULL; + if ((workItem.mFromModuleRebuildIdx != -1) && (workItem.mFromModuleRebuildIdx != module->mRebuildIdx)) + wantProcessMethod = false; + else if (workItem.mType->IsDeleting()) + wantProcessMethod = false; + else if (!IsWorkItemValid(&workItem)) + wantProcessMethod = false; workIdx = mInlineMethodWorkList.RemoveAt(workIdx); - BfLogSysM("Module %p inlining method %p into func:%p\n", module, methodInstance, workItem.mFunc); - - BfMethodInstance dupMethodInstance; - dupMethodInstance.CopyFrom(methodInstance); - dupMethodInstance.mIRFunction = workItem.mFunc; - dupMethodInstance.mIsReified = true; - dupMethodInstance.mInCEMachine = false; // Only have the original one - BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules - - bool wantProcessMethod = true; - if (owner->IsDeleting()) - wantProcessMethod = false; + BfLogSysM("Module %p inlining method %p into func:%p wantProcessMethod:%d\n", module, methodInstance, workItem.mFunc, wantProcessMethod); if (wantProcessMethod) { + BF_ASSERT(module->mIsModuleMutable); + module->PrepareForIRWriting(methodInstance->GetOwner()); + + BfMethodInstance dupMethodInstance; + dupMethodInstance.CopyFrom(methodInstance); + dupMethodInstance.mIRFunction = workItem.mFunc; + dupMethodInstance.mIsReified = true; + dupMethodInstance.mInCEMachine = false; // Only have the original one + BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules + // These errors SHOULD be duplicates, but if we have no other errors at all then we don't ignoreErrors, which // may help unveil some kinds of compiler bugs SetAndRestoreValue prevIgnoreErrors(module->mIgnoreErrors, mCompiler->mPassInstance->HasFailed()); module->ProcessMethod(&dupMethodInstance, true); + + static int sMethodIdx = 0; + module->mBfIRBuilder->Func_SetLinkage(workItem.mFunc, BfIRLinkageType_Internal); } - static int sMethodIdx = 0; - module->mBfIRBuilder->Func_SetLinkage(workItem.mFunc, BfIRLinkageType_Internal); - BF_ASSERT(module->mContext == this); BF_ASSERT(module->mIsModuleMutable); if ((wantProcessMethod) && (!module->mAwaitingFinish) && (module->WantsFinishModule())) { BfLogSysM("Module finished: %s (from inlining)\n", module->mModuleName.c_str()); - QueueFinishModule(module); + QueueFinishModule(module); } didWork = true; @@ -786,7 +823,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) { if ((mPopulateTypeWorkList.size() == 0) && (resolveParser == NULL)) { - BP_ZONE("PWL_CheckIncompleteGenerics"); + BP_ZONE("PWL_CheckIncompleteGenerics"); for (auto type : mResolvedTypes) { @@ -817,7 +854,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) if (!didWork) break; didAnyWork = true; - } + } return didAnyWork; } @@ -831,9 +868,9 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp return; if (typeDef->mDefState != BfTypeDef::DefState_Defined) - { - if (mCompiler->mResolvePassData->mIsClassifying) - { + { + if (mCompiler->mResolvePassData->mIsClassifying) + { auto _CheckSource = [&](BfTypeDef* checkTypeDef) { auto typeDecl = checkTypeDef->mTypeDeclaration; @@ -844,7 +881,7 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(typeDecl)) { - SetAndRestoreValue prevSkipTypeDeclaration(sourceClassifier->mSkipTypeDeclarations, true); + SetAndRestoreValue prevSkipTypeDeclaration(sourceClassifier->mSkipTypeDeclarations, true); sourceClassifier->mSkipMethodInternals = isAutoCompleteTempType; sourceClassifier->Handle(typeDecl); } @@ -858,8 +895,8 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp else { _CheckSource(typeDef); - } - } + } + } } if ((!typeDef->mIsPartial) && (!isAutoCompleteTempType)) @@ -876,7 +913,7 @@ void BfContext::HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTemp BfType * BfContext::FindTypeById(int typeId) { for (auto type : mResolvedTypes) - { + { if (type->mTypeId == typeId) return type; } @@ -890,7 +927,7 @@ void BfContext::AddTypeToWorkList(BfType* type) BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_InTempPool) == 0); if ((type->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0) - { + { type->mRebuildFlags = (BfTypeRebuildFlags)(type->mRebuildFlags | BfTypeRebuildFlag_AddedToWorkList); BfTypeProcessRequest* typeProcessRequest = mPopulateTypeWorkList.Alloc(); @@ -905,22 +942,22 @@ void BfContext::ValidateDependencies() #if _DEBUG // BP_ZONE("BfContext::ValidateDependencies"); // BfLogSysM("ValidateDependencies\n"); -// +// // bool deletedNewTypes = false; -// for (auto type : mResolvedTypes) -// { +// for (auto type : mResolvedTypes) +// { // if (type->IsDeleting()) // continue; -// +// // if (type->IsGenericTypeInstance()) // { // // We can't contain deleted generic arguments without being deleted ourselves // BfTypeInstance* genericType = (BfTypeInstance*)type; -// +// // for (auto genericTypeArg : genericType->mGenericTypeInfo->mTypeGenericArguments) // { // BF_ASSERT((!genericTypeArg->IsDeleting())); -// +// // auto argDepType = genericTypeArg->ToDependedType(); // if (argDepType != NULL) // { @@ -930,22 +967,22 @@ void BfContext::ValidateDependencies() // BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0); // } // } -// } +// } // } #endif } void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuildModule, bool placeSpecializiedInPurgatory) { - BfTypeInstance* typeInst = type->ToTypeInstance(); - + BfTypeInstance* typeInst = type->ToTypeInstance(); + if (type->IsDeleting()) { return; } - + type->mDirty = true; - + bool wantDeleteType = (type->IsOnDemand()) && (deleteOnDemandTypes); if (type->IsConstExprValue()) { @@ -964,17 +1001,20 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild } if (typeInst == NULL) - { + { type->mDefineState = BfTypeDefineState_Undefined; BfTypeProcessRequest* typeProcessRequest = mPopulateTypeWorkList.Alloc(); - typeProcessRequest->mType = type; + typeProcessRequest->mType = type; mCompiler->mStats.mTypesQueued++; mCompiler->UpdateCompletion(); - + return; } + if (mCompiler->mCeMachine != NULL) + mCompiler->mCeMachine->ClearTypeData(typeInst); + BF_ASSERT_REL(typeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting); // We need to verify lookups before we rebuild the type, because a type lookup change needs to count as a TypeDataChanged @@ -992,12 +1032,12 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild } if ((typeInst->IsTypeAlias()) != (typeInst->mTypeDef->mTypeCode == BfTypeCode_TypeAlias)) - { + { BfLogSysM("TypeAlias %p status changed - deleting\n", typeInst); DeleteType(type); - return; + return; } - + if ((typeInst->IsBoxed()) && (typeInst->mTypeDef->mEmitParent != NULL)) typeInst->mTypeDef = typeInst->mTypeDef->mEmitParent; @@ -1010,18 +1050,18 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild { // The type definition failed, so we need to rebuild everyone that was depending on us RebuildDependentTypes(typeInst); - } - + } + if (typeInst->mTypeDef->GetDefinition()->mDefState == BfTypeDef::DefState_Deleted) - return; - + return; + if (typeInst->mDefineState == BfTypeDefineState_Undefined) { // If we haven't added this type the worklist yet then we reprocess the type rebuilding if ((typeInst->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) != 0) - return; - } - + return; + } + if (typeInst->mIsReified) mHasReifiedQueuedRebuildTypes = true; @@ -1033,12 +1073,12 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild mCompiler->mGenericInstancePurgatory.push_back(typeInst); addToWorkList = false; } - + String typeName = mScratchModule->TypeToString(typeInst, BfTypeNameFlags_None); BfLogSysM("%p Rebuild Type: %p %s deleted:%d\n", this, typeInst, typeName.c_str(), typeInst->IsDeleting()); if (addToWorkList) { - AddTypeToWorkList(typeInst); + AddTypeToWorkList(typeInst); } // Why did we need to do this? This caused all struct types to be rebuilt when we needed to rebuild ValueType due to @@ -1055,7 +1095,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild RebuildType(dependentType); } }*/ - + if ((mCompiler->IsHotCompile()) && (!typeInst->IsTypeAlias())) { BF_ASSERT(typeInst->mHotTypeData != NULL); @@ -1076,7 +1116,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild typeInst->mHotTypeData = NULL; } - auto typeDef = typeInst->mTypeDef; + auto typeDef = typeInst->mTypeDef; // Process deps before clearing mMethodInstanceGroups, to make sure we delete any methodrefs pointing to us before // deleting those methods @@ -1100,7 +1140,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild { // Rebuild undefined type. This isn't necessary when we modify the typeDef, but when we change configurations then // the specialized types will rebuild - + //TODO: WE just added "no rebuild module" to this. I'm not sure what this is all about anyway... RebuildType(depType, true, false); } @@ -1127,7 +1167,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild auto methodInstance = methodSpecializationItr.mValue; if ((!methodInstance->mIsUnspecialized) && (methodInstance->mHasFailed)) { - // A specialized generic method has failed, but the unspecialized version did not. This + // A specialized generic method has failed, but the unspecialized version did not. This // can only happen for 'var' constrained methods, and we need to cause all referring // types to rebuild to ensure we're really specializing only the correct methods needMethodCallsRebuild = true; @@ -1136,14 +1176,14 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild } } if (needMethodCallsRebuild) - { - TypeMethodSignaturesChanged(typeInst); + { + TypeMethodSignaturesChanged(typeInst); } } } typeInst->ReleaseData(); - type->mDefineState = BfTypeDefineState_Undefined; + type->mDefineState = BfTypeDefineState_Undefined; typeInst->mSpecializedMethodReferences.Clear(); typeInst->mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None; typeInst->mHasBeenInstantiated = false; @@ -1161,21 +1201,24 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild typeInst->mHasBeenInstantiated = false; typeInst->mHasParameterizedBase = false; typeInst->mTypeFailed = false; - typeInst->mTypeWarned = false; + typeInst->mTypeWarned = false; typeInst->mHasUnderlyingArray = false; - typeInst->mHasPackingHoles = false; + typeInst->mHasPackingHoles = false; typeInst->mWantsGCMarking = false; typeInst->mHasDeclError = false; delete typeInst->mTypeInfoEx; typeInst->mTypeInfoEx = NULL; - + if (typeInst->mCeTypeInfo != NULL) typeInst->mCeTypeInfo->mRebuildMap.Clear(); if (typeInst->mTypeDef->mEmitParent != NULL) { - auto emitTypeDef = typeInst->mTypeDef; - typeInst->mTypeDef = emitTypeDef->mEmitParent; + auto emitTypeDef = typeInst->mTypeDef; + typeInst->mTypeDef = emitTypeDef->mEmitParent; + if (typeInst->mTypeDef->mIsPartial) + typeInst->mTypeDef = mSystem->GetCombinedPartial(typeInst->mTypeDef); + BfLogSysM("Type %p queueing delete of typeDef %p, resetting typeDef to %p\n", typeInst, emitTypeDef, typeInst->mTypeDef); if (emitTypeDef->mDefState != BfTypeDef::DefState_Deleted) { @@ -1192,7 +1235,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild RebuildType(typeInst); } } - } + } } //typeInst->mTypeDef->ClearEmitted(); @@ -1213,7 +1256,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild if (genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo != NULL) genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo->Clear(); genericTypeInstance->mGenericTypeInfo->mProjectsReferenced.Clear(); - } + } typeInst->mStaticSearchMap.Clear(); typeInst->mInternalAccessMap.Clear(); @@ -1235,7 +1278,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild delete typeInst->mCustomAttributes; typeInst->mCustomAttributes = NULL; delete typeInst->mAttributeData; - typeInst->mAttributeData = NULL; + typeInst->mAttributeData = NULL; typeInst->mVirtualMethodTableSize = 0; typeInst->mVirtualMethodTable.Clear(); typeInst->mReifyMethodDependencies.Clear(); @@ -1249,9 +1292,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild if ((typeInst->mModule != NULL) && (rebuildModule)) { - typeInst->mModule->StartNewRevision(); + typeInst->mModule->StartNewRevision(); typeInst->mRevision = mCompiler->mRevision; - } + } } void BfContext::RebuildDependentTypes(BfDependedType* dType) @@ -1280,7 +1323,7 @@ void BfContext::RebuildDependentTypes_MidCompile(BfDependedType* dType, const St BF_ASSERT(!module->mIsDeleting); BF_ASSERT(!module->mOwnedTypeInstances.IsEmpty()); } - + mCompiler->mStats.mMidCompileRebuilds++; dType->mRebuildFlags = (BfTypeRebuildFlags)(dType->mRebuildFlags | BfTypeRebuildFlag_ChangedMidCompile); int prevDeletedTypes = mCompiler->mStats.mTypesDeleted; @@ -1295,13 +1338,12 @@ void BfContext::RebuildDependentTypes_MidCompile(BfDependedType* dType, const St mCompiler->mNeedsFullRefresh = true; mCompiler->mLastMidCompileRefreshRevision = mCompiler->mRevision; } - } BfLogSysM("Rebuilding dependent types MidCompile Type:%p Reason:%s\n", dType, reason.c_str()); RebuildDependentTypes(dType); if (mCompiler->mStats.mTypesDeleted != prevDeletedTypes) - { + { BfLogSysM("Rebuilding dependent types MidCompile Type:%p Reason:%s - updating after deleting types\n", dType, reason.c_str()); UpdateAfterDeletingTypes(); } @@ -1328,20 +1370,20 @@ bool BfContext::CanRebuild(BfType* type) // (obviously) doesn't change the data layout of ClassC // Calls: non-cascading dependency, since it's independent of data layout ConstValue: non-cascading data change void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange) -{ +{ BfLogSysM("TypeDataChanged %p\n", dType); - + auto rebuildFlag = isNonStaticDataChange ? BfTypeRebuildFlag_NonStaticChange : BfTypeRebuildFlag_StaticChange; if ((dType->mRebuildFlags & rebuildFlag) != 0) // Already did this change? return; dType->mRebuildFlags = (BfTypeRebuildFlags)(dType->mRebuildFlags | rebuildFlag); - + // We need to rebuild all other types that rely on our data layout for (auto& depItr : dType->mDependencyMap) { auto dependentType = depItr.mKey; auto dependencyFlags = depItr.mValue.mFlags; - + auto dependentDType = dependentType->ToDependedType(); if (dependentDType != NULL) { @@ -1350,16 +1392,16 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang { bool hadChange = false; - if ((dependencyFlags & + if ((dependencyFlags & (BfDependencyMap::DependencyFlag_DerivedFrom | BfDependencyMap::DependencyFlag_ValueTypeMemberData | BfDependencyMap::DependencyFlag_NameReference | BfDependencyMap::DependencyFlag_ValueTypeSizeDep)) != 0) { - hadChange = true; + hadChange = true; } - // This case is for when we were declared as a class on a previous compilation, + // This case is for when we were declared as a class on a previous compilation, // but then we were changed to a struct if ((dType->IsValueType()) && (dependencyFlags & BfDependencyMap::DependencyFlag_PtrMemberData)) @@ -1383,15 +1425,15 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang if (dependencyFlags & BfDependencyMap::DependencyFlag_ConstValue) { TypeDataChanged(dependentDType, false); - + // The ConstValue dependency may be that dependentType used one of our consts as // a default value to a method param, so assume callsites need rebuilding if (dependentTypeInstance != NULL) TypeMethodSignaturesChanged(dependentTypeInstance); } - if (CanRebuild(dependentType)) - { + if (CanRebuild(dependentType)) + { // We need to include DependencyFlag_ParamOrReturnValue because it could be a struct that changes its splatting ability // We can't ONLY check against structs, though, because a type could change from a class to a struct if (dependencyFlags & @@ -1401,7 +1443,7 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang { RebuildType(dependentType); } - else if (((dependencyFlags & BfDependencyMap::DependencyFlag_NameReference) != 0) && + else if (((dependencyFlags & BfDependencyMap::DependencyFlag_NameReference) != 0) && ((dType->mRebuildFlags & BfTypeRebuildFlag_ChangedMidCompile) != 0) && (dType->IsTypeAlias())) { @@ -1418,9 +1460,9 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang } } } - + if (CanRebuild(dType)) - RebuildType(dType); + RebuildType(dType); } void BfContext::TypeMethodSignaturesChanged(BfTypeInstance* typeInst) @@ -1464,7 +1506,7 @@ void BfContext::TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst) for (auto& depItr : typeInst->mDependencyMap) { auto dependentType = depItr.mKey; - + auto dependencyFlags = depItr.mValue.mFlags; if (dependentType->mRevision != mCompiler->mRevision) @@ -1521,7 +1563,7 @@ void BfContext::TypeConstEvalFieldChanged(BfTypeInstance* typeInst) { auto dependentType = depItr.mKey; auto dependencyFlags = depItr.mValue.mFlags; - + if ((dependencyFlags & BfDependencyMap::DependencyFlag_ConstEvalConstField) != 0) { auto depTypeInst = dependentType->ToTypeInstance(); @@ -1544,12 +1586,12 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) auto hotTypeData = typeInstance->mHotTypeData; if (hotTypeData == NULL) return; - - if (typeInstance->IsIncomplete()) + + if (typeInstance->IsIncomplete()) return; if (hotTypeData->mVTableOrigLength == -1) - { + { auto committedHotTypeVersion = typeInstance->mHotTypeData->GetTypeVersion(mCompiler->mHotState->mCommittedHotCompileIdx); if (committedHotTypeVersion != NULL) { @@ -1557,7 +1599,7 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) hotTypeData->mOrigInterfaceMethodsLength = typeInstance->GetIFaceVMethodSize(); } BfLogSysM("PopulateHotTypeDataVTable set %p HotDataType->mVTableOrigLength To %d\n", typeInstance, hotTypeData->mVTableOrigLength); - } + } int vTableStart = -1; int primaryVTableSize = 0; @@ -1572,8 +1614,8 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) { auto& methodRef = typeInstance->mVirtualMethodTable[vIdx].mDeclaringMethod; if (methodRef.mMethodNum == -1) - { - BF_DBG_FATAL("Shouldn't have vext marker"); + { + BF_DBG_FATAL("Shouldn't have vext marker"); } } #endif @@ -1600,11 +1642,11 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) primaryVTableSize = (int)typeInstance->mVirtualMethodTable.size() - vTableStart; BF_ASSERT(vTableStart != -1); - + if (primaryVTableSize > (int)hotTypeData->mVTableEntries.size()) hotTypeData->mVTableEntries.Resize(primaryVTableSize); - int methodIdx = -1; + int methodIdx = -1; for (int vIdx = 0; vIdx < primaryVTableSize; vIdx++) { auto& methodRef = typeInstance->mVirtualMethodTable[vTableStart + vIdx].mDeclaringMethod; @@ -1612,7 +1654,7 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) auto methodInstance = (BfMethodInstance*)methodRef; if (methodInstance == NULL) continue; - + BF_ASSERT(methodRef.mTypeInstance == typeInstance); BF_ASSERT(methodInstance->mVirtualTableIdx != -1); BF_ASSERT(!methodInstance->mMethodDef->mIsOverride); @@ -1630,7 +1672,7 @@ void BfContext::PopulateHotTypeDataVTable(BfTypeInstance* typeInstance) auto& entry = hotTypeData->mVTableEntries[vIdx]; if (entry.mFuncName.empty()) - { + { entry.mFuncName = methodInstance->mMethodInfoEx->mMangledName; } else @@ -1663,7 +1705,7 @@ void BfContext::SaveDeletingType(BfType* type) else { // This can happen if we have a conflicting type definition - savedTypeData = *savedTypeDataPtr; + savedTypeData = *savedTypeDataPtr; } savedTypeData->mTypeId = type->mTypeId; while ((int)mSavedTypeData.size() <= savedTypeData->mTypeId) @@ -1672,7 +1714,7 @@ void BfContext::SaveDeletingType(BfType* type) auto typeInst = type->ToTypeInstance(); if (typeInst != NULL) - { + { delete savedTypeData->mHotTypeData; if (mCompiler->IsHotCompile()) savedTypeData->mHotTypeData = typeInst->mHotTypeData; @@ -1762,13 +1804,13 @@ void BfContext::ReflectInit() void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) { if (type == mBfObjectType) - mBfObjectType = NULL; - if (type == mBfTypeType) + mBfObjectType = NULL; + if (type == mBfTypeType) mBfObjectType = NULL; if (type->mRebuildFlags & BfTypeRebuildFlag_Deleted) - return; - + return; + mCompiler->mDepsMayHaveDeletedTypes = true; mCompiler->mStats.mTypesDeleted++; @@ -1794,7 +1836,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) BF_ASSERT(module->mOwnedTypeInstances.size() == 0); } else - { + { module->mOwnedTypeInstances.Remove(typeInst); if ((module->mOwnedTypeInstances.size() == 0) && (module != mScratchModule)) @@ -1805,22 +1847,22 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) module->RemoveModuleData(); module->mIsDeleting = true; mModules.Remove(module); - + // This was only needed for 'zombie modules', which we don't need anymore? // To avoid linking errors. Used instead of directly removing from mModules. mDeletingModules.Add(module); } } } - } + } type->mRebuildFlags = (BfTypeRebuildFlags)((type->mRebuildFlags | BfTypeRebuildFlag_Deleted) & ~BfTypeRebuildFlag_DeleteQueued); SaveDeletingType(type); - + mTypes[type->mTypeId] = NULL; BfLogSysM("Deleting Type: %p %s\n", type, mScratchModule->TypeToString(type).c_str()); - + if (typeInst != NULL) { for (auto& methodInstGroup : typeInst->mMethodInstanceGroups) @@ -1839,28 +1881,28 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) } } - // All dependencies cause rebuilds when we delete types + // All dependencies cause rebuilds when we delete types if (dType != NULL) { //TODO: Do PopulateHotTypeDataVTable then store the HotTypeDataData - + if (dType->IsUnspecializedType()) - { + { /*auto itr = mScratchModule->mClassVDataRefs.find(typeInst); if (itr != mScratchModule->mClassVDataRefs.end()) mScratchModule->mClassVDataRefs.erase(itr);*/ - + mScratchModule->mClassVDataRefs.Remove(typeInst); - } - + } + //UH - I think this is not true. // If A derives from B, and C derives from B, if we delete 'A' then it's true that // 'C' won't rebuild otherwise, BUT 'B' would fail to build but it would do a TypeDataChanged once it WAS able to built. Right? // Even though we do rebuilds on all types below, we specifically need to call - // TypeDataChanged here for cascading data dependencies + // TypeDataChanged here for cascading data dependencies /*if (!deferDepRebuilds) TypeDataChanged(typeInst, true);*/ - + Array rebuildTypeQueue; for (auto& depItr : dType->mDependencyMap) @@ -1873,7 +1915,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) if ((dependencyEntry.mFlags & (BfDependencyMap::DependencyFlag_MethodGenericArg)) != 0) { if (!dependentType->IsDeleting()) - { + { if ((deferDepRebuilds) && (dependentTypeInst != NULL)) mQueuedSpecializedMethodRebuildTypes.Add(dependentTypeInst); } @@ -1885,7 +1927,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) DeleteType(dependentType, deferDepRebuilds); continue; } - + if (dependentTypeInst == NULL) { // This was something like a sized array @@ -1910,15 +1952,17 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) } if ((deferDepRebuilds) && (dependentTypeInst != NULL)) - mFailTypes.Add(dependentTypeInst); + { + mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal); + } else { rebuildTypeQueue.Add(dependentType); } - } + } if (type->IsMethodRef()) - { + { // Detach auto methodRefType = (BfMethodRefType*)type; BfMethodInstance* methodInstance = methodRefType->mMethodRef; @@ -1933,15 +1977,15 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) if (CanRebuild(dependentType)) RebuildType(dependentType); } - } + } } void BfContext::UpdateAfterDeletingTypes() { BP_ZONE("BfContext::UpdateAfterDeletingTypes"); BfLogSysM("UpdateAfterDeletingTypes\n"); - - int graveyardStart = (int)mTypeGraveyard.size(); + + int graveyardStart = (int)mTypeGraveyard.size(); while (true) { @@ -1962,11 +2006,11 @@ void BfContext::UpdateAfterDeletingTypes() deletedNewTypes = true; isDeleting = true; DeleteType(type); - } + } } if (isDeleting) - { + { doDelete = true; } else @@ -2017,14 +2061,14 @@ void BfContext::UpdateAfterDeletingTypes() // ++itr; // } #endif - + if (!mCompiler->mIsResolveOnly) { BP_ZONE("BfContext::UpdateAfterDeletingTypes saving typeData"); for (int graveyardIdx = graveyardStart; graveyardIdx < (int)mTypeGraveyard.size(); graveyardIdx++) { - auto type = mTypeGraveyard[graveyardIdx]; - SaveDeletingType(type); + auto type = mTypeGraveyard[graveyardIdx]; + SaveDeletingType(type); } } } @@ -2040,22 +2084,21 @@ void BfContext::PreUpdateRevisedTypes() // auto typeInst = type->ToTypeInstance(); // if (typeInst == NULL) // continue; -// +// // auto typeDef = typeInst->mTypeDef; // if ((typeDef->mDefState != BfTypeDef::DefState_New) && (typeDef->mDefState != BfTypeDef::DefState_Defined)) // { // if (typeInst->mHotTypeData == NULL) // { -// typeInst->mHotTypeData = new BfHotTypeData(); -// typeInst->CalcHotVirtualData(&typeInst->mHotTypeData->mInterfaceMapping); +// typeInst->mHotTypeData = new BfHotTypeData(); +// typeInst->CalcHotVirtualData(&typeInst->mHotTypeData->mInterfaceMapping); // } // PopulateHotTypeDataVTable(typeInst); // } -// } +// } // } } - // Note that this method can also cause modules to be build in other contexts. // That's why we do our UpdateAfterDeletingTypes after all the contexts' UpdateRevisedTypes void BfContext::UpdateRevisedTypes() @@ -2096,7 +2139,7 @@ void BfContext::UpdateRevisedTypes() { BfTypeDef* typeDef = *itr; if ((typeDef->mDefState != BfTypeDef::DefState_Deleted) && - (!typeDef->mIsCombinedPartial)) + (!typeDef->mIsCombinedPartial)) { if (typeDef->mFullNameEx == qualifiedFindName) if (!_CheckCanSkipCtor(typeDef)) @@ -2107,7 +2150,7 @@ void BfContext::UpdateRevisedTypes() return true; }; - + bool wantsCanSkipObjectCtor = _CheckCanSkipCtorByName("System.Object"); bool wantsCanSkipValueTypeCtor = _CheckCanSkipCtorByName("System.ValueType"); @@ -2129,7 +2172,7 @@ void BfContext::UpdateRevisedTypes() auto uintPtrType = mScratchModule->GetPrimitiveType(BfTypeCode_UIntPtr); if (intPtrType != NULL) { - RebuildType(intPtrType); + RebuildType(intPtrType); mScratchModule->PopulateType(intPtrType); } if (uintPtrType != NULL) @@ -2140,17 +2183,17 @@ void BfContext::UpdateRevisedTypes() // Rebuild all types for (auto type : mResolvedTypes) - { + { RebuildType(type); } } // Temporarily store failTypes - we may need to re-insert into them after another failure auto failTypes = mFailTypes; - mFailTypes.Clear(); + mFailTypes.Clear(); bool wantsDebugInfo = (mCompiler->mOptions.mEmitDebugInfo); - + Array defStateChangedQueue; Array defEmitParentCheckQueue; @@ -2170,22 +2213,22 @@ void BfContext::UpdateRevisedTypes() /*if ((!mCompiler->mIsResolveOnly) && (!type->IsNull()) && (!type->IsUnspecializedType())) { - // We need to completely rebuild all types if we switch from having debug info to not having debug info - if ((typeInst != NULL) && (typeInst->mModule != NULL) && (typeInst->mModule->mHasDebugInfo != wantsDebugInfo)) + // We need to completely rebuild all types if we switch from having debug info to not having debug info + if ((typeInst != NULL) && (typeInst->mModule != NULL) && (typeInst->mModule->mHasDebugInfo != wantsDebugInfo)) { RebuildType(type); } }*/ - + if (typeInst == NULL) continue; - + if (typeInst->IsDeleting()) continue; - auto typeDef = typeInst->mTypeDef; + auto typeDef = typeInst->mTypeDef; - if (typeDef->mEmitParent != NULL) + if (typeDef->mEmitParent != NULL) defEmitParentCheckQueue.Add(typeInst); if (typeDef->mProject->mDisabled) @@ -2193,10 +2236,10 @@ void BfContext::UpdateRevisedTypes() DeleteType(type); continue; } - + // Clear flags we don't want to propagate typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & (BfTypeRebuildFlag_UnderlyingTypeDeferred | BfTypeRebuildFlag_PendingGenericArgDep)); - + if (typeDef->mIsPartial) { // This was a type that wasn't marked as partial before but now it is, so it doesn't need its own typedef @@ -2223,7 +2266,7 @@ void BfContext::UpdateRevisedTypes() if (*valuePtr != kv.mValue.mInt) changed = true; mCompiler->mRebuildFileSet.Add(kv.mKey.mString); - } + } if ((kv.mKey.mKind == CeRebuildKey::Kind_File) || (kv.mKey.mKind == CeRebuildKey::Kind_Directory)) { @@ -2235,7 +2278,8 @@ void BfContext::UpdateRevisedTypes() if (changed) { - RebuildType(typeInst); + TypeDataChanged(typeInst, true); + TypeMethodSignaturesChanged(typeInst); } } @@ -2262,7 +2306,7 @@ void BfContext::UpdateRevisedTypes() if (checkTypeDef->mDefState != BfTypeDef::DefState_New) { - defStateChangedQueue.Add(typeInst); + defStateChangedQueue.Add(typeInst); } } @@ -2275,7 +2319,7 @@ void BfContext::UpdateRevisedTypes() auto typeDef = typeInst->mTypeDef; - bool isTypeDefinedInContext = true; + bool isTypeDefinedInContext = true; if (typeDef->mEmitParent != NULL) { @@ -2283,12 +2327,12 @@ void BfContext::UpdateRevisedTypes() } if (typeDef->mDefState == BfTypeDef::DefState_Deleted) - { + { HandleChangedTypeDef(typeDef); DeleteType(typeInst); continue; } - + if (typeDef->mDefState == BfTypeDef::DefState_InlinedInternals_Changed) { TypeInlineMethodInternalsChanged(typeInst); @@ -2309,7 +2353,7 @@ void BfContext::UpdateRevisedTypes() if (isSignatureChange) { TypeDataChanged(typeInst, true); - TypeMethodSignaturesChanged(typeInst); + TypeMethodSignaturesChanged(typeInst); } /*if (!mCompiler->mIsResolveOnly) @@ -2319,15 +2363,19 @@ void BfContext::UpdateRevisedTypes() RebuildType(typeInst); } - - for (auto typeInst : failTypes) + + for (auto failKV : failTypes) { + auto typeInst = failKV.mKey; if (!typeInst->IsDeleting()) { if (!typeInst->mTypeDef->mProject->mDisabled) { - BfLogSysM("Rebuilding failed type %p\n", typeInst); - RebuildType(typeInst); + BfLogSysM("Rebuilding failed type %p %d\n", typeInst, (int)failKV.mValue); + if (failKV.mValue == BfFailKind_Deep) + TypeDataChanged(typeInst, true); + else + RebuildType(typeInst); } } } @@ -2362,7 +2410,7 @@ void BfContext::UpdateRevisedTypes() AutoCrit autoCrit(mSystem->mDataLock); auto options = &mCompiler->mOptions; - HashContext workspaceConfigHashCtx; + HashContext workspaceConfigHashCtx; workspaceConfigHashCtx.MixinStr(options->mTargetTriple); workspaceConfigHashCtx.MixinStr(options->mTargetCPU); @@ -2370,15 +2418,15 @@ void BfContext::UpdateRevisedTypes() workspaceConfigHashCtx.Mixin(options->mMachineType); workspaceConfigHashCtx.Mixin(options->mToolsetType); - workspaceConfigHashCtx.Mixin(options->mSIMDSetting); + workspaceConfigHashCtx.Mixin(options->mSIMDSetting); workspaceConfigHashCtx.Mixin(options->mEmitDebugInfo); - workspaceConfigHashCtx.Mixin(options->mEmitLineInfo); + workspaceConfigHashCtx.Mixin(options->mEmitLineInfo); workspaceConfigHashCtx.Mixin(options->mNoFramePointerElim); workspaceConfigHashCtx.Mixin(options->mInitLocalVariables); workspaceConfigHashCtx.Mixin(options->mRuntimeChecks); - workspaceConfigHashCtx.Mixin(options->mAllowStructByVal); + workspaceConfigHashCtx.Mixin(options->mAllowStructByVal); workspaceConfigHashCtx.Mixin(options->mEmitDynamicCastCheck); workspaceConfigHashCtx.Mixin(options->mAllowHotSwapping); @@ -2418,7 +2466,7 @@ void BfContext::UpdateRevisedTypes() workspaceConfigHashCtx.Mixin(typeOptions.mOrFlags); workspaceConfigHashCtx.Mixin(typeOptions.mReflectMethodFilters.size()); for (auto& filter : typeOptions.mReflectMethodFilters) - { + { workspaceConfigHashCtx.MixinStr(filter.mFilter); workspaceConfigHashCtx.Mixin(filter.mAndFlags); workspaceConfigHashCtx.Mixin(filter.mOrFlags); @@ -2448,23 +2496,23 @@ void BfContext::UpdateRevisedTypes() mSystem->mMergedTypeOptions.Clear(); mSystem->mWorkspaceConfigHash = workspaceConfigHash; } - + for (auto project : mSystem->mProjects) { HashContext buildConfigHashCtx; buildConfigHashCtx.Mixin(workspaceConfigHash); - + if (!mCompiler->mIsResolveOnly) { - auto& codeGenOptions = project->mCodeGenOptions; - + auto& codeGenOptions = project->mCodeGenOptions; + buildConfigHashCtx.MixinStr(mCompiler->mOutputDirectory); buildConfigHashCtx.Mixin(project->mAlwaysIncludeAll); buildConfigHashCtx.Mixin(project->mSingleModule); bool isTestConfig = project->mTargetType == BfTargetType_BeefTest; buildConfigHashCtx.Mixin(isTestConfig); - + buildConfigHashCtx.Mixin(codeGenOptions.mOptLevel); buildConfigHashCtx.Mixin(codeGenOptions.mSizeLevel); buildConfigHashCtx.Mixin(codeGenOptions.mUseCFLAA); @@ -2510,18 +2558,18 @@ void BfContext::UpdateRevisedTypes() auto vDataConfigHash = vDataConfigHashCtx.Finish128(); project->mBuildConfigChanged = buildConfigHash != project->mBuildConfigHash; - project->mBuildConfigHash = buildConfigHash; + project->mBuildConfigHash = buildConfigHash; project->mVDataConfigHash = vDataConfigHash; } - } - + } + Array moduleRebuildList; for (int moduleIdx = 0; moduleIdx < (int)mModules.size(); moduleIdx++) { //mCompiler->mOutputDirectory auto module = mModules[moduleIdx]; - + // This logic needs to run on both us and our mOptModule //for (int subModuleIdx = 0; subModuleIdx < 2; subModuleIdx++) auto subModule = module; @@ -2553,7 +2601,7 @@ void BfContext::UpdateRevisedTypes() subModule = subModule->mNextAltModule; } - + if ((module->mProject != NULL) && (module->mProject->mDisabled)) { continue; @@ -2567,7 +2615,7 @@ void BfContext::UpdateRevisedTypes() needsModuleRebuild = true; } if (module->mProject != NULL) - { + { if ((module->mIsHotModule) && (mCompiler->mOptions.mHotProject == NULL)) needsModuleRebuild = true; if (module->mProject->mBuildConfigChanged) @@ -2581,11 +2629,11 @@ void BfContext::UpdateRevisedTypes() } if (needsModuleRebuild) - moduleRebuildList.push_back(module); + moduleRebuildList.push_back(module); if (module->mIsSpecialModule) // vdata, external, data continue; - + bool wantMethodSpecializations = !mCompiler->mIsResolveOnly; // We don't really need this on for resolveOnly passes, but this is useful to force on for debugging. @@ -2607,7 +2655,7 @@ void BfContext::UpdateRevisedTypes() if (mSystem->mWorkspaceConfigChanged) { for (auto type : mResolvedTypes) - { + { RebuildType(type); } } @@ -2619,7 +2667,7 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst) { BfTypeLookupEntry& lookupEntry = lookupEntryPair.mKey; bool isDirty = false; - if (lookupEntry.mName.IsEmpty()) + if (lookupEntry.mName.IsEmpty()) { // If the name lookup failed before, thats because we didn't have the right atoms. Are there new atoms now? if (lookupEntry.mAtomUpdateIdx != mSystem->mAtomUpdateIdx) @@ -2629,10 +2677,10 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst) { // If any atoms have been placed in the graveyard, typesHash will be zero and thus cause a rebuild uint32 atomUpdateIdx = lookupEntry.mName.GetAtomUpdateIdx(); - + if (atomUpdateIdx == 0) { - isDirty = true; + isDirty = true; } else { @@ -2665,10 +2713,10 @@ void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst) lookupEntry.mAtomUpdateIdx = atomUpdateIdx; } } - } + } if (isDirty) - { + { // Clear lookup results to avoid infinite recursion typeInst->mLookupResults.Clear(); @@ -2695,7 +2743,7 @@ void BfContext::GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl name += '_';*/ } else - { + { for (int i = 0; i < typeInst->mTypeDef->mNamespace.mSize; i++) { auto atom = typeInst->mTypeDef->mNamespace.mParts[i]; @@ -2715,7 +2763,7 @@ void BfContext::GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl if (typeInst->IsClosure()) { - auto closureType = (BfClosureType*)typeInst; + auto closureType = (BfClosureType*)typeInst; name += closureType->mNameAdd; return; } @@ -2757,14 +2805,14 @@ void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) { auto ptrType = (BfPointerType*)type; name += "PTR_"; - GenerateModuleName_Type(ptrType->mElementType, name); + GenerateModuleName_Type(ptrType->mElementType, name); return; } if (type->IsTuple()) { auto tupleType = (BfTypeInstance*)type; - name += "TUPLE_"; + name += "TUPLE_"; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; @@ -2782,7 +2830,7 @@ void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) auto typeInst = type->ToTypeInstance(); auto delegateInfo = type->GetDelegateInfo(); - auto methodDef = typeInst->mTypeDef->mMethods[0]; + auto methodDef = typeInst->mTypeDef->mMethods[0]; if (type->IsDelegateFromTypeRef()) name += "DELEGATE_"; @@ -2795,7 +2843,7 @@ void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) if (paramIdx > 0) name += "_"; auto paramDef = methodDef->mParams[paramIdx]; - GenerateModuleName_Type(mScratchModule->ResolveTypeRef(paramDef->mTypeRef), name); + GenerateModuleName_Type(mScratchModule->ResolveTypeRef(paramDef->mTypeRef), name); name += "_"; name += paramDef->mName; } @@ -2828,7 +2876,7 @@ void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) else name += StrFormat("%ld", constExprType->mValue.mInt64); return; - } + } } auto typeInst = type->ToTypeInstance(); @@ -2836,11 +2884,11 @@ void BfContext::GenerateModuleName_Type(BfType* type, StringImpl& name) { GenerateModuleName_TypeInst(typeInst, name); return; - } + } } void BfContext::GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name) -{ +{ GenerateModuleName_Type(typeInst, name); int maxChars = 80; @@ -2855,7 +2903,7 @@ void BfContext::GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name) if (c == '@') name[i] = '_'; } - + for (int i = 2; true; i++) { StringT<256> upperName = name; @@ -2879,25 +2927,25 @@ bool BfContext::IsSentinelMethod(BfMethodInstance* methodInstance) void BfContext::VerifyTypeLookups() { - BP_ZONE("BfContext::VerifyTypeLookups"); + BP_ZONE("BfContext::VerifyTypeLookups"); for (auto type : mResolvedTypes) - { + { auto typeInst = type->ToTypeInstance(); if ((typeInst != NULL) && (!typeInst->IsDeleting()) && (!typeInst->IsIncomplete())) { - VerifyTypeLookups(typeInst); + VerifyTypeLookups(typeInst); } } } -// When we are rebuilding 'typeInst' and we want to make sure that we rebuild all the methods that were +// When we are rebuilding 'typeInst' and we want to make sure that we rebuild all the methods that were // actively referenced previously, this method will generate BfMethodSpecializationRequest for all used // methods from previously-built modules void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag) { BF_ASSERT(!typeInst->IsDeleting()); - + BP_ZONE("BfContext::QueueMethodSpecializations"); auto module = typeInst->mModule; @@ -2918,10 +2966,10 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS // modules that are NOT rebuilding to be sure we generate those. Failure to do this // will cause a link error from an old module for (auto& methodRefKV : typeInst->mSpecializedMethodReferences) - { + { auto& methodRef = methodRefKV.mKey; auto& specializedMethodRefInfo = methodRefKV.mValue; - + if (checkSpecializedMethodRebuildFlag) { if ((methodRef.mTypeInstance->mRebuildFlags & BfTypeRebuildFlag_SpecializedMethodRebuild) == 0) @@ -2932,7 +2980,7 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS if ((methodRef.mTypeInstance->mModule == NULL) || (methodRef.mTypeInstance->mModule->mRevision != mCompiler->mRevision)) continue; - } + } bool allowMismatch = false; if ((methodRef.mTypeInstance->IsInstanceOf(mCompiler->mInternalTypeDef)) || (methodRef.mTypeInstance->IsInstanceOf(mCompiler->mGCTypeDef))) @@ -2957,7 +3005,7 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS specializationRequest->mMethodIdx = methodRef.mMethodNum; //specializationRequest->mMethodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum]; specializationRequest->mMethodGenericArguments = methodRef.mMethodGenericArguments; - specializationRequest->mType = methodRef.mTypeInstance; + specializationRequest->mType = methodRef.mTypeInstance; BfLogSysM("QueueMethodSpecializations typeInst %p specializationRequest %p methodDef %p fromModule %p\n", typeInst, specializationRequest, methodDef, specializationRequest->mFromModule); } @@ -3002,27 +3050,49 @@ bool BfContext::IsWorkItemValid(BfWorkListEntry* item) return true; } +bool BfContext::IsWorkItemValid(BfMethodInstance* methodInstance) +{ + if (methodInstance == NULL) + return false; + + for (auto& param : methodInstance->mParams) + { + if (param.mResolvedType->IsDeleting()) + return false; + } + + if (methodInstance->mMethodInfoEx != NULL) + { + for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments) + if (genericArg->IsDeleting()) + return false; + } + + return true; +} + bool BfContext::IsWorkItemValid(BfMethodProcessRequest* item) { // If we had mid-compile rebuilds then we may have deleted types referenced in methods if (mCompiler->mStats.mMidCompileRebuilds == 0) return true; - if (item->mMethodInstance == NULL) + if (!IsWorkItemValid(item->mMethodInstance)) return false; - for (auto& param : item->mMethodInstance->mParams) - { - if (param.mResolvedType->IsDeleting()) - return false; - } + return true; +} - if (item->mMethodInstance->mMethodInfoEx != NULL) - { - for (auto genericArg : item->mMethodInstance->mMethodInfoEx->mMethodGenericArguments) - if (genericArg->IsDeleting()) - return false; - } +bool BfContext::IsWorkItemValid(BfInlineMethodRequest* item) +{ + if (mCompiler->mStats.mMidCompileRebuilds == 0) + return true; + + if (!IsWorkItemValid(item->mMethodInstance)) + return false; + + if (item->mMethodInstance->GetOwner()->IsDeleting()) + return false; return true; } @@ -3045,7 +3115,7 @@ bool BfContext::IsWorkItemValid(BfMethodSpecializationRequest* item) template void DoRemoveInvalidWorkItems(BfContext* bfContext, WorkQueue& workList, bool requireValidType) -{ +{ //auto itr = workList.begin(); //while (itr != workList.end()) @@ -3057,11 +3127,11 @@ void DoRemoveInvalidWorkItems(BfContext* bfContext, WorkQueue& workList, bool auto workItem = workList[workIdx]; if (workItem == NULL) continue; - + BfTypeInstance* typeInst = workItem->mType->ToTypeInstance(); if ((workItem->mType->IsDeleting()) || - (workItem->mType->mRebuildFlags & BfTypeRebuildFlag_Deleted) || + (workItem->mType->mRebuildFlags & BfTypeRebuildFlag_Deleted) || ((workItem->mRevision != -1) && (typeInst != NULL) && (workItem->mRevision != typeInst->mRevision)) || ((workItem->mSignatureRevision != -1) && (typeInst != NULL) && (workItem->mSignatureRevision != typeInst->mSignatureRevision)) || ((workItem->mFromModuleRevision != -1) && (workItem->mFromModuleRevision != workItem->mFromModule->mRevision)) || @@ -3080,18 +3150,18 @@ void DoRemoveInvalidWorkItems(BfContext* bfContext, WorkQueue& workList, bool BfLogSys(bfContext->mSystem, "Removing work item: %p ReqId:%d\n", workItem, workItem->mReqId); ReportRemovedItem(workItem); workIdx = workList.RemoveAt(workIdx); - //itr = workList.erase(itr); + //itr = workList.erase(itr); } //else - //++itr; + //++itr; } } void BfContext::RemoveInvalidFailTypes() -{ +{ for (auto itr = mFailTypes.begin(); itr != mFailTypes.end(); ) { - auto typeInst = *itr; + auto typeInst = itr->mKey; BfLogSysM("Checking FailType: %p\n", typeInst); if ((typeInst->IsDeleting()) || (typeInst->mRebuildFlags & BfTypeRebuildFlag_Deleted)) { @@ -3100,13 +3170,13 @@ void BfContext::RemoveInvalidFailTypes() } else itr++; - } + } } // These work items are left over from a previous canceled run, OR from explicit method // specializations being rebuilt when the type is rebuilt void BfContext::RemoveInvalidWorkItems() -{ +{ BfLogSysM("RemoveInvalidWorkItems %p\n", this); // Delete any request that include deleted types. @@ -3114,20 +3184,20 @@ void BfContext::RemoveInvalidWorkItems() // whether or not the type has been reset since these work items were requested DoRemoveInvalidWorkItems(this, mMethodWorkList, true); - DoRemoveInvalidWorkItems(this, mInlineMethodWorkList, true); + DoRemoveInvalidWorkItems(this, mInlineMethodWorkList, true); //TODO: We used to pass true into requireValidType, but this gets populated from UpdateRevisedTypes right before RemoveInvalidWorkItems, // so we're passing false in here now. Don't just switch it back and forth - find why 'false' was causing an issue. - // Same with mMethodSpecializationWorkList - DoRemoveInvalidWorkItems(this, mPopulateTypeWorkList, false); + // Same with mMethodSpecializationWorkList + DoRemoveInvalidWorkItems(this, mPopulateTypeWorkList, false); DoRemoveInvalidWorkItems(this, mMidCompileWorkList, false); DoRemoveInvalidWorkItems(this, mMethodSpecializationWorkList, false/*true*/); DoRemoveInvalidWorkItems(this, mTypeRefVerifyWorkList, false); - + #ifdef _DEBUG for (auto& workItem : mMethodWorkList) { - //BF_ASSERT(workItem.mMethodInstance->mDeclModule != NULL); + //BF_ASSERT(workItem.mMethodInstance->mDeclModule != NULL); } for (auto workItem : mMethodSpecializationWorkList) @@ -3148,40 +3218,40 @@ void BfContext::RemoveInvalidWorkItems() for (auto workListItem : mMethodWorkList) { if ((workListItem != NULL) && (workListItem->mType->IsUnspecializedType())) - { - workListItem->mMethodInstance->mIRFunction = BfIRFunction(); - } + { + workListItem->mMethodInstance->mIRFunction = BfIRFunction(); + } } - } - + } + RemoveInvalidFailTypes(); } void BfContext::RemapObject() -{ +{ if (mCompiler->mBfObjectTypeDef == NULL) return; - // There are several types that get their LLVM type mapped to Object, so make sure to remap that + // There are several types that get their LLVM type mapped to Object, so make sure to remap that // for when Object itself gets recreated - + auto objectType = mScratchModule->ResolveTypeDef(mCompiler->mBfObjectTypeDef, BfPopulateType_Declaration); auto objectTypeInst = objectType->ToTypeInstance(); if (objectTypeInst->mRevision == mMappedObjectRevision) return; mMappedObjectRevision = objectTypeInst->mRevision; - + for (int paramKind = 0; paramKind < 2; paramKind++) { for (int paramIdx = 0; paramIdx < (int)mGenericParamTypes[paramKind].size(); paramIdx++) { - auto genericParam = mGenericParamTypes[paramKind][paramIdx]; + auto genericParam = mGenericParamTypes[paramKind][paramIdx]; genericParam->mSize = objectType->mSize; genericParam->mAlign = objectType->mAlign; } } - auto varType = mScratchModule->GetPrimitiveType(BfTypeCode_Var); + auto varType = mScratchModule->GetPrimitiveType(BfTypeCode_Var); varType->mSize = objectType->mSize; varType->mAlign = objectType->mAlign; } @@ -3222,7 +3292,7 @@ void BfContext::TryUnreifyModules() BP_ZONE("BfContext::TryUnreifyModules"); for (auto module : mModules) - { + { if (module->mIsSpecialModule) continue; @@ -3238,7 +3308,7 @@ void BfContext::TryUnreifyModules() if (typeInst->mTypeDef->IsGlobalsContainer()) isRequired = true; - if (typeInst->IsAlwaysInclude()) + if (typeInst->IsAlwaysInclude()) isRequired = true; } @@ -3258,8 +3328,8 @@ void BfContext::MarkUsedModules(BfProject* project, BfModule* module) if (module->mIsScratchModule) return; - if (project->mUsedModules.Contains(module)) - return; + if (project->mUsedModules.Contains(module)) + return; if (!mCompiler->IsModuleAccessible(module, project)) return; @@ -3267,7 +3337,7 @@ void BfContext::MarkUsedModules(BfProject* project, BfModule* module) project->mUsedModules.Add(module); for (auto& typeDataKV : module->mTypeDataRefs) - project->mReferencedTypeData.Add(typeDataKV.mKey); + project->mReferencedTypeData.Add(typeDataKV.mKey); for (auto& slotKV : module->mInterfaceSlotRefs) { @@ -3276,7 +3346,7 @@ void BfContext::MarkUsedModules(BfProject* project, BfModule* module) mCompiler->mHotState->mHasNewInterfaceTypes = true; mReferencedIFaceSlots.Add(typeInstance); } - + for (auto& kv : module->mStaticFieldRefs) { auto& fieldRef = kv.mKey; @@ -3289,7 +3359,7 @@ void BfContext::MarkUsedModules(BfProject* project, BfModule* module) module->mLastUsedRevision = mCompiler->mRevision; for (auto usedModule : module->mModuleRefs) - { + { MarkUsedModules(project, usedModule); } @@ -3300,8 +3370,7 @@ void BfContext::MarkUsedModules(BfProject* project, BfModule* module) } void BfContext::Finish() -{ - +{ } void BfContext::Cleanup() @@ -3309,7 +3378,7 @@ void BfContext::Cleanup() BfLogSysM("BfContext::Cleanup() MethodWorkList: %d LocalMethodGraveyard: %d\n", mMethodWorkList.size(), mLocalMethodGraveyard.size()); // Can't clean up LLVM types, they are allocated with a bump allocator - RemoveInvalidFailTypes(); + RemoveInvalidFailTypes(); mCompiler->mCompileState = BfCompiler::CompileState_Cleanup; @@ -3359,7 +3428,7 @@ void BfContext::Cleanup() // These need to get deleted before the modules because we access mModule in the MethodInstance dtors for (int pass = 0; pass < 2; pass++) { - for (int i = 0; i < (int)mTypeGraveyard.size(); i++) + for (int i = 0; i < (int)mTypeGraveyard.size(); i++) { auto type = mTypeGraveyard[i]; if (type == NULL) @@ -3383,7 +3452,7 @@ void BfContext::Cleanup() for (auto itr = project->mUsedModules.begin(); itr != project->mUsedModules.end(); ) { auto module = *itr; - + if (module->mIsDeleting) itr = project->mUsedModules.Remove(itr); else @@ -3398,8 +3467,8 @@ void BfContext::Cleanup() for (auto module : mDeletingModules) { int idx = (int)mFinishedModuleWorkList.IndexOf(module); - if (idx != -1) - mFinishedModuleWorkList.RemoveAt(idx); + if (idx != -1) + mFinishedModuleWorkList.RemoveAt(idx); idx = (int)mFinishedSlotAwaitModuleWorkList.IndexOf(module); if (idx != -1) @@ -3407,15 +3476,14 @@ void BfContext::Cleanup() delete module; } - mDeletingModules.Clear(); - + mDeletingModules.Clear(); + for (auto typeDef : mTypeDefGraveyard) delete typeDef; - mTypeDefGraveyard.Clear(); - + mTypeDefGraveyard.Clear(); + mScratchModule->Cleanup(); mUnreifiedModule->Cleanup(); - for (auto module : mModules) + for (auto module : mModules) module->Cleanup(); -} - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 57db1d36..44d883ee 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -12,22 +12,22 @@ public: BfModule* mFromModule; int mRevision; int mSignatureRevision; - int mFromModuleRevision; + int mFromModuleRevision; int mFromModuleRebuildIdx; - int mReqId; - static int sCurReqId; + int mReqId; + static int sCurReqId; public: BfWorkListEntry() { mType = NULL; mFromModule = NULL; - mRevision = -1; + mRevision = -1; mSignatureRevision = -1; mFromModuleRevision = -1; mFromModuleRebuildIdx = -1; - mReqId = ++sCurReqId; - } + mReqId = ++sCurReqId; + } }; class BfTypeProcessRequest : public BfWorkListEntry @@ -43,7 +43,7 @@ public: class BfMethodSpecializationRequest : public BfWorkListEntry { -public: +public: int32 mMethodIdx; BfTypeVector mMethodGenericArguments; BfGetMethodInstanceFlags mFlags; @@ -51,7 +51,7 @@ public: public: BfMethodSpecializationRequest() - { + { mMethodIdx = -1; mFlags = BfGetMethodInstanceFlag_None; mForeignType = NULL; @@ -97,9 +97,9 @@ public: class BfInlineMethodRequest : public BfMethodProcessRequest { -public: +public: BfIRFunction mFunc; - + ~BfInlineMethodRequest() { mMethodInstance = NULL; @@ -110,12 +110,12 @@ class BfTypeRefVerifyRequest : public BfWorkListEntry { public: BfTypeInstance* mCurTypeInstance; - BfAstNode* mRefNode; + BfAstNode* mRefNode; }; class BfMidCompileRequest : public BfWorkListEntry { -public: +public: String mReason; }; @@ -153,15 +153,15 @@ public: BfType* mType; BfTypeDef* mGlobalContainerCurUserTypeDef; - Array mGlobalContainers; // All global containers that are visible + Array mGlobalContainers; // All global containers that are visible BfPopulateType mPopulateType; BfTypeReference* mCurBaseTypeRef; BfTypeInstance* mCurBaseType; BfTypeReference* mCurAttributeTypeRef; - BfFieldDef* mCurFieldDef; + BfFieldDef* mCurFieldDef; BfTypeDef* mCurTypeDef; - BfTypeDef* mForceActiveTypeDef; + BfTypeDef* mForceActiveTypeDef; BfProject* mActiveProject; ResolveKind mResolveKind; BfAstNode* mCurVarInitializer; @@ -209,7 +209,7 @@ public: class BfSavedTypeData { public: - BfHotTypeData* mHotTypeData; + BfHotTypeData* mHotTypeData; int mTypeId; public: @@ -221,7 +221,7 @@ public: struct SpecializedErrorData { - // We need to store errors during type specialization and method specialization, + // We need to store errors during type specialization and method specialization, // because if the type is deleted we need to clear the errors BfTypeInstance* mRefType; BfModule* mModule; @@ -241,8 +241,8 @@ struct BfCaseInsensitiveStringHash { size_t operator()(const StringImpl& str) const { - int curHash = 0; - for (int i = 0; i < (int)str.length(); i++) + int curHash = 0; + for (int i = 0; i < (int)str.length(); i++) curHash = ((curHash ^ (int)(intptr)toupper(str[i])) << 5) - curHash; return curHash; } @@ -251,7 +251,7 @@ struct BfCaseInsensitiveStringHash struct BfCaseInsensitiveStringEquals { bool operator()(const StringImpl& lhs, const StringImpl& rhs) const - { + { if (lhs.length() != rhs.length()) return false; return _stricmp(lhs.c_str(), rhs.c_str()) == 0; @@ -270,7 +270,7 @@ public: { T*& ref = (*this)[idx]; if (ref != NULL) - (*ref).~T(); + (*ref).~T(); Deque::RemoveAt(0); if (this->mSize == 0) { @@ -303,7 +303,7 @@ public: T* item = mWorkAlloc.Alloc(); this->Add(item); return item; - } + } }; template @@ -348,19 +348,25 @@ public: bool operator==(const BfConstraintState& other) const { - return + return (mGenericParamInstance == other.mGenericParamInstance) && (mLeftType == other.mLeftType) && (mRightType == other.mRightType); } }; +enum BfFailKind +{ + BfFailKind_Normal, + BfFailKind_Deep +}; + class BfContext { public: - CritSect mCritSect; - bool mDeleting; - + CritSect mCritSect; + bool mDeleting; + BfTypeState* mCurTypeState; BfSizedArray* mCurNamespaceNodes; BfConstraintState* mCurConstraintState; @@ -369,25 +375,25 @@ public: bool mAssertOnPopulateType; BfSystem* mSystem; - BfCompiler* mCompiler; - + BfCompiler* mCompiler; + bool mAllowLockYield; bool mLockModules; BfModule* mScratchModule; - BfModule* mUnreifiedModule; + BfModule* mUnreifiedModule; HashSet mUsedModuleNames; Dictionary mProjectModule; Array mModules; - Array mDeletingModules; - HashSet mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile + Array mDeletingModules; + Dictionary mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile HashSet mReferencedIFaceSlots; BfMethodInstance* mValueTypeDeinitSentinel; Array mTempNodes; - BfResolvedTypeSet mResolvedTypes; + BfResolvedTypeSet mResolvedTypes; Array mTypes; // Can contain NULLs for deleted types - Array mFieldResolveReentrys; // For detecting 'var' field circular refs + Array mFieldResolveReentrys; // For detecting 'var' field circular refs Dictionary mSavedTypeDataMap; Array mSavedTypeData; @@ -399,7 +405,7 @@ public: PtrWorkQueue mReifyModuleWorkList; WorkQueue mMethodWorkList; - WorkQueue mInlineMethodWorkList; + WorkQueue mInlineMethodWorkList; WorkQueue mPopulateTypeWorkList; WorkQueue mMethodSpecializationWorkList; WorkQueue mTypeRefVerifyWorkList; @@ -409,7 +415,7 @@ public: bool mHasReifiedQueuedRebuildTypes; Array mGenericParamTypes[3]; - + Array mTypeGraveyard; Array mTypeDefGraveyard; Array mLocalMethodGraveyard; @@ -418,9 +424,9 @@ public: Dictionary mStringObjectIdMap; int mCurStringObjectPoolId; - HashSet mQueuedSpecializedMethodRebuildTypes; + HashSet mQueuedSpecializedMethodRebuildTypes; - BfAllocPool mPointerTypePool; + BfAllocPool mPointerTypePool; BfAllocPool mArrayTypePool; BfAllocPool mSizedArrayTypePool; BfAllocPool mUnknownSizedArrayTypePool; @@ -429,13 +435,13 @@ public: BfAllocPool mAliasTypePool; BfAllocPool mRefTypePool; BfAllocPool mModifiedTypeTypePool; - BfAllocPool mGenericTypeInstancePool; + BfAllocPool mGenericTypeInstancePool; BfAllocPool mArrayTypeInstancePool; BfAllocPool mGenericParamTypePool; BfAllocPool mTypeDefTypeRefPool; BfAllocPool mConcreteInterfaceTypePool; BfAllocPool mConstExprValueTypePool; - BfAllocPool mDelegateTypePool; + BfAllocPool mDelegateTypePool; BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length]; BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length]; @@ -447,15 +453,15 @@ public: void PopulateHotTypeDataVTable(BfTypeInstance* typeInstance); void DeleteType(BfType* type, bool deferDepRebuilds = false); void UpdateAfterDeletingTypes(); - void VerifyTypeLookups(BfTypeInstance* typeInst); + void VerifyTypeLookups(BfTypeInstance* typeInst); void GenerateModuleName_TypeInst(BfTypeInstance* typeInst, StringImpl& name); void GenerateModuleName_Type(BfType* type, StringImpl& name); void GenerateModuleName(BfTypeInstance* typeInst, StringImpl& name); bool IsSentinelMethod(BfMethodInstance* methodInstance); - void SaveDeletingType(BfType* type); + void SaveDeletingType(BfType* type); BfType* FindType(const StringImpl& typeName); String TypeIdToString(int typeId); - BfHotTypeData* GetHotTypeData(int typeId); + BfHotTypeData* GetHotTypeData(int typeId); void ReflectInit(); public: @@ -464,28 +470,30 @@ public: void ReportMemory(MemReporter* memReporter); void ProcessMethod(BfMethodInstance* methodInstance); - int GetStringLiteralId(const StringImpl& str); + int GetStringLiteralId(const StringImpl& str); void CheckLockYield(); bool IsCancellingAndYield(); void QueueFinishModule(BfModule * module); void CancelWorkItems(); bool ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods); void HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTempType = false); - void PreUpdateRevisedTypes(); - void UpdateRevisedTypes(); - void VerifyTypeLookups(); + void PreUpdateRevisedTypes(); + void UpdateRevisedTypes(); + void VerifyTypeLookups(); void QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag); void MarkAsReferenced(BfDependedType* depType); void RemoveInvalidFailTypes(); bool IsWorkItemValid(BfWorkListEntry* item); + bool IsWorkItemValid(BfMethodInstance* methodInstance); bool IsWorkItemValid(BfMethodProcessRequest* item); + bool IsWorkItemValid(BfInlineMethodRequest* item); bool IsWorkItemValid(BfMethodSpecializationRequest* item); - void RemoveInvalidWorkItems(); + void RemoveInvalidWorkItems(); BfType* FindTypeById(int typeId); void AddTypeToWorkList(BfType* type); void ValidateDependencies(); void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true); - void RebuildDependentTypes(BfDependedType* dType); + void RebuildDependentTypes(BfDependedType* dType); void QueueMidCompileRebuildDependentTypes(BfDependedType* dType, const String& reason); void RebuildDependentTypes_MidCompile(BfDependedType* dType, const String& reason); bool CanRebuild(BfType* type); diff --git a/IDEHelper/Compiler/BfDefBuilder.cpp b/IDEHelper/Compiler/BfDefBuilder.cpp index 03aa0cc5..366ce1d3 100644 --- a/IDEHelper/Compiler/BfDefBuilder.cpp +++ b/IDEHelper/Compiler/BfDefBuilder.cpp @@ -73,8 +73,8 @@ BfDefBuilder::BfDefBuilder(BfSystem* bfSystem) BfDefBuilder::~BfDefBuilder() { - for (auto& usingNamespace : mNamespaceSearch) - mSystem->ReleaseAtomComposite(usingNamespace); + for (auto& usingNamespace : mNamespaceSearch) + mSystem->ReleaseAtomComposite(usingNamespace); } void BfDefBuilder::Process(BfPassInstance* passInstance, BfSource* bfSource, bool fullRefresh) @@ -92,19 +92,19 @@ void BfDefBuilder::Process(BfPassInstance* passInstance, BfSource* bfSource, boo mSystem->mNeedsTypesHandledByCompiler = true; mPassInstance = passInstance; - + bool isAutocomplete = false; if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL)) - { + { mCurSource = bfSource; - Visit(bfSource->mRootNode); + Visit(bfSource->mRootNode); mCurSource = NULL; mPassInstance = NULL; return; } mFullRefresh = fullRefresh; - + if (bfSource->mPrevRevision != NULL) { for (auto typeDef : bfSource->mPrevRevision->mTypeDefs) @@ -123,7 +123,7 @@ void BfDefBuilder::Process(BfPassInstance* passInstance, BfSource* bfSource, boo mCurSource = NULL; } } - + if (bfSource->mPrevRevision != NULL) { for (auto typeDef : bfSource->mPrevRevision->mTypeDefs) @@ -146,15 +146,15 @@ void BfDefBuilder::Process(BfPassInstance* passInstance, BfSource* bfSource, boo void BfDefBuilder::Visit(BfIdentifierNode* identifier) { - if (mResolvePassData != NULL) - mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(identifier); + if (mResolvePassData != NULL) + mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(identifier); } // We need to be aware of the startNode because the reducer adds specifiers like 'static' and 'public' AFTER the method has // already been handled, so we need to ignore that space while determining if we're "inside" this method or not during // autocompletion bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int addLen) -{ +{ if ((mResolvePassData == NULL) || (!mResolvePassData->mHasCursorIdx)) return true; @@ -173,13 +173,13 @@ bool BfDefBuilder::WantsNode(BfAstNode* wholeNode, BfAstNode* startNode, int add if ((startNode == NULL) || (parser->mCursorIdx >= startNode->GetSrcStart())) return true; } - return false; + return false; } static int sGenericParamIdx = 0; void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array& genericParams, Array* externConstraintDefs, int outerGenericSize, bool isInGeneric) -{ +{ if (genericParamsDecl != NULL) { int startIdx = (int)genericParams.size(); @@ -200,11 +200,11 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD while (checkTypeDef != NULL) { if (&genericParams != &checkTypeDef->mGenericParamDefs) - { + { for (int checkParamsIdx = 0; checkParamsIdx < (int)checkTypeDef->mGenericParamDefs.size(); checkParamsIdx++) { if (checkTypeDef->mGenericParamDefs[checkParamsIdx]->mName == name) - { + { mPassInstance->Warn(0, "Generic param name has same name as generic param from outer type", genericParamNode); } } @@ -212,13 +212,13 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD checkTypeDef = checkTypeDef->mOuterType; } - - auto genericParamDef = new BfGenericParamDef(); + + auto genericParamDef = new BfGenericParamDef(); genericParamDef->mName = name; genericParamDef->mNameNodes.Add(genericParamNode); - genericParamDef->mGenericParamFlags = BfGenericParamFlag_None; - genericParams.push_back(genericParamDef); - } + genericParamDef->mGenericParamFlags = BfGenericParamFlag_None; + genericParams.push_back(genericParamDef); + } } if (genericConstraints == NULL) @@ -245,7 +245,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD genericParamDef = checkGenericParam; } } - + BfConstraintDef* constraintDef = genericParamDef; if (genericParamDef == NULL) @@ -271,7 +271,7 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD constraintDef = externConstraintDef; } } - + if (genericParamDef != NULL) genericParamDef->mNameNodes.Add(nameNode); @@ -287,14 +287,14 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD { name = tokenPairNode->mLeft->ToString() + tokenPairNode->mRight->ToString(); } - + if (!name.empty()) { if ((name == "class") || (name == "struct") || (name == "struct*") || (name == "const") || (name == "var") || (name == "concrete") || (name == "interface") || (name == "enum")) { - int prevFlags = constraintDef->mGenericParamFlags & + int prevFlags = constraintDef->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface | BfGenericParamFlag_Enum); - if (prevFlags != 0) + if (prevFlags != 0) { String prevFlagName; if (prevFlags & BfGenericParamFlag_Class) @@ -331,20 +331,20 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Enum); else //if (name == "var") constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Var); - + continue; - } + } else if (name == "new") { constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_New); continue; - } + } else if (name == "delete") { constraintDef->mGenericParamFlags = (BfGenericParamFlags)(constraintDef->mGenericParamFlags | BfGenericParamFlag_Delete); continue; } - } + } if (auto genericOpConstraint = BfNodeDynCast(constraintNode)) { @@ -357,22 +357,22 @@ void BfDefBuilder::ParseGenericParams(BfGenericParamsDeclaration* genericParamsD { Fail("Invalid constraint", constraintNode); return; - } + } } - + constraintDef->mConstraints.Add(constraintNode); } } } BfProtection BfDefBuilder::GetProtection(BfAstNode* protectionNode) -{ +{ if (auto tokenPair = BfNodeDynCast(protectionNode)) { return BfProtection_ProtectedInternal; } else if (auto protectionToken = BfNodeDynCast(protectionNode)) - { + { if (protectionToken->GetToken() == BfToken_Public) return BfProtection_Public; if (protectionToken->GetToken() == BfToken_Protected) @@ -381,11 +381,11 @@ BfProtection BfDefBuilder::GetProtection(BfAstNode* protectionNode) return BfProtection_Internal; return BfProtection_Private; } - + if (mCurTypeDef->mTypeCode == BfTypeCode_Interface) return BfProtection_Public; else - return BfProtection_Private; + return BfProtection_Private; } void BfDefBuilder::Visit(BfConstructorDeclaration* ctorDeclaration) @@ -397,7 +397,7 @@ void BfDefBuilder::Visit(BfConstructorDeclaration* ctorDeclaration) } BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaration, BfMethodDef* outerMethodDef) -{ +{ BfMethodDef* methodDef; if (auto operatorDecl = BfNodeDynCast(methodDeclaration)) @@ -405,7 +405,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio auto operatorDef = new BfOperatorDef(); operatorDef->mOperatorDeclaration = operatorDecl; operatorDef->mIsOperator = true; - methodDef = operatorDef; + methodDef = operatorDef; } else methodDef = new BfMethodDef(); @@ -414,12 +414,12 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio methodDef->mDeclaringType = mCurDeclaringTypeDef; methodDef->mMethodDeclaration = methodDeclaration; methodDef->mExplicitInterface = methodDeclaration->mExplicitInterface; - methodDef->mReturnTypeRef = methodDeclaration->mReturnType; - methodDef->mProtection = GetProtection(methodDeclaration->mProtectionSpecifier); + methodDef->mReturnTypeRef = methodDeclaration->mReturnType; + methodDef->mProtection = GetProtection(methodDeclaration->mProtectionSpecifier); methodDef->mIsReadOnly = methodDeclaration->mReadOnlySpecifier != NULL; methodDef->mIsStatic = methodDeclaration->mStaticSpecifier != NULL; - methodDef->mIsVirtual = methodDeclaration->mVirtualSpecifier != NULL; - methodDef->mIsPartial = methodDeclaration->mPartialSpecifier != NULL; + methodDef->mIsVirtual = methodDeclaration->mVirtualSpecifier != NULL; + methodDef->mIsPartial = methodDeclaration->mPartialSpecifier != NULL; methodDef->mIsNew = methodDeclaration->mNewSpecifier != NULL; methodDef->mIsMutating = methodDeclaration->mMutSpecifier != NULL; methodDef->mIsExtern = methodDeclaration->mExternSpecifier != NULL; @@ -450,7 +450,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio { methodDef->mIsConcrete = true; methodDef->mIsVirtual = false; - } + } if (methodDef->mIsAbstract) { @@ -462,12 +462,12 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio { methodDef->mIsOverride = false; methodDef->mIsAbstract = false; - } + } if (mCurTypeDef->mTypeCode == BfTypeCode_Interface) { if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodDef->mGenericParams.empty()) && (methodDef->mProtection == BfProtection_Public)) - methodDef->mIsVirtual = true; + methodDef->mIsVirtual = true; } bool isAutoCtor = false; @@ -495,12 +495,12 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio } } else if (methodDeclaration->IsA()) - { + { methodDef->mMethodType = BfMethodType_Dtor; if (methodDef->mIsStatic) methodDef->mName = "__BfStaticDtor"; else - { + { methodDef->mName = "~this"; if (!methodDef->mIsVirtual) { @@ -515,7 +515,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio /*if (propertyDecl->mStaticSpecifier == NULL) { Fail("Operators must be declared as static", methodDeclaration); - }*/ + }*/ String declError; if (methodDef->mProtection != BfProtection_Public) @@ -554,7 +554,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio methodDef->mMethodType = BfMethodType_Normal; methodDef->mProtection = BfProtection_Public; methodDef->mIsStatic = mCurTypeDef->mIsFunction; - + auto attributes = mCurTypeDef->mTypeDeclaration->mAttributes; while (attributes != NULL) { @@ -566,13 +566,13 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio methodDef->mCallingConvention = BfCallingConvention_Stdcall; } attributes = attributes->mNextAttribute; - } + } } else if (methodDeclaration->mMixinSpecifier != NULL) { if (methodDeclaration->mNameNode != NULL) methodDef->SetName(methodDeclaration->mNameNode); - methodDef->mMethodType = BfMethodType_Mixin; + methodDef->mMethodType = BfMethodType_Mixin; } else { @@ -621,8 +621,8 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio bool hadParams = false; bool hasDefault = false; for (int paramIdx = 0; paramIdx < (int)methodDeclaration->mParams.size(); paramIdx++) - { - BfParameterDeclaration* paramDecl = methodDeclaration->mParams[paramIdx]; + { + BfParameterDeclaration* paramDecl = methodDeclaration->mParams[paramIdx]; auto paramDef = new BfParameterDef(); paramDef->mParamDeclaration = paramDecl; @@ -667,8 +667,8 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio hadParams = true; } else if (hadParams) - { - methodDef->mParams[paramIdx - 1]->mParamKind = BfParamKind_Normal; + { + methodDef->mParams[paramIdx - 1]->mParamKind = BfParamKind_Normal; hadParams = false; Fail("Params parameter must be the last parameter", methodDef->mParams[paramIdx - 1]->mParamDeclaration); } @@ -684,7 +684,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio } methodDef->mParams.push_back(paramDef); - } + } if ((mCurTypeDef->mIsFunction) && (!methodDef->mParams.IsEmpty()) && (methodDef->mParams[0]->mName == "this")) { @@ -696,7 +696,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio { if (refTypeRef->mRefToken->mToken != BfToken_Mut) { - Fail("Only 'mut' is allowed here", refTypeRef->mRefToken); + Fail("Only 'mut' is allowed here", refTypeRef->mRefToken); } methodDef->mIsMutating = true; } @@ -717,7 +717,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio fieldDef->mTypeRef = paramDef->mTypeRef; fieldDef->mProtection = BfProtection_Public; BF_ASSERT(mCurDeclaringTypeDef != NULL); - fieldDef->mDeclaringType = mCurDeclaringTypeDef; + fieldDef->mDeclaringType = mCurDeclaringTypeDef; fieldDef->mIdx = mCurTypeDef->mFields.mSize; if ((paramDef->mParamDeclaration->mModToken != NULL) && (paramDef->mParamDeclaration->mModToken->mToken == BfToken_ReadOnly)) @@ -726,7 +726,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio } } - ParseAttributes(methodDeclaration->mAttributes, methodDef); + ParseAttributes(methodDeclaration->mAttributes, methodDef); return methodDef; } @@ -747,7 +747,7 @@ void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration) int addLen = 0; if ((methodDeclaration->mNameNode == NULL) && (methodDeclaration->mBody == NULL)) - addLen = 1; + addLen = 1; mSystem->CheckLockYield(); @@ -774,12 +774,12 @@ void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration) auto methodDef = CreateMethodDef(methodDeclaration); methodDef->mWantsBody = wantsBody; - if (methodDef->mMethodType == BfMethodType_Operator) - mCurTypeDef->mOperators.push_back((BfOperatorDef*)methodDef); - mCurTypeDef->mMethods.push_back(methodDef); + if (methodDef->mMethodType == BfMethodType_Operator) + mCurTypeDef->mOperators.push_back((BfOperatorDef*)methodDef); + mCurTypeDef->mMethods.push_back(methodDef); if (methodDef->mCommutableKind == BfCommutableKind_Forward) - { + { auto revMethodDef = CreateMethodDef(methodDeclaration); revMethodDef->mWantsBody = wantsBody; if (revMethodDef->mMethodType == BfMethodType_Operator) @@ -789,15 +789,15 @@ void BfDefBuilder::Visit(BfMethodDeclaration* methodDeclaration) { BF_SWAP(revMethodDef->mParams[0], revMethodDef->mParams[1]); } - revMethodDef->mCommutableKind = BfCommutableKind_Reverse; - mCurTypeDef->mMethods.push_back(revMethodDef); - } + revMethodDef->mCommutableKind = BfCommutableKind_Reverse; + mCurTypeDef->mMethods.push_back(revMethodDef); + } } void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef) { while (attributes != NULL) - { + { if (attributes->mAttributeTypeRef != NULL) { auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString(); @@ -805,7 +805,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef if (typeRefName == "CLink") methodDef->mCLink = true; else if (typeRefName == "StdCall") - methodDef->mCallingConvention = BfCallingConvention_Stdcall; + methodDef->mCallingConvention = BfCallingConvention_Stdcall; else if (typeRefName == "Inline") { if (methodDef->mIsExtern) @@ -837,7 +837,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef if (literalExpr->mValue.mTypeCode == BfTypeCode_CharPtr) { String filePath = *literalExpr->mValue.mString; - methodDef->mImportKind = BfMethodDef::GetImportKindFromPath(filePath); + methodDef->mImportKind = BfMethodDef::GetImportKindFromPath(filePath); } } } @@ -851,7 +851,18 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef methodDef->mHasComptime = true; } else if (typeRefName == "NoShow") - methodDef->mIsNoShow = true; + { + methodDef->mShow = BfShow_Hide; + + if (!attributes->mArguments.IsEmpty()) + { + if (auto literalExpr = BfNodeDynCast(attributes->mArguments[0])) + { + if (literalExpr->mValue.mBool) + methodDef->mShow = BfShow_HideIndirect; + } + } + } else if (typeRefName == "NoDiscard") methodDef->mIsNoDiscard = true; else if (typeRefName == "NoSplat") @@ -869,10 +880,10 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef else methodDef->mCommutableKind = BfCommutableKind_Forward; } - } + } else if (typeRefName == "OnCompile") { - mCurTypeDef->mHasCEOnCompile = true; + mCurTypeDef->mHasCEOnCompile = true; } } @@ -883,7 +894,7 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef) { while (attributes != NULL) - { + { if (attributes->mAttributeTypeRef != NULL) { auto typeRefName = attributes->mAttributeTypeRef->ToCleanAttributeString(); @@ -891,7 +902,20 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* if (typeRefName == "AlwaysInclude") typeDef->mIsAlwaysInclude = true; else if (typeRefName == "NoDiscard") - typeDef->mIsNoDiscard = true; + typeDef->mIsNoDiscard = true; + else if (typeRefName == "NoShow") + { + typeDef->mShow = BfShow_Hide; + + if (!attributes->mArguments.IsEmpty()) + { + if (auto literalExpr = BfNodeDynCast(attributes->mArguments[0])) + { + if (literalExpr->mValue.mBool) + typeDef->mShow = BfShow_HideIndirect; + } + } + } } attributes = attributes->mNextAttribute; @@ -908,10 +932,10 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) if (!WantsNode(propertyDeclaration, propertyDeclaration->mTypeRef, addLen)) { if (!WantsNode(propertyDeclaration, NULL, addLen)) - return; + return; // The cursor is inside some exterior specifiers, don't process body - wantsBody = false; - } + wantsBody = false; + } if ((propertyDeclaration->mConstSpecifier != NULL) && (propertyDeclaration->mConstSpecifier->mToken == BfToken_Const)) { @@ -919,11 +943,11 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) } if (mSignatureHashCtx != NULL) - HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock); + HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock); BfPropertyDef* propertyDef = new BfPropertyDef(); mCurTypeDef->mProperties.push_back(propertyDef); - propertyDef->mProtection = GetProtection(propertyDeclaration->mProtectionSpecifier); + propertyDef->mProtection = GetProtection(propertyDeclaration->mProtectionSpecifier); propertyDef->mIdx = (int)mCurTypeDef->mProperties.size() - 1; propertyDef->mIsConst = false; propertyDef->mIsProperty = true; @@ -939,20 +963,20 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) if (propertyDeclaration->mNameNode != NULL) propertyDef->SetName(propertyDeclaration->mNameNode); else if (propertyDeclaration->IsA()) - { + { propertyDef->mName = "[]"; } - propertyDef->mTypeRef = propertyDeclaration->mTypeRef; + propertyDef->mTypeRef = propertyDeclaration->mTypeRef; propertyDef->mFieldDeclaration = propertyDeclaration; BF_ASSERT(mCurDeclaringTypeDef != NULL); - propertyDef->mDeclaringType = mCurDeclaringTypeDef; + propertyDef->mDeclaringType = mCurDeclaringTypeDef; - if (auto varType = BfNodeDynCast(propertyDef->mTypeRef)) + if (auto varType = BfNodeDynCast(propertyDef->mTypeRef)) propertyDef->mIsReadOnly = true; //HashNode(*mSignatureHashCtx, propertyDeclaration, propertyDeclaration->mDefinitionBlock); - //mCurTypeDef->mSignatureHash = HashNode(propertyDeclaration, propertyDeclaration->mDefinitionBlock, mCurTypeDef->mSignatureHash); + //mCurTypeDef->mSignatureHash = HashNode(propertyDeclaration, propertyDeclaration->mDefinitionBlock, mCurTypeDef->mSignatureHash); if (propertyDeclaration->mDefinitionBlock == NULL) // To differentiate between autocompleting partial property if it transitions to a field { //mCurTypeDef->mSignatureHash = HashString("nullprop", mCurTypeDef->mSignatureHash); @@ -960,10 +984,10 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) mSignatureHashCtx->MixinStr("nullprop"); } - auto indexerDeclaration = BfNodeDynCast(propertyDeclaration); - + auto indexerDeclaration = BfNodeDynCast(propertyDeclaration); + bool isAbstract = false; - if (propertyDeclaration->mVirtualSpecifier != NULL) + if (propertyDeclaration->mVirtualSpecifier != NULL) isAbstract = propertyDeclaration->mVirtualSpecifier->GetToken() == BfToken_Abstract; bool needsAutoProperty = mCurTypeDef->HasAutoProperty(propertyDeclaration); @@ -978,7 +1002,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) fieldDef->mTypeRef = propertyDef->mTypeRef; if (auto refTypeRef = BfNodeDynCast(fieldDef->mTypeRef)) fieldDef->mTypeRef = refTypeRef->mElementType; - fieldDef->mName = mCurTypeDef->GetAutoPropertyName(propertyDeclaration); + fieldDef->mName = mCurTypeDef->GetAutoPropertyName(propertyDeclaration); fieldDef->mIdx = (int)mCurTypeDef->mFields.size(); mCurTypeDef->mFields.push_back(fieldDef); @@ -1055,7 +1079,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) else methodDef->mIsOverride = false; methodDef->mIsNew = propertyDeclaration->mNewSpecifier != NULL; - + if (indexerDeclaration != NULL) { for (int paramIdx = 0; paramIdx < (int)indexerDeclaration->mParams.size(); paramIdx++) @@ -1074,7 +1098,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) } } - String methodName; + String methodName; if (auto propExprBody = BfNodeDynCast(propertyDeclaration->mDefinitionBlock)) { methodName = "get"; @@ -1086,7 +1110,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) } else if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL)) methodName = methodDeclaration->mNameNode->ToString(); - + if (methodName == "get") { methodDef->mName = "get__"; @@ -1107,7 +1131,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) if (BfNodeDynCast(methodDeclaration->mBody) != NULL) methodDef->mIsMutating = true; // Don't require "set mut;", just "set;" - + auto paramDef = new BfParameterDef(); paramDef->mName = "value"; paramDef->mTypeRef = propertyDeclaration->mTypeRef; @@ -1121,7 +1145,7 @@ void BfDefBuilder::Visit(BfPropertyDeclaration* propertyDeclaration) if (methodDeclaration->mSetRefSpecifier != NULL) Fail("Property setter 'ref' can only be used with a 'ref' property type", methodDeclaration->mSetRefSpecifier); } - methodDef->mParams.Insert(0, paramDef); + methodDef->mParams.Insert(0, paramDef); propertyDef->mMethods.Add(methodDef); } else @@ -1139,7 +1163,7 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration) mSystem->CheckLockYield(); int endingAdd = 1;// Add '1' for autocompletion of 'new' initializer - + if (!WantsNode(fieldDeclaration, NULL, endingAdd)) { return; @@ -1149,34 +1173,35 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration) bool isEnumEntryDecl = fieldDeclaration->IsA(); auto fieldDef = new BfFieldDef(); - mCurTypeDef->mFields.push_back(fieldDef); + mCurTypeDef->mFields.push_back(fieldDef); fieldDef->mFieldDeclaration = fieldDeclaration; BF_ASSERT(mCurDeclaringTypeDef != NULL); fieldDef->mDeclaringType = mCurDeclaringTypeDef; if (fieldDeclaration->mNameNode != NULL) fieldDef->SetName(fieldDeclaration->mNameNode); - fieldDef->mProtection = GetProtection(fieldDeclaration->mProtectionSpecifier); + fieldDef->mProtection = GetProtection(fieldDeclaration->mProtectionSpecifier); if (isEnumEntryDecl) - fieldDef->mProtection = BfProtection_Public; - fieldDef->mIsReadOnly = fieldDeclaration->mReadOnlySpecifier != NULL; + fieldDef->mProtection = BfProtection_Public; + fieldDef->mIsReadOnly = fieldDeclaration->mReadOnlySpecifier != NULL; fieldDef->mIsInline = (fieldDeclaration->mReadOnlySpecifier != NULL) && (fieldDeclaration->mReadOnlySpecifier->GetToken() == BfToken_Inline); - fieldDef->mIsExtern = (fieldDeclaration->mExternSpecifier != NULL); + fieldDef->mIsExtern = (fieldDeclaration->mExternSpecifier != NULL) && (fieldDeclaration->mExternSpecifier->mToken == BfToken_Extern); + fieldDef->mIsAppend = (fieldDeclaration->mExternSpecifier != NULL) && (fieldDeclaration->mExternSpecifier->mToken == BfToken_Append); auto constSpecifierToken = BfNodeDynCast(fieldDeclaration->mConstSpecifier); - fieldDef->mIsConst = ((constSpecifierToken != NULL) && (constSpecifierToken->mToken == BfToken_Const)) || (isEnumEntryDecl); + fieldDef->mIsConst = ((constSpecifierToken != NULL) && (constSpecifierToken->mToken == BfToken_Const)) || (isEnumEntryDecl); if (auto usingSpecifier = BfNodeDynCast(fieldDeclaration->mConstSpecifier)) { if (usingSpecifier->mProtection != NULL) fieldDef->mUsingProtection = GetProtection(usingSpecifier->mProtection); else fieldDef->mUsingProtection = fieldDef->mProtection; - } + } fieldDef->mIsStatic = (fieldDeclaration->mStaticSpecifier != NULL) || fieldDef->mIsConst; fieldDef->mIsVolatile = (fieldDeclaration->mVolatileSpecifier != NULL); fieldDef->mTypeRef = fieldDeclaration->mTypeRef; - if (auto varType = BfNodeDynCast(fieldDef->mTypeRef)) + if (auto varType = BfNodeDynCast(fieldDef->mTypeRef)) fieldDef->mIsReadOnly = true; - + if (fieldDef->mUsingProtection != BfProtection_Hidden) mCurTypeDef->mHasUsingFields = true; @@ -1189,7 +1214,7 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration) } } - fieldDef->mIdx = (int)mCurTypeDef->mFields.size() - 1; + fieldDef->mIdx = (int)mCurTypeDef->mFields.size() - 1; //mCurTypeDef->mSignatureHash = HashNode(fieldDeclaration, mCurTypeDef->mSignatureHash); if (mSignatureHashCtx != NULL) @@ -1197,7 +1222,7 @@ void BfDefBuilder::Visit(BfFieldDeclaration* fieldDeclaration) } void BfDefBuilder::Visit(BfEnumCaseDeclaration* enumCaseDeclaration) -{ +{ // Using `enumCaseDeclaration->mCaseToken` breaks attribute autocompletion //if (!WantsNode(enumCaseDeclaration, enumCaseDeclaration->mCaseToken, 0)) @@ -1219,8 +1244,8 @@ BfFieldDef* BfDefBuilder::AddField(BfTypeDef* typeDef, BfTypeReference* fieldTyp fieldDef->mDeclaringType = typeDef; fieldDef->mTypeRef = fieldType; fieldDef->mName = fieldName; - fieldDef->mIdx = (int)typeDef->mFields.size(); - typeDef->mFields.push_back(fieldDef); + fieldDef->mIdx = (int)typeDef->mFields.size(); + typeDef->mFields.push_back(fieldDef); return fieldDef; } @@ -1230,9 +1255,9 @@ BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType auto methodDef = new BfMethodDef(); methodDef->mIdx = (int)typeDef->mMethods.size(); - typeDef->mMethods.push_back(methodDef); + typeDef->mMethods.push_back(methodDef); methodDef->mDeclaringType = typeDef; - methodDef->mMethodType = methodType; + methodDef->mMethodType = methodType; methodDef->mAddedAfterEmit = addedAfterEmit; if (name.empty()) { @@ -1267,13 +1292,13 @@ BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType { methodDef->mName = "~this"; methodDef->mIsVirtual = true; - methodDef->mIsOverride = true; + methodDef->mIsOverride = true; } } else { BF_FATAL("Method name expected"); - } + } } else methodDef->mName = name; @@ -1291,13 +1316,13 @@ BfMethodDef* BfDefBuilder::AddDtor(BfTypeDef* typeDef) methodDef->mProtection = BfProtection_Public; methodDef->mMethodType = BfMethodType_Dtor; methodDef->mIsVirtual = true; - methodDef->mIsOverride = true; + methodDef->mIsOverride = true; return methodDef; } void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef) -{ - // +{ + // { auto methodDef = new BfMethodDef(); methodDef->mIdx = (int)typeDef->mMethods.size(); @@ -1318,7 +1343,7 @@ void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef) methodDef->mIsNoReflect = true; } - // + // { auto methodDef = new BfMethodDef(); methodDef->mIdx = (int)typeDef->mMethods.size(); @@ -1341,9 +1366,9 @@ void BfDefBuilder::AddDynamicCastMethods(BfTypeDef* typeDef) } void BfDefBuilder::AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName) -{ +{ auto paramDef = new BfParameterDef(); - paramDef->mName = paramName; + paramDef->mName = paramName; paramDef->mTypeRef = typeRef; methodDef->mParams.push_back(paramDef); } @@ -1396,7 +1421,7 @@ BfTypeDef* BfDefBuilder::ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* c if ((!prevMatches) && (checkMatches)) return checkTypeDef; - return prevTypeDef; + return prevTypeDef; } void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) @@ -1479,7 +1504,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) mCurTypeDef->mNamespace = mNamespace; mSystem->AddNamespaceUsage(mCurTypeDef->mNamespace, mCurTypeDef->mProject); if (typeDeclaration->mTypeNode == NULL) - { + { mCurTypeDef->mIsPartial = true; mCurTypeDef->mIsExplicitPartial = true; } @@ -1498,13 +1523,13 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) Fail(StrFormat("Type name '%s' is reserved", typeDeclaration->mNameNode->ToString().c_str()), typeDeclaration->mNameNode); } } - + BfLogSys(mCurSource->mSystem, "DefBuilder %p %p TypeDecl:%s\n", mCurTypeDef, mCurSource, mCurTypeDef->mName->ToString().mPtr); - mCurTypeDef->mProtection = (outerTypeDef == NULL) ? BfProtection_Public : BfProtection_Private; + mCurTypeDef->mProtection = (outerTypeDef == NULL) ? BfProtection_Public : BfProtection_Private; if (typeDeclaration->mProtectionSpecifier != NULL) { - if ((outerTypeDef == NULL) && + if ((outerTypeDef == NULL) && (typeDeclaration->mProtectionSpecifier->GetToken() != BfToken_Public) && (typeDeclaration->mProtectionSpecifier->GetToken() != BfToken_Internal)) { @@ -1538,15 +1563,15 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) HashNode(*mSignatureHashCtx, baseClassNode); HashNode(*mSignatureHashCtx, typeDeclaration->mAttributes); HashNode(*mSignatureHashCtx, typeDeclaration->mAbstractSpecifier); - HashNode(*mSignatureHashCtx, typeDeclaration->mSealedSpecifier); + HashNode(*mSignatureHashCtx, typeDeclaration->mSealedSpecifier); HashNode(*mSignatureHashCtx, typeDeclaration->mProtectionSpecifier); HashNode(*mSignatureHashCtx, typeDeclaration->mPartialSpecifier); HashNode(*mSignatureHashCtx, typeDeclaration->mNameNode); HashNode(*mSignatureHashCtx, typeDeclaration->mGenericParams); HashNode(*mSignatureHashCtx, typeDeclaration->mGenericConstraintsDeclaration); - + HashNode(*mFullHashCtx, typeDeclaration); - + // Allow internal preprocessor flags to change a full hash change if (bfParser != NULL) { @@ -1579,7 +1604,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) //int randomCrap = rand(); //HASH128_MIXIN(mCurTypeDef->mFullHash, randomCrap); - // To cause a type rebuild when we change pragma settings or #if resolves + // To cause a type rebuild when we change pragma settings or #if resolves //mCurTypeDef->mFullHash = Hash128(&typeDeclaration->mParser->mStateHash, sizeof(Val128), mCurTypeDef->mFullHash); //BfParser* bfParser = typeDeclaration->mParser; @@ -1639,7 +1664,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) BfGenericParamDef* copiedGenericParamDef = new BfGenericParamDef(); *copiedGenericParamDef = *outerGenericParamDef; mCurTypeDef->mGenericParamDefs.Add(copiedGenericParamDef); - } + } BfTypeDef* parentType = outerTypeDef; while (parentType != NULL) @@ -1655,56 +1680,56 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) mCurTypeDef->mStaticSearch = mStaticSearch; mCurTypeDef->mInternalAccessSet = mInternalAccessSet; } - + // We need to mix the namespace search into the signature hash because it can change how type references are resolved for (auto& usingName : mCurTypeDef->mNamespaceSearch) - { + { mSystem->RefAtomComposite(usingName); mSignatureHashCtx->MixinStr(usingName.ToString()); } - for (auto& usingName : mCurTypeDef->mStaticSearch) + for (auto& usingName : mCurTypeDef->mStaticSearch) HashNode(*mSignatureHashCtx, usingName); for (auto& usingName : mCurTypeDef->mInternalAccessSet) HashNode(*mSignatureHashCtx, usingName); - + if ((typeDeclaration->mPartialSpecifier != NULL) && (!isAutoCompleteTempType)) { mCurTypeDef->mIsExplicitPartial = true; mCurTypeDef->mIsPartial = true; } - + bool isExtension = false; if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mTypeNode->GetToken() == BfToken_Extension)) { mCurTypeDef->mIsPartial = true; isExtension = true; } - + BfAtomComposite fullName; if (!expandedName.IsEmpty()) fullName.Set(mCurTypeDef->mNamespace.mParts, mCurTypeDef->mNamespace.mSize, &expandedName[0], (int)expandedName.size()); else fullName = mCurTypeDef->mNamespace; - + String fullNameStr = fullName.ToString(); mCurTypeDef->mHash = 0xBEEF123; // Salt the hash for (char c : fullNameStr) mCurTypeDef->mHash = ((mCurTypeDef->mHash ^ c) << 4) - mCurTypeDef->mHash; - mCurTypeDef->mFullName = fullName; + mCurTypeDef->mFullName = fullName; BfTypeDef* prevRevisionTypeDef = NULL; BfTypeDef* otherDefinitionTypeDef = NULL; - + int numGenericParams = 0; if (typeDeclaration->mGenericParams != NULL) numGenericParams = (int)typeDeclaration->mGenericParams->mGenericParams.size(); if (outerTypeDef != NULL) numGenericParams += (int)outerTypeDef->mGenericParamDefs.size(); - + mCurTypeDef->mSource = mCurSource; mCurTypeDef->mSource->mRefCount++; mCurTypeDef->mTypeDeclaration = typeDeclaration; - mCurTypeDef->mIsAbstract = (typeDeclaration->mAbstractSpecifier != NULL) && (typeDeclaration->mAbstractSpecifier->GetToken() == BfToken_Abstract); + mCurTypeDef->mIsAbstract = (typeDeclaration->mAbstractSpecifier != NULL) && (typeDeclaration->mAbstractSpecifier->GetToken() == BfToken_Abstract); mCurTypeDef->mIsStatic = typeDeclaration->mStaticSpecifier != NULL; mCurTypeDef->mIsDelegate = false; mCurTypeDef->mIsFunction = false; @@ -1769,7 +1794,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) mCurTypeDef->mIsAbstract = false; } } - + int outerGenericSize = 0; if (actualOuterTypeDef != NULL) { @@ -1782,25 +1807,25 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) if (!isAutoCompleteTempType) { BfTypeDef* prevDef = NULL; - - auto itr = mSystem->mTypeDefs.TryGet(fullName); + + auto itr = mSystem->mTypeDefs.TryGet(fullName); while (itr) { BfTypeDef* checkTypeDef = *itr; - + if (checkTypeDef->mDefState == BfTypeDef::DefState_Deleted) { itr.MoveToNextHashMatch(); continue; } - if ((checkTypeDef->NameEquals(mCurTypeDef)) && + if ((checkTypeDef->NameEquals(mCurTypeDef)) && (checkTypeDef->mGenericParamDefs.size() == numGenericParams) && (mCurTypeDef->mProject == checkTypeDef->mProject)) { if (checkTypeDef->mIsCombinedPartial) { - // Ignore + // Ignore } else { @@ -1808,13 +1833,13 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) { // We don't allow "new revision" semantics if the 'isExtension' state changes, or // if the outer type did not use "new revision" semantics (for isExtension change on itself or other outer type) - + bool isCompatible = (isExtension == (checkTypeDef->mTypeCode == BfTypeCode_Extension)) && (checkTypeDef->mTypeCode == mCurTypeDef->mTypeCode) && (checkTypeDef->mIsDelegate == mCurTypeDef->mIsDelegate) && (checkTypeDef->mIsFunction == mCurTypeDef->mIsFunction) && (checkTypeDef->mOuterType == actualOuterTypeDef); - + if (isCompatible) { if (prevRevisionTypeDef == NULL) @@ -1856,12 +1881,12 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) BF_ASSERT(mCurTypeDef->mSystem != NULL); mCurActualTypeDef = prevRevisionTypeDef; doInsertNew = false; - } + } } else { mSystem->TrackName(mCurTypeDef); - bfParser->mTypeDefs.Add(mCurTypeDef); + bfParser->mTypeDefs.Add(mCurTypeDef); } if (doInsertNew) @@ -1884,14 +1909,14 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef); } - BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mCurTypeDef->mHash, typeDeclaration, - typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef); - + BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mCurTypeDef->mHash, typeDeclaration, + typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef); + BF_ASSERT(mCurTypeDef->mNameEx == NULL); - + if (mCurTypeDef->mGenericParamDefs.size() != 0) { - mCurTypeDef->mNameEx = mSystem->GetAtom(StrFormat("%s`%d", mCurTypeDef->mName->mString.mPtr, numGenericParams)); + mCurTypeDef->mNameEx = mSystem->GetAtom(StrFormat("%s`%d", mCurTypeDef->mName->mString.mPtr, numGenericParams)); } else { @@ -1899,7 +1924,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) mCurTypeDef->mNameEx->mRefCount++; } if (!fullName.IsEmpty()) - { + { if (mCurTypeDef->IsGlobalsContainer()) { mCurTypeDef->mFullNameEx.Set(fullName.mParts, fullName.mSize, &mCurTypeDef->mNameEx, 1); @@ -1907,10 +1932,10 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) else { mCurTypeDef->mFullNameEx = fullName; - mCurTypeDef->mFullNameEx.mParts[mCurTypeDef->mFullNameEx.mSize - 1] = mCurTypeDef->mNameEx; + mCurTypeDef->mFullNameEx.mParts[mCurTypeDef->mFullNameEx.mSize - 1] = mCurTypeDef->mNameEx; } } - + if (typeDeclaration->mAutoCtor != NULL) VisitChildNoRef(typeDeclaration->mAutoCtor); @@ -1924,7 +1949,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) else if (auto defineTokenNode = BfNodeDynCast(typeDeclaration->mDefineNode)) { if (defineTokenNode->GetToken() == BfToken_Semicolon) - { + { if (typeDeclaration->mAutoCtor == NULL) mCurTypeDef->mIsOpaque = true; } @@ -1958,19 +1983,19 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration) else prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Internals_Changed; } - + // There's a new type with this name... if ((prevRevisionTypeDef == NULL) && (!isAutoCompleteTempType)) { mCurTypeDef->mName->mAtomUpdateIdx = ++mSystem->mAtomUpdateIdx; - } + } } void BfDefBuilder::FinishTypeDef(bool wantsToString) { auto bfSource = mCurTypeDef->mSource; bool isAlias = mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias; - bool hasCtor = false; + bool hasCtor = false; bool needsDefaultCtor = (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (!mCurTypeDef->mIsStatic) && (!isAlias); bool hasDefaultCtor = false; BfMethodDef* ctorClear = NULL; @@ -1982,16 +2007,16 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) BfMethodDef* dynamicCastMethod = NULL; BfMethodDef* toStringMethod = NULL; BfMethodDef* getUnderlyingMethod = 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* strictEqualsMethod = NULL; + BfMethodDef* strictEqualsMethod = NULL; bool needsStaticInit = false; for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++) { auto method = mCurTypeDef->mMethods[methodIdx]; - + auto _SetMethod = [&](BfMethodDef*& setMethodDef, BfMethodDef* methodDef) { if ((setMethodDef != NULL) && (setMethodDef->mMethodDeclaration == NULL)) @@ -2020,7 +2045,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) _SetMethod(staticCtor, method); } - else + else { hasCtor = true; if (method->mParams.size() == 0) @@ -2028,19 +2053,19 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) auto ctorDeclaration = (BfConstructorDeclaration*)method->mMethodDeclaration; if (method->mHasAppend) - { + { mCurTypeDef->mHasAppendCtor = true; auto methodDef = new BfMethodDef(); mCurTypeDef->mMethods.Insert(methodIdx + 1, methodDef); BF_ASSERT(mCurDeclaringTypeDef != NULL); - methodDef->mDeclaringType = mCurDeclaringTypeDef; + methodDef->mDeclaringType = mCurDeclaringTypeDef; methodDef->mName = BF_METHODNAME_CALCAPPEND; - methodDef->mProtection = BfProtection_Public; + methodDef->mProtection = BfProtection_Public; methodDef->mMethodType = BfMethodType_CtorCalcAppend; methodDef->mIsMutating = method->mIsMutating; methodDef->mIsNoSplat = true; - + methodDef->mMethodDeclaration = method->mMethodDeclaration; methodDef->mReturnTypeRef = mSystem->mDirectIntTypeRef; methodDef->mIsStatic = true; @@ -2057,7 +2082,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) methodDef->mParams.push_back(newParam); } - // Insert a 'appendIdx' + // Insert a 'appendIdx' BfParameterDef* newParam = new BfParameterDef(); newParam->mName = "appendIdx"; newParam->mTypeRef = mSystem->mDirectRefIntTypeRef; @@ -2084,7 +2109,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) Fail("Only one static constructor is allowed", method->mMethodDeclaration); method->mIsStatic = false; } - + _SetMethod(staticDtor, method); } else @@ -2094,10 +2119,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) Fail("Only one destructor is allowed", method->mMethodDeclaration); method->mIsStatic = false; } - _SetMethod(dtor, method); + _SetMethod(dtor, method); } - if (method->mParams.size() != 0) + if (method->mParams.size() != 0) Fail("Destructors cannot declare parameters", method->GetMethodDeclaration()->mParams[0]); } else if (method->mMethodType == BfMethodType_Normal) @@ -2118,7 +2143,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) if (method->mName == BF_METHODNAME_DYNAMICCAST) _SetMethod(dynamicCastMethod, method); if (method->mName == BF_METHODNAME_TO_STRING) - _SetMethod(toStringMethod, method); + _SetMethod(toStringMethod, method); } } else if (method->mMethodType == BfMethodType_PropertyGetter) @@ -2127,13 +2152,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) _SetMethod(getUnderlyingMethod, method); } else if ((method->mMethodType == BfMethodType_Operator) && - (method->mIsStatic) && + (method->mIsStatic) && (method->mParams.size() == 2)) { if (auto operatorDecl = BfNodeDynCast(method->mMethodDeclaration)) { if (operatorDecl->mBinOp == BfBinaryOp_Equality) - { + { // This is a conservative check. It's okay to add a system-defined equals method even if we don't need it. if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) && (method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString())) @@ -2141,13 +2166,13 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) _SetMethod(equalsOpMethod, method); } } - } + } } if ((method->mImportKind == BfImportKind_Import_Dynamic) || (method->mImportKind == BfImportKind_Import_Unknown)) needsStaticInit = true; } - + if (mCurTypeDef->IsExtension()) needsDefaultCtor = false; @@ -2160,7 +2185,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) { if (field->mIsStatic) { - // Resolve-only compiler wants to visit const initializers in a static ctor method, but we don't + // Resolve-only compiler wants to visit const initializers in a static ctor method, but we don't // want to create it for the actual binary if ((!field->mIsConst) || (mSystem->mIsResolveOnly)) { @@ -2168,11 +2193,16 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) if (field->mFieldDeclaration != NULL) { if (field->GetFieldDeclaration()->mInitializer != NULL) - { + { needsStaticInit = true; } if (field->GetFieldDeclaration()->mFieldDtor != NULL) needsStaticDtor = true; + if (field->mIsAppend) + { + needsStaticInit = true; + needsStaticDtor = true; + } } } @@ -2193,11 +2223,16 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) } } } - else + else { hasNonStaticField = true; if (field->GetInitializer() != NULL) needsDefaultCtor = true; + if (field->mIsAppend) + { + needsDefaultCtor = true; + needsDtor = true; + } if (auto fieldDecl = field->GetFieldDeclaration()) { if (fieldDecl->mFieldDtor != NULL) @@ -2205,38 +2240,38 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) } } } - + bool needsDynamicCastMethod = dynamicCastMethod == NULL; if (mCurTypeDef->mIsFunction) { wantsToString = false; needsEqualsMethod = false; - needsDefaultCtor = false; + needsDefaultCtor = false; needsDynamicCastMethod = false; } if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic) && (ctorClear == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "", mIsComptime); - methodDef->mIsMutating = true; + methodDef->mIsMutating = true; } if ((needsDtor) && (dtor == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "", mIsComptime); } if ((needsStaticDtor) && (staticDtor == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "", mIsComptime); } if ((needsStaticInit) && (staticCtor == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "", mIsComptime); } - + bool makeCtorPrivate = hasCtor; if (mCurTypeDef->mTypeCode == BfTypeCode_TypeAlias) @@ -2251,22 +2286,21 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) prot = BfProtection_Hidden; // Create default constructor. If it's the only constructor then make it public, - // otherwise make it private so we can still internally use it but the user can't + // otherwise make it private so we can still internally use it but the user can't auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, prot, false, "", mIsComptime); methodDef->mIsMutating = true; } - bool isAutocomplete = false; if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL)) isAutocomplete = true; - - //TODO: Don't do this for the autocomplete pass + + //TODO: Don't do this for the autocomplete pass if ((needsDynamicCastMethod) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface) && (mCurTypeDef->mTypeCode != BfTypeCode_Extension) && (!mCurTypeDef->mIsStatic) && (!isAutocomplete) && (!isAlias)) - { + { AddDynamicCastMethods(mCurTypeDef); - } + } bool isPayloadEnum = false; if (mCurTypeDef->mTypeCode == BfTypeCode_Enum) @@ -2287,7 +2321,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) if (mCurTypeDef->mTypeCode != BfTypeCode_Interface) { if ((hasStaticField) && (staticMarkMethod == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC, mIsComptime); methodDef->mIsNoReflect = true; } @@ -2299,7 +2333,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) } if ((hasNonStaticField) && (markMethod == NULL)) - { + { auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS, mIsComptime); methodDef->mIsVirtual = true; methodDef->mIsOverride = true; @@ -2308,12 +2342,12 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) mCurTypeDef->mHasOverrideMethods = true; } } - + if (toStringMethod != NULL) wantsToString = false; - + if ((mCurTypeDef->mTypeCode == BfTypeCode_Enum) && (!isPayloadEnum) && (getUnderlyingMethod == NULL)) - { + { auto methodDef = new BfMethodDef(); mCurTypeDef->mMethods.push_back(methodDef); BF_ASSERT(mCurDeclaringTypeDef != NULL); @@ -2385,9 +2419,9 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) mCurTypeDef->mHasOverrideMethods = true; methodDef->mAddedAfterEmit = mIsComptime; } - + if ((needsEqualsMethod) && (equalsMethod == NULL) && (equalsOpMethod == NULL)) - { + { auto methodDef = new BfMethodDef(); mCurTypeDef->mMethods.push_back(methodDef); BF_ASSERT(mCurDeclaringTypeDef != NULL); @@ -2395,7 +2429,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) methodDef->mName = BF_METHODNAME_DEFAULT_EQUALS; methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef; methodDef->mProtection = BfProtection_Private; - methodDef->mIsStatic = true; + methodDef->mIsStatic = true; AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs"); AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs"); methodDef->mAddedAfterEmit = mIsComptime; @@ -2430,12 +2464,12 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) { // Add in name so the hand-created methods can be compared by hash auto methodDef = mCurTypeDef->mMethods[methodIdx]; - methodDef->mIdx = methodIdx; - methodDef->mFullHash = HashString(methodDef->mName, methodDef->mFullHash); + methodDef->mIdx = methodIdx; + methodDef->mFullHash = HashString(methodDef->mName, methodDef->mFullHash); if (mSignatureHashCtx != NULL) mSignatureHashCtx->MixinStr(methodDef->mName); - - if ((methodDef->mAlwaysInline) || + + if ((methodDef->mAlwaysInline) || (methodDef->mHasAppend) || (methodDef->mMethodType == BfMethodType_Mixin)) inlineHashCtx.Mixin(methodDef->mFullHash); @@ -2443,14 +2477,14 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString) if (mFullRefresh) methodDef->mCodeChanged = true; } - + mCurTypeDef->mInlineHash = inlineHashCtx.Finish128(); if (mSignatureHashCtx != NULL) { mCurTypeDef->mSignatureHash = mSignatureHashCtx->Finish128(); // We need to hash the signature in here because the preprocessor settings - // may change so the text is the same but the signature changes + // may change so the text is the same but the signature changes // so fullHash needs to change too mFullHashCtx->Mixin(mCurTypeDef->mSignatureHash); } @@ -2470,21 +2504,21 @@ void BfDefBuilder::Visit(BfUsingDirective* usingDirective) if (mResolvePassData != NULL) mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(usingDirective); - String usingString = usingDirective->mNamespace->ToString(); + String usingString = usingDirective->mNamespace->ToString(); BfAtomComposite usingComposite; - mSystem->ParseAtomComposite(usingString, usingComposite, true); - + mSystem->ParseAtomComposite(usingString, usingComposite, true); + if (!mNamespaceSearch.Contains(usingComposite)) mNamespaceSearch.Insert(0, usingComposite); else - mSystem->ReleaseAtomComposite(usingComposite); + mSystem->ReleaseAtomComposite(usingComposite); } void BfDefBuilder::Visit(BfUsingModDirective* usingDirective) { if (mResolvePassData != NULL) mResolvePassData->mExteriorAutocompleteCheckNodes.push_back(usingDirective); - + if (usingDirective->mModToken->mToken == BfToken_Internal) { if (usingDirective->mTypeRef != NULL) @@ -2509,7 +2543,7 @@ void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration) { auto blockNode = BfNodeDynCast(namespaceDeclaration->mBody); bool isFileLevel = (blockNode == NULL) && (namespaceDeclaration->mBody != NULL); - + if (mNamespaceBlockDepth < mFileLevelNamespaceState.mSize) { auto& prevNamespaceState = mFileLevelNamespaceState[mNamespaceBlockDepth]; @@ -2523,7 +2557,7 @@ void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration) NamespaceState namespaceState; namespaceState.mNamespace = mNamespace; namespaceState.mNamespaceSearchCount = (int)mNamespaceSearch.size(); - + if (isFileLevel) { while (mNamespaceBlockDepth >= mFileLevelNamespaceState.mSize) @@ -2542,28 +2576,28 @@ void BfDefBuilder::Visit(BfNamespaceDeclaration* namespaceDeclaration) { BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft); mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1); - + if (!mNamespaceSearch.Contains(mNamespace)) { mSystem->RefAtomComposite(mNamespace); - mNamespaceSearch.Insert(0, mNamespace); + mNamespaceSearch.Insert(0, mNamespace); } mSystem->ReleaseAtom(namespaceAtom); break; } BfAtom* namespaceAtom = mSystem->GetAtom(namespaceLeft.Substring(0, dotIdx)); - mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1); + mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1); namespaceLeft = namespaceLeft.Substring(dotIdx + 1); - + if (!mNamespaceSearch.Contains(mNamespace)) { mSystem->RefAtomComposite(mNamespace); mNamespaceSearch.Insert(0, mNamespace); } - mSystem->ReleaseAtom(namespaceAtom); + mSystem->ReleaseAtom(namespaceAtom); } - + if (blockNode != NULL) { mNamespaceBlockDepth++; @@ -2583,4 +2617,4 @@ void BfDefBuilder::Visit(BfBlock* block) void BfDefBuilder::Visit(BfRootNode* rootNode) { VisitMembers(rootNode); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfDefBuilder.h b/IDEHelper/Compiler/BfDefBuilder.h index 39fc134f..15ef96e1 100644 --- a/IDEHelper/Compiler/BfDefBuilder.h +++ b/IDEHelper/Compiler/BfDefBuilder.h @@ -39,14 +39,14 @@ public: Array mInternalAccessSet; HashContext* mFullHashCtx; HashContext* mSignatureHashCtx; - + Array mFileLevelNamespaceState; - int mNamespaceBlockDepth; + int mNamespaceBlockDepth; public: void ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array& genericParams, Array* externConstraintDefs, int outerGenericSize, bool isInGeneric); BfProtection GetProtection(BfAstNode* protectionNode); - bool WantsNode(BfAstNode* wholeNode, BfAstNode* startNode = NULL, int addLen = 0); + bool WantsNode(BfAstNode* wholeNode, BfAstNode* startNode = NULL, int addLen = 0); //static BfNamedTypeReference* AllocTypeReference(BfSource* bfSource, const StringImpl& typeName); //static BfResolvedTypeReference* AllocTypeReference(BfSource* bfSource, BfType* type); static BfFieldDef* AddField(BfTypeDef* typeDef, BfTypeReference* typeRef, const StringImpl& name); @@ -67,18 +67,18 @@ public: ~BfDefBuilder(); void Process(BfPassInstance* passInstance, BfSource* bfSource, bool fullRefresh); - void RemoveDefsFrom(BfSource* bfSource); - + void RemoveDefsFrom(BfSource* bfSource); + virtual void Visit(BfIdentifierNode* identifier) override; virtual void Visit(BfMethodDeclaration* methodDeclaration) override; virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override; virtual void Visit(BfPropertyDeclaration* propertyDeclaration) override; - virtual void Visit(BfFieldDeclaration* fieldDeclaration) override; + virtual void Visit(BfFieldDeclaration* fieldDeclaration) override; virtual void Visit(BfEnumCaseDeclaration* enumCaseDeclaration) override; virtual void Visit(BfTypeDeclaration* typeDeclaration) override; virtual void Visit(BfUsingDirective* usingDirective) override; virtual void Visit(BfUsingModDirective* usingDirective) override; - virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override; + virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override; virtual void Visit(BfBlock* block) override; virtual void Visit(BfRootNode* rootNode) override; }; diff --git a/IDEHelper/Compiler/BfDeferEvalChecker.cpp b/IDEHelper/Compiler/BfDeferEvalChecker.cpp index 2aff7225..b583237f 100644 --- a/IDEHelper/Compiler/BfDeferEvalChecker.cpp +++ b/IDEHelper/Compiler/BfDeferEvalChecker.cpp @@ -1,19 +1,38 @@ #include "BfDeferEvalChecker.h" +#include "BfUtil.h" USING_NS_BF; BfDeferEvalChecker::BfDeferEvalChecker() { + mRootNode = NULL; mNeedsDeferEval = false; mDeferLiterals = true; mDeferDelegateBind = true; } +void BfDeferEvalChecker::Check(BfAstNode* node) +{ + if (auto namedNode = BfNodeDynCastExact(node)) + node = namedNode->mExpression; + + if (node == NULL) + return; + + SetAndRestoreValue rootNode(mRootNode, node); + node->Accept(this); +} + void BfDeferEvalChecker::Visit(BfAstNode* attribExpr) { mNeedsDeferEval = false; } +void BfDeferEvalChecker::Visit(BfAttributedExpression* attributedExpr) +{ + VisitChild(attributedExpr->mExpression); +} + void BfDeferEvalChecker::Visit(BfInitializerExpression* collectionInitExpr) { VisitChild(collectionInitExpr->mTarget); @@ -27,16 +46,16 @@ void BfDeferEvalChecker::Visit(BfLiteralExpression* literalExpr) case BfTypeCode_Boolean: case BfTypeCode_Char8: case BfTypeCode_Int8: - case BfTypeCode_UInt8: - case BfTypeCode_Int16: + case BfTypeCode_UInt8: + case BfTypeCode_Int16: case BfTypeCode_UInt16: case BfTypeCode_Int32: - case BfTypeCode_UInt32: - case BfTypeCode_Int64: + case BfTypeCode_UInt32: + case BfTypeCode_Int64: case BfTypeCode_UInt64: - case BfTypeCode_IntPtr: + case BfTypeCode_IntPtr: case BfTypeCode_UIntPtr: - case BfTypeCode_IntUnknown: + case BfTypeCode_IntUnknown: case BfTypeCode_UIntUnknown: if (mDeferLiterals) mNeedsDeferEval = true; @@ -44,11 +63,10 @@ void BfDeferEvalChecker::Visit(BfLiteralExpression* literalExpr) default: mNeedsDeferEval = false; } - } void BfDeferEvalChecker::Visit(BfCastExpression* castExpr) -{ +{ if (auto namedTypeRef = BfNodeDynCastExact(castExpr->mTypeRef)) { if (namedTypeRef->ToString() == "ExpectedType") @@ -103,11 +121,11 @@ void BfDeferEvalChecker::Visit(BfDelegateBindExpression* delegateBindExpr) } void BfDeferEvalChecker::Visit(BfConditionalExpression* condExpr) -{ +{ VisitChild(condExpr->mConditionExpression); bool prev = mNeedsDeferEval; VisitChild(condExpr->mTrueExpression); - prev |= mNeedsDeferEval; + prev |= mNeedsDeferEval; VisitChild(condExpr->mFalseExpression); mNeedsDeferEval |= prev; } @@ -135,7 +153,7 @@ void BfDeferEvalChecker::Visit(BfObjectCreateExpression * objCreateExpr) { if (objCreateExpr->mTypeRef->IsExact()) mNeedsDeferEval = true; - } + } } void BfDeferEvalChecker::Visit(BfBinaryOperatorExpression* binOpExpr) @@ -151,14 +169,14 @@ void BfDeferEvalChecker::Visit(BfBinaryOperatorExpression* binOpExpr) case BfBinaryOp_BitwiseOr: case BfBinaryOp_ExclusiveOr: case BfBinaryOp_LeftShift: - case BfBinaryOp_RightShift: + case BfBinaryOp_RightShift: case BfBinaryOp_GreaterThan: case BfBinaryOp_LessThan: case BfBinaryOp_GreaterThanOrEqual: case BfBinaryOp_LessThanOrEqual: { VisitChild(binOpExpr->mLeft); - bool prev = mNeedsDeferEval; + bool prev = mNeedsDeferEval; VisitChild(binOpExpr->mRight); mNeedsDeferEval |= prev; } @@ -169,8 +187,13 @@ void BfDeferEvalChecker::Visit(BfBinaryOperatorExpression* binOpExpr) } void BfDeferEvalChecker::Visit(BfDefaultExpression* defaultExpr) -{ +{ if (defaultExpr->mTypeRef == NULL) mNeedsDeferEval = true; } +void BfDeferEvalChecker::Visit(BfVariableDeclaration* varDecl) +{ + if (varDecl != mRootNode) + mNeedsDeferEval = true; +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfDeferEvalChecker.h b/IDEHelper/Compiler/BfDeferEvalChecker.h index 13e4a6c8..7d46fb15 100644 --- a/IDEHelper/Compiler/BfDeferEvalChecker.h +++ b/IDEHelper/Compiler/BfDeferEvalChecker.h @@ -8,16 +8,20 @@ NS_BF_BEGIN class BfDeferEvalChecker : public BfStructuralVisitor { public: + BfAstNode* mRootNode; bool mNeedsDeferEval; bool mDeferDelegateBind; - bool mDeferLiterals; + bool mDeferLiterals; public: BfDeferEvalChecker(); + void Check(BfAstNode* node); + virtual void Visit(BfAstNode* node) override; - virtual void Visit(BfInitializerExpression* collectionInitExpr); + virtual void Visit(BfAttributedExpression* attributedExpr) override; + virtual void Visit(BfInitializerExpression* collectionInitExpr) override; virtual void Visit(BfLiteralExpression* literalExpr) override; virtual void Visit(BfCastExpression* castExpr) override; virtual void Visit(BfParenthesizedExpression* parenExpr) override; @@ -29,9 +33,9 @@ public: virtual void Visit(BfConditionalExpression* condExpr) override; virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override; virtual void Visit(BfObjectCreateExpression* objCreateExpr) override; - virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override; + virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override; virtual void Visit(BfDefaultExpression* defaultExpr) override; + virtual void Visit(BfVariableDeclaration* varDecl) override; }; - NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfDemangler.cpp b/IDEHelper/Compiler/BfDemangler.cpp index 9df61596..4747d6f1 100644 --- a/IDEHelper/Compiler/BfDemangler.cpp +++ b/IDEHelper/Compiler/BfDemangler.cpp @@ -11,7 +11,7 @@ static char SafeGetChar(const StringImpl& str, int idx) DemangleBase::DemangleBase() { - mCurIdx = 0; + mCurIdx = 0; mFailed = false; mLanguage = DbgLanguage_Unknown; mInArgs = false; @@ -20,30 +20,30 @@ DemangleBase::DemangleBase() bool DemangleBase::Failed() { - //BF_DBG_FATAL("DwDemangler::Failed"); + //BF_DBG_FATAL("DwDemangler::Failed"); mFailed = true; return false; } void DemangleBase::Require(bool result) { - //BF_ASSERT(result); + //BF_ASSERT(result); if (!result) { - mFailed = true; + mFailed = true; } } ////////////////////////////////////////////////////////////////////////// DwDemangler::DwDemangler() -{ +{ mOmitSubstituteAdd = false; mIsFirstName = true; mTemplateDepth = 0; mCaptureTargetType = false; mFunctionPopSubstitute = false; - mRawDemangle = false; + mRawDemangle = false; } #define RETURN_STR(strVal) do { outName = strVal; return true; } while(false) @@ -54,11 +54,11 @@ bool DwDemangler::DemangleBuiltinType(StringImpl& outName) switch (firstChar) { case 'v': - RETURN_STR("void"); + RETURN_STR("void"); case 'w': RETURN_STR("wchar_t"); case 'b': - RETURN_STR("bool"); + RETURN_STR("bool"); case 'a': if (mLanguage == DbgLanguage_Beef) RETURN_STR("int8"); @@ -95,7 +95,7 @@ bool DwDemangler::DemangleBuiltinType(StringImpl& outName) RETURN_STR("uint32"); else RETURN_STR("uint"); - case 'y': + case 'y': RETURN_STR("ulong"); case 'c': if (mLanguage == DbgLanguage_Beef) @@ -149,9 +149,8 @@ bool DwDemangler::DemangleArrayType(StringImpl& outName) /*auto firstChar = SafeGetChar(mMangledName, mCurIdx++); switch (firstChar) { - case 'A': + case 'A': { - } break; default: @@ -169,7 +168,7 @@ bool DwDemangler::DemangleClassEnumType(StringImpl& outName) } bool DwDemangler::DemangleFunction(StringImpl& outName) -{ +{ bool wantsReturnValue = false; //String outName; bool hasTemplateArgs; @@ -189,7 +188,7 @@ bool DwDemangler::DemangleFunction(StringImpl& outName) { DwDemangler subDemangler; outName.Remove(0, lastAt + 1); - outName = subDemangler.Demangle(outName); + outName = subDemangler.Demangle(outName); return true; } int lastDot = (int)outName.LastIndexOf('.'); @@ -197,7 +196,7 @@ bool DwDemangler::DemangleFunction(StringImpl& outName) outName.RemoveToEnd(lastDot); return true; } - + // New if (mFunctionPopSubstitute) { @@ -206,7 +205,7 @@ bool DwDemangler::DemangleFunction(StringImpl& outName) mSubstituteList.pop_back(); mFunctionPopSubstitute = false; } - + if (mCurIdx < (int) mMangledName.length()) { //TODO: Needed? Caused a crash. mSubstituteList.pop_back(); // Remove method name @@ -231,15 +230,15 @@ bool DwDemangler::DemangleFunction(StringImpl& outName) for (int paramIdx = 0; mCurIdx < (int)mMangledName.length(); paramIdx++) { - if (SafeGetChar(mMangledName, mCurIdx) == 'E') - break; + if (SafeGetChar(mMangledName, mCurIdx) == 'E') + break; if (needsComma) outName += ", "; - + StringT<256> paramType; Require(DemangleType(paramType)); - + bool atEnd = mCurIdx >= (int) mMangledName.length(); if ((paramIdx == 0) && (wantsReturnValue)) { @@ -323,7 +322,7 @@ bool DwDemangler::DemangleType(StringImpl& outName) auto firstChar = SafeGetChar(mMangledName, mCurIdx++); switch (firstChar) - { + { case 'D': { auto nextChar = SafeGetChar(mMangledName, mCurIdx++); @@ -376,13 +375,13 @@ bool DwDemangler::DemangleType(StringImpl& outName) outName = modName + " " + outName; return true; } - break; - //TODO: 'C', 'G', 'U' + break; + //TODO: 'C', 'G', 'U' default: mCurIdx--; break; - } - + } + if (DemangleBuiltinType(outName)) return true; if (DemangleFunctionType(outName)) @@ -402,11 +401,11 @@ bool DwDemangler::DemangleType(StringImpl& outName) if (DemangleClassEnumType(outName)) return true; //TODO: DemangleArrayType - //TODO: DemanglePointerToMemberType + //TODO: DemanglePointerToMemberType if (DemangleTemplateParam(outName)) return true; //TODO: TemplateTemplateParam - //TODO: DeclType + //TODO: DeclType return false; } @@ -447,9 +446,8 @@ bool DwDemangler::DemangleNestedName(StringImpl& outName) { case 'N': { - } - break; + break; } mCurIdx--; @@ -480,18 +478,17 @@ bool DwDemangler::DemangleRefQualifier(StringImpl& outName) case 'R': RETURN_STR("&"); case 'O': - RETURN_STR("&&"); + RETURN_STR("&&"); } mCurIdx--; return false; } - bool DwDemangler::DemangleOperatorName(StringImpl& outName) { - auto firstChar = SafeGetChar(mMangledName, mCurIdx++); + auto firstChar = SafeGetChar(mMangledName, mCurIdx++); StringT<64> opCode; - opCode += firstChar; + opCode += firstChar; opCode += SafeGetChar(mMangledName, mCurIdx++); StringT<64> opName; @@ -544,7 +541,7 @@ bool DwDemangler::DemangleOperatorName(StringImpl& outName) else if (opCode == "eq") opName = "=="; else if (opCode == "ne") - opName = "!="; + opName = "!="; else if (opCode == "lt") opName = "<"; else if (opCode == "gt") @@ -612,15 +609,15 @@ bool DwDemangler::DemangleOperatorName(StringImpl& outName) if (!opName.empty()) outName += "operator" + opName; //mSubstituteList.push_back(outName); - + return true; } bool DwDemangler::DemangleSourceName(StringImpl& outName) { - auto c = SafeGetChar(mMangledName, mCurIdx); + auto c = SafeGetChar(mMangledName, mCurIdx); if ((c >= '0') && (c <= '9')) - { + { int nameLen = 0; while (mCurIdx < (int) mMangledName.length()) { @@ -644,7 +641,7 @@ bool DwDemangler::DemangleSourceName(StringImpl& outName) return true; } - return false; + return false; } bool DwDemangler::DemangleUnqualifiedName(StringImpl& outName) @@ -652,12 +649,12 @@ bool DwDemangler::DemangleUnqualifiedName(StringImpl& outName) if (DemangleOperatorName(outName)) // Also handles ctor/dtor return true; if (DemangleSourceName(outName)) - return true; + return true; return false; } bool DwDemangler::DemangleEnd() -{ +{ auto firstChar = SafeGetChar(mMangledName, mCurIdx++); if (firstChar == 'E') return true; @@ -704,7 +701,6 @@ bool DwDemangler::DemangleExprPriamry(StringImpl& outName) return false; } - bool DwDemangler::DemangleTemplateArg(StringImpl& outName) { if (DemangleType(outName)) @@ -716,7 +712,7 @@ bool DwDemangler::DemangleTemplateArg(StringImpl& outName) } bool DwDemangler::DemangleTemplateArgs(StringImpl& outName) -{ +{ auto firstChar = SafeGetChar(mMangledName, mCurIdx++); if (firstChar == 'I') { @@ -728,7 +724,7 @@ bool DwDemangler::DemangleTemplateArgs(StringImpl& outName) bool inParamPack = false; bool foundEnd = false; bool needsComma = false; - + outName = "<"; for (int argIdx = 0; true; argIdx++) { @@ -737,9 +733,9 @@ bool DwDemangler::DemangleTemplateArgs(StringImpl& outName) if (DemangleEnd()) { - if (inParamPack) + if (inParamPack) { - inParamPack = false; + inParamPack = false; continue; } else @@ -782,7 +778,7 @@ bool DwDemangler::DemangleSubstitution(StringImpl& outName) bool hadChars = 0; while (true) { - char idxChar = SafeGetChar(mMangledName, mCurIdx++); + char idxChar = SafeGetChar(mMangledName, mCurIdx++); if (idxChar == 't') { DemangleUnqualifiedName(outName); @@ -804,7 +800,7 @@ bool DwDemangler::DemangleSubstitution(StringImpl& outName) { RETURN_STR("std.string"); } - if (idxChar == 'i') + if (idxChar == 'i') { RETURN_STR("std.basic_istream>"); } @@ -853,7 +849,7 @@ bool DwDemangler::DemangleTemplateParam(StringImpl& outName) bool hadChars = 0; while (true) { - char idxChar = SafeGetChar(mMangledName, mCurIdx++); + char idxChar = SafeGetChar(mMangledName, mCurIdx++); if (idxChar == '?') break; if (idxChar == '_') @@ -887,7 +883,7 @@ bool DwDemangler::DemangleUnscopedName(StringImpl& outName) if (DemangleUnqualifiedName(outName)) return true; if (DemangleSubstitution(outName)) - return true; + return true; return false; } @@ -899,17 +895,17 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) switch (firstChar) { case 'N': // NestedName - { + { StringT<64> cvQualifier; if (DemangleCVQualifiers(cvQualifier)) outName += cvQualifier + " "; StringT<64> refQualifier; if (DemangleRefQualifier(refQualifier)) - outName += refQualifier + " "; + outName += refQualifier + " "; int nameCount = 0; while ((!DemangleEnd()) && (!mFailed)) - { + { StringT<128> unqualifiedName; mOmitSubstituteAdd = false; if ((DemangleUnscopedName(unqualifiedName)) || @@ -917,7 +913,7 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) { if (outHasTemplateArgs != NULL) *outHasTemplateArgs = false; - if (nameCount > 0) + if (nameCount > 0) { if (mLanguage == DbgLanguage_Beef) outName += "."; @@ -932,7 +928,7 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) nameCount++; continue; } - + StringT<128> templateArgs; if (DemangleTemplateArgs(templateArgs)) { @@ -974,11 +970,11 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) } continue; } - + Failed(); break; } - + return true; } break; @@ -997,7 +993,7 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) { if (outHasTemplateArgs != NULL) *outHasTemplateArgs = true; - outName += templateArgs; + outName += templateArgs; } if ((outName.length() > 0) && (outName[outName.length() - 1] == '.')) @@ -1012,11 +1008,11 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) else { Failed(); - } + } } return true; - } + } if (DemangleLocalName(outName)) return true; @@ -1026,7 +1022,7 @@ bool DwDemangler::DemangleName(StringImpl& outName, bool* outHasTemplateArgs) String DwDemangler::Demangle(const StringImpl& mangledName) { - BF_ASSERT(mCurIdx == 0); + BF_ASSERT(mCurIdx == 0); /*String overrideVal = "_ZZL9DumpStatsP16TCMalloc_PrinteriE3MiB"; //String overrideVal = "_ZN3Hey4Dude3Bro9TestClass7MethodBEivf"; @@ -1047,16 +1043,16 @@ String DwDemangler::Demangle(const StringImpl& mangledName) //"__ZN6System6String6ConcatEU6paramsPNS_6Array1INS_6ObjectEEE"; //_ZNSt3mapI3HeyfSt4lessIiESaISt4pairIKifEEEixES_S0_S1_S2_S3_S4_S5_S6_ String overrideDemangled; - if (mangledName != overrideVal) + if (mangledName != overrideVal) { BfDemangler demangler; overrideDemangled = demangler.Demangle(overrideVal); }*/ - - mMangledName = mangledName; + + mMangledName = mangledName; String outStr; - + if (mangledName.length() < 3) return mangledName; @@ -1098,7 +1094,7 @@ String DwDemangler::Demangle(const StringImpl& mangledName) { mCurIdx++; char typeChar2 = SafeGetChar(mangledName, mCurIdx++); - if (typeChar2 == 'S') + if (typeChar2 == 'S') { // typeinfo } @@ -1110,7 +1106,7 @@ String DwDemangler::Demangle(const StringImpl& mangledName) { return mangledName; } - } + } else if (typeChar == 'S') { mayHaveParams = false; @@ -1148,12 +1144,12 @@ MsDemangler::MsDemangler() } bool MsDemangler::DemangleString(StringImpl& outName) -{ +{ while (true) { char c = SafeGetChar(mMangledName, mCurIdx++); if ((c == '!') || (c == '?')) - return Failed(); + return Failed(); if (c == '@') break; outName.Append(c); @@ -1175,7 +1171,7 @@ bool MsDemangler::DemangleTemplateName(StringImpl& outName, String* primaryName) { String paramType; if (!DemangleType(paramType)) - break; + break; if (paramIdx > 0) outName += ", "; outName += paramType; @@ -1185,21 +1181,20 @@ bool MsDemangler::DemangleTemplateName(StringImpl& outName, String* primaryName) return true; } - bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName) -{ +{ for (int nameIdx = 0; true; nameIdx++) { if (mFailed) return false; - char c = SafeGetChar(mMangledName, mCurIdx++); + char c = SafeGetChar(mMangledName, mCurIdx++); if (c == '@') return true; /*{ - if (curScope.length() == 0) - return true; + if (curScope.length() == 0) + return true; if (nameIdx == 0) { if (primaryName != NULL) @@ -1220,11 +1215,11 @@ bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName) { c = SafeGetChar(mMangledName, mCurIdx++); if (c == '$') - { + { SubstituteList oldSubList = mSubstituteList; mSubstituteList.Clear(); DemangleTemplateName(namePart, /*primaryName*/NULL); - mSubstituteList = oldSubList; + mSubstituteList = oldSubList; } else if (c == '?') { @@ -1236,10 +1231,9 @@ bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName) int num = DemangleNumber(); outName = StrFormat("%d", num); } - } else if ((c >= '0') && (c <= '9')) - { + { int subIdx = c - '0'; if (subIdx < mSubstituteList.size()) { @@ -1252,25 +1246,25 @@ bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName) } else { - mCurIdx--; - Require(DemangleString(namePart)); + mCurIdx--; + Require(DemangleString(namePart)); } if (nameIdx == 0) - { + { //We moved this down so we get the template args for the ctor name /*if ((primaryName != NULL) && (primaryName->empty())) *primaryName = namePart;*/ outName = namePart; if ((primaryName != NULL) && (primaryName->empty())) - *primaryName = namePart; + *primaryName = namePart; } else if (mLanguage == DbgLanguage_Beef) { if ((mBeefFixed) && (namePart == "bf")) namePart.Clear(); - if (!namePart.IsEmpty()) + if (!namePart.IsEmpty()) outName = namePart + "." + outName; } else @@ -1285,7 +1279,7 @@ bool MsDemangler::DemangleScopedName(StringImpl& outName, String* primaryName) bool MsDemangler::DemangleModifiedType(StringImpl& outName, bool isPtr) { String modifier; - DemangleCV(modifier); + DemangleCV(modifier); char c = SafeGetChar(mMangledName, mCurIdx); if (c == 'Y') // Sized array @@ -1323,7 +1317,7 @@ bool MsDemangler::DemangleType(StringImpl& outName) return false; switch (c) - { + { case '0': case '1': case '2': @@ -1418,7 +1412,7 @@ bool MsDemangler::DemangleType(StringImpl& outName) char c = SafeGetChar(mMangledName, mCurIdx++); if (c == 'C') { - String modifier; + String modifier; DemangleCV(modifier); DemangleType(outName); outName = modifier + " " + outName; @@ -1426,7 +1420,7 @@ bool MsDemangler::DemangleType(StringImpl& outName) } else if (c == 'Q') { - String modifier; + String modifier; DemangleCV(modifier); DemangleType(outName); outName = modifier + " " + outName; @@ -1435,7 +1429,6 @@ bool MsDemangler::DemangleType(StringImpl& outName) } break; } - } break; @@ -1443,7 +1436,7 @@ bool MsDemangler::DemangleType(StringImpl& outName) { c = SafeGetChar(mMangledName, mCurIdx++); switch (c) - { + { case 'D': outName = "int8"; return true; @@ -1485,20 +1478,20 @@ bool MsDemangler::DemangleType(StringImpl& outName) break; } } - break; + break; case 'A': { DemangleModifiedType(outName, false); - outName += "&"; + outName += "&"; } return true; case 'B': DemangleModifiedType(outName, false); outName = "volatile " + outName + "&"; return true; - case 'P': - DemangleModifiedType(outName, true); + case 'P': + DemangleModifiedType(outName, true); return true; case 'Q': DemangleModifiedType(outName, true); @@ -1587,7 +1580,7 @@ bool MsDemangler::DemangleType(StringImpl& outName) case 'X': outName += "void"; return true; - case '?': + case '?': if (mInArgs) { int num = DemangleNumber(); @@ -1607,13 +1600,13 @@ bool MsDemangler::DemangleType(StringImpl& outName) } int MsDemangler::DemangleNumber() -{ +{ char c = SafeGetChar(mMangledName, mCurIdx++); bool isSigned = false; if (c == '?') - { + { isSigned = true; - c = SafeGetChar(mMangledName, mCurIdx++); + c = SafeGetChar(mMangledName, mCurIdx++); } if ((c >= '0') && (c <= '9')) @@ -1625,7 +1618,7 @@ int MsDemangler::DemangleNumber() while ((c >= 'A') && (c <= 'P')) { val = (val * 0x10) + (c - 'A'); - c = SafeGetChar(mMangledName, mCurIdx++); + c = SafeGetChar(mMangledName, mCurIdx++); } if (c != '@') @@ -1721,7 +1714,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) char c = SafeGetChar(mMangledName, mCurIdx++); if (c == '?') - { + { c = SafeGetChar(mMangledName, mCurIdx++); if (c == '$') { @@ -1736,7 +1729,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) switch (c) { case '0': - // Ctor + // Ctor Require(DemangleScopedName(outName, &primaryName)); if (mLanguage == DbgLanguage_Beef) outName += ".this"; @@ -1747,9 +1740,9 @@ bool MsDemangler::DemangleName(StringImpl& outName) // Dtor Require(DemangleScopedName(outName, &primaryName)); if (mLanguage == DbgLanguage_Beef) - outName += ".~this"; + outName += ".~this"; else - outName += "::~" + primaryName; + outName += "::~" + primaryName; break; case '2': funcName = "operator new"; break; case '3': funcName = "operator delete"; break; @@ -1760,7 +1753,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) case '8': funcName = "operator=="; break; case '9': funcName = "operator!="; break; case 'A': funcName = "operator[]"; break; - case 'B': + case 'B': funcName = "operator "; appendRetType = true; break; @@ -1818,15 +1811,15 @@ bool MsDemangler::DemangleName(StringImpl& outName) case 'M': funcName = "`eh vector destructor iterator'"; break; case 'N': funcName = "`eh vector vbase constructor iterator'"; break; case 'O': funcName = "`copy constructor closure'"; break; - case 'R': + case 'R': c = SafeGetChar(mMangledName, mCurIdx++); switch (c) { case 0: funcName = "`RTTI Type Descriptor'"; break; - case 1: funcName = "`RTTI Class Descriptor'"; break; + case 1: funcName = "`RTTI Class Descriptor'"; break; case '2': funcName = "`RTTI Base Class Array'"; break; case '3': funcName = "`RTTI Class Hierarchy Descriptor'"; break; - case '4': funcName = "`RTTI Complete Object Locater"; break; + case '4': funcName = "`RTTI Complete Object Locater"; break; } break; case 'S': funcName = "`local vftable'"; break; @@ -1834,12 +1827,12 @@ bool MsDemangler::DemangleName(StringImpl& outName) case 'U': funcName = "operator new[]"; break; case 'V': funcName = "operator delete[]"; break; case 'X': funcName = "`placement delete closure'"; break; - case 'Y': funcName = "`placement delete[] closure'"; break; + case 'Y': funcName = "`placement delete[] closure'"; break; } } - break; + break; default: - mCurIdx -= 2; + mCurIdx -= 2; break; } @@ -1876,7 +1869,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) if (!scopeName.empty()) { if (mLanguage == DbgLanguage_Beef) - { + { scopeName += "."; } else @@ -1967,7 +1960,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) { // Global variable / static member String varType; - Require(DemangleType(varType)); + Require(DemangleType(varType)); c = SafeGetChar(mMangledName, mCurIdx++); // 0 = private, 1 = protected, 2 = public @@ -1975,11 +1968,11 @@ bool MsDemangler::DemangleName(StringImpl& outName) } return true; - } + } - // Method attribute + // Method attribute if (c == 0) - return true; + return true; struct { @@ -1993,7 +1986,7 @@ bool MsDemangler::DemangleName(StringImpl& outName) //int funcTypeVal = c - 'A'; //int accessType = funcTypeVal >> 3; - //bool isNonMember = c == 'Y'; + //bool isNonMember = c == 'Y'; //bool isVirtual = (c == 'E') || (c == 'M') || (c == 'U'); //bool hasThis = isVirtual || (c == 'A') || (c == 'I') || (c == 'Q'); @@ -2010,15 +2003,15 @@ bool MsDemangler::DemangleName(StringImpl& outName) } // Calling convention - c = SafeGetChar(mMangledName, mCurIdx++); + c = SafeGetChar(mMangledName, mCurIdx++); union - { + { uint8 mDllExport : 1; - uint8 mCallingConv : 7; // cdecl, pascal, thiscall, stdcall, fastcall + uint8 mCallingConv : 7; // cdecl, pascal, thiscall, stdcall, fastcall } callType; *((uint8*)&callType) = (c - 'A'); - if (callType.mCallingConv > 6) + if (callType.mCallingConv > 6) return Failed(); String retType; @@ -2071,7 +2064,6 @@ String MsDemangler::Demangle(const StringImpl& mangledName) return outName; } - ////////////////////////////////////////////////////////////////////////// MsDemangleScanner::MsDemangleScanner() @@ -2081,14 +2073,14 @@ MsDemangleScanner::MsDemangleScanner() } bool MsDemangleScanner::DemangleString() -{ +{ while (true) { char c = SafeGetChar(mMangledName, mCurIdx++); if ((c == '!') || (c == '?')) - return Failed(); + return Failed(); if (c == '@') - break; + break; } //mSubstituteList.push_back(outName); @@ -2097,26 +2089,25 @@ bool MsDemangleScanner::DemangleString() bool MsDemangleScanner::DemangleTemplateName() { - DemangleString(); - + DemangleString(); + for (int paramIdx = 0; true; paramIdx++) - { + { if (!DemangleType()) - break; - } + break; + } return true; } - bool MsDemangleScanner::DemangleScopedName() -{ +{ for (int nameIdx = 0; true; nameIdx++) { if (mFailed) return false; - char c = SafeGetChar(mMangledName, mCurIdx++); + char c = SafeGetChar(mMangledName, mCurIdx++); if (c == '@') return true; @@ -2125,7 +2116,7 @@ bool MsDemangleScanner::DemangleScopedName() c = SafeGetChar(mMangledName, mCurIdx++); if (c == '$') { - DemangleTemplateName(); + DemangleTemplateName(); } else if (c == '?') { @@ -2134,12 +2125,11 @@ bool MsDemangleScanner::DemangleScopedName() else { mCurIdx--; - int num = DemangleNumber(); + int num = DemangleNumber(); } - } else if ((c >= '0') && (c <= '9')) - { + { int subIdx = c - '0'; if (subIdx < mSubstituteList.size()) { @@ -2152,33 +2142,33 @@ bool MsDemangleScanner::DemangleScopedName() } else { - mCurIdx--; + mCurIdx--; Require(DemangleString()); - } + } } } bool MsDemangleScanner::DemangleModifiedType(bool isPtr) -{ - DemangleCV(); +{ + DemangleCV(); char c = SafeGetChar(mMangledName, mCurIdx); if (c == 'Y') // Sized array - { + { mCurIdx++; int dimCount = DemangleNumber(); for (int dim = 0; dim < dimCount; dim++) { - int dimSize = DemangleNumber(); + int dimSize = DemangleNumber(); } - DemangleType(); + DemangleType(); } else { - DemangleType(); + DemangleType(); } - + return true; } @@ -2189,7 +2179,7 @@ bool MsDemangleScanner::DemangleType() return false; switch (c) - { + { case '0': case '1': case '2': @@ -2205,11 +2195,11 @@ bool MsDemangleScanner::DemangleType() return false; int subIdx = c - '0'; if ((subIdx < 0) || (subIdx >= (int)mSubstituteList.size())) - return Failed(); + return Failed(); return true; } break; - + case '$': { char c = SafeGetChar(mMangledName, mCurIdx++); @@ -2249,79 +2239,78 @@ bool MsDemangleScanner::DemangleType() { char c = SafeGetChar(mMangledName, mCurIdx++); if (c == 'C') - { + { DemangleCV(); - DemangleType(); + DemangleType(); return true; } else if (c == 'Q') - { + { DemangleCV(); - DemangleType(); + DemangleType(); return true; } } break; } - } break; - + case '_': { c = SafeGetChar(mMangledName, mCurIdx++); switch (c) - { - case 'D': + { + case 'D': return true; - case 'E': + case 'E': return true; - case 'F': + case 'F': return true; - case 'G': + case 'G': return true; - case 'H': + case 'H': return true; - case 'I': + case 'I': return true; - case 'J': + case 'J': return true; - case 'K': + case 'K': return true; - case 'L': + case 'L': return true; - case 'M': + case 'M': return true; - case 'W': + case 'W': return true; - case 'N': + case 'N': return true; default: return Failed(); break; } } - break; + break; case 'A': { - DemangleModifiedType(false); + DemangleModifiedType(false); } return true; case 'B': - DemangleModifiedType(false); + DemangleModifiedType(false); return true; - case 'P': - DemangleModifiedType(true); + case 'P': + DemangleModifiedType(true); return true; case 'Q': - DemangleModifiedType(true); + DemangleModifiedType(true); return true; case 'R': - DemangleModifiedType(true); + DemangleModifiedType(true); return true; case 'S': - DemangleModifiedType(true); + DemangleModifiedType(true); return true; case 'T': // union @@ -2341,20 +2330,20 @@ bool MsDemangleScanner::DemangleType() Require((c >= '0') && (c <= '8')); DemangleScopedName(); return true; - - case 'C': + + case 'C': return true; - case 'D': + case 'D': return true; - case 'E': + case 'E': return true; - case 'F': + case 'F': return true; - case 'G': + case 'G': return true; - case 'H': + case 'H': return true; - case 'I': + case 'I': return true; case 'J': return true; @@ -2362,13 +2351,13 @@ bool MsDemangleScanner::DemangleType() return true; case 'M': return true; - case 'N': + case 'N': return true; - case 'O': + case 'O': return true; - case 'X': + case 'X': return true; - case '?': + case '?': if (mInArgs) { int num = DemangleNumber(); @@ -2388,13 +2377,13 @@ bool MsDemangleScanner::DemangleType() } int MsDemangleScanner::DemangleNumber() -{ +{ char c = SafeGetChar(mMangledName, mCurIdx++); bool isSigned = false; if (c == '?') - { + { isSigned = true; - c = SafeGetChar(mMangledName, mCurIdx++); + c = SafeGetChar(mMangledName, mCurIdx++); } if ((c >= '0') && (c <= '9')) @@ -2406,7 +2395,7 @@ int MsDemangleScanner::DemangleNumber() while ((c >= 'A') && (c <= 'P')) { val = (val * 10) + (c - 'A'); - c = SafeGetChar(mMangledName, mCurIdx++); + c = SafeGetChar(mMangledName, mCurIdx++); } if (c != '@') @@ -2416,7 +2405,7 @@ int MsDemangleScanner::DemangleNumber() } bool MsDemangleScanner::DemangleCV() -{ +{ while (true) { char c = SafeGetChar(mMangledName, mCurIdx++); @@ -2437,9 +2426,9 @@ bool MsDemangleScanner::DemangleCV() break; } mCurIdx--; - + char c = SafeGetChar(mMangledName, mCurIdx++); - int constVal = 0; + int constVal = 0; if ((c < 'A') || (c > 'X')) { return Failed(); @@ -2455,7 +2444,7 @@ bool MsDemangleScanner::DemangleName() char c = SafeGetChar(mMangledName, mCurIdx++); if (c == '?') - { + { // A ?? is always a function return true; } @@ -2469,16 +2458,16 @@ bool MsDemangleScanner::DemangleName() if ((c >= '0') && (c <= '9')) { // Global variable / static member - mIsData = true; + mIsData = true; return true; - } + } // Not data - return true; + return true; } void MsDemangleScanner::Process(const StringImpl& mangledName) -{ +{ mMangledName = mangledName; char c = mangledName[mCurIdx++]; @@ -2489,13 +2478,13 @@ void MsDemangleScanner::Process(const StringImpl& mangledName) if (mFailed) { mIsData = false; - } + } } ////////////////////////////////////////////////////////////////////////// String BfDemangler::Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags) -{ +{ if (mangledName.IsEmpty()) return ""; if (mangledName[0] == '?') @@ -2525,5 +2514,4 @@ bool BfDemangler::IsData(const StringImpl& mangledName) return demangler.mIsData; } return false; -} - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfDemangler.h b/IDEHelper/Compiler/BfDemangler.h index 1173153c..ac771dcf 100644 --- a/IDEHelper/Compiler/BfDemangler.h +++ b/IDEHelper/Compiler/BfDemangler.h @@ -14,7 +14,7 @@ public: int mCurIdx; String mResult; bool mFailed; - String mMangledName; + String mMangledName; SubstituteList mSubstituteList; bool mInArgs; bool mBeefFixed; @@ -28,25 +28,25 @@ public: class DwDemangler : public DemangleBase { -public: +public: SubstituteList mTemplateList; bool mIsFirstName; - int mTemplateDepth; - bool mOmitSubstituteAdd; + int mTemplateDepth; + bool mOmitSubstituteAdd; bool mCaptureTargetType; bool mFunctionPopSubstitute; - bool mRawDemangle; + bool mRawDemangle; -public: +public: bool DemangleEnd(); bool DemangleArrayType(StringImpl& outName); bool DemangleBuiltinType(StringImpl& outName); bool DemangleFunctionType(StringImpl& outName); bool DemangleSourceName(StringImpl& outName); - bool DemangleRefQualifier(StringImpl& outName); + bool DemangleRefQualifier(StringImpl& outName); bool DemangleType(StringImpl& outName); bool DemangleNestedName(StringImpl& outName); - bool DemangleCVQualifiers(StringImpl& outName); + bool DemangleCVQualifiers(StringImpl& outName); bool DemangleOperatorName(StringImpl& outName); bool DemangleExprPriamry(StringImpl& outName); bool DemangleTemplateArgPack(StringImpl& outName); @@ -62,7 +62,7 @@ public: bool DemangleName(StringImpl& outName, bool* outHasTemplateArgs = NULL); bool DemangleFunction(StringImpl& outName); -public: +public: DwDemangler(); String Demangle(const StringImpl& mangledName); @@ -104,7 +104,7 @@ public: bool DemangleType(); bool DemangleScopedName(); bool DemangleName(); - + public: MsDemangleScanner(); diff --git a/IDEHelper/Compiler/BfElementVisitor.cpp b/IDEHelper/Compiler/BfElementVisitor.cpp index c5ad402b..aaa007d8 100644 --- a/IDEHelper/Compiler/BfElementVisitor.cpp +++ b/IDEHelper/Compiler/BfElementVisitor.cpp @@ -6,7 +6,6 @@ USING_NS_BF; BfElementVisitor::BfElementVisitor() { - } void BfElementVisitor::Visit(BfTypedValueExpression* typedValueExpr) @@ -36,7 +35,7 @@ void BfElementVisitor::Visit(BfPreprocessorDefinedExpression* definedExpr) { Visit(definedExpr->ToBase()); - VisitChild(definedExpr->mIdentifier); + VisitChild(definedExpr->mIdentifier); } void BfElementVisitor::Visit(BfAttributeDirective* attributeDirective) @@ -65,7 +64,7 @@ void BfElementVisitor::Visit(BfGenericParamsDeclaration* genericParams) for (auto& val : genericParams->mGenericParams) VisitChild(val); for (auto& val : genericParams->mCommas) - VisitChild(val); + VisitChild(val); VisitChild(genericParams->mCloseChevron); } @@ -84,7 +83,7 @@ void BfElementVisitor::Visit(BfGenericConstraintsDeclaration* genericConstraints Visit(genericConstraints->ToBase()); for (auto genericConstraintNode : genericConstraints->mGenericConstraints) - { + { if (auto genericConstraint = BfNodeDynCast(genericConstraintNode)) { VisitChild(genericConstraint->mWhereToken); @@ -100,7 +99,7 @@ void BfElementVisitor::Visit(BfGenericConstraintsDeclaration* genericConstraints VisitChild(genericConstraintExpr->mWhereToken); VisitChild(genericConstraintExpr->mExpression); } - } + } } void BfElementVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode) @@ -111,7 +110,7 @@ void BfElementVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode) for (auto& val : genericArgumentsNode->mGenericArgs) VisitChild(val); for (auto& val : genericArgumentsNode->mCommas) - VisitChild(val); + VisitChild(val); VisitChild(genericArgumentsNode->mCloseChevron); } @@ -169,7 +168,7 @@ void BfElementVisitor::Visit(BfNewNode* newNode) void BfElementVisitor::Visit(BfLabeledBlock* labeledBlock) { Visit(labeledBlock->ToBase()); - + VisitChild(labeledBlock->mBlock); } @@ -185,6 +184,15 @@ void BfElementVisitor::Visit(BfExpressionStatement* exprStmt) VisitChild(exprStmt->mExpression); } +void BfElementVisitor::Visit(BfNamedExpression* namedExpr) +{ + Visit(namedExpr->ToBase()); + + VisitChild(namedExpr->mNameNode); + VisitChild(namedExpr->mColonToken); + VisitChild(namedExpr->mExpression); +} + void BfElementVisitor::Visit(BfAttributedExpression* attribExpr) { Visit(attribExpr->ToBase()); @@ -257,7 +265,7 @@ void BfElementVisitor::Visit(BfQualifiedNameNode* nameNode) void BfElementVisitor::Visit(BfThisExpression* thisExpr) { - Visit(thisExpr->ToBase()); + Visit(thisExpr->ToBase()); } void BfElementVisitor::Visit(BfBaseExpression* baseExpr) @@ -297,9 +305,9 @@ void BfElementVisitor::Visit(BfCollectionInitializerExpression* collectionInitEx VisitChild(collectionInitExpr->mOpenBrace); for (auto& val : collectionInitExpr->mValues) - VisitChild(val); + VisitChild(val); for (auto& val : collectionInitExpr->mCommas) - VisitChild(val); + VisitChild(val); VisitChild(collectionInitExpr->mCloseBrace); } @@ -318,7 +326,7 @@ void BfElementVisitor::Visit(BfNamedTypeReference* typeRef) void BfElementVisitor::Visit(BfQualifiedTypeReference* qualifiedTypeRef) { Visit(qualifiedTypeRef->ToBase()); - + VisitChild(qualifiedTypeRef->mLeft); VisitChild(qualifiedTypeRef->mDot); VisitChild(qualifiedTypeRef->mRight); @@ -372,17 +380,17 @@ void BfElementVisitor::Visit(BfConstExprTypeRef* typeRef) void BfElementVisitor::Visit(BfRefTypeRef* typeRef) { Visit((BfTypeReference*)typeRef); // Skip the Elemented part so we can put the element in the right spot - + VisitChild(typeRef->mRefToken); VisitChild(typeRef->mElementType); } void BfElementVisitor::Visit(BfModifiedTypeRef * typeRef) -{ +{ Visit((BfTypeReference*)typeRef); // Skip the Elemented part so we can put the element in the right spot VisitChild(typeRef->mRetTypeToken); - VisitChild(typeRef->mOpenParen); + VisitChild(typeRef->mOpenParen); VisitChild(typeRef->mElementType); VisitChild(typeRef->mCloseParen); } @@ -390,11 +398,11 @@ void BfElementVisitor::Visit(BfModifiedTypeRef * typeRef) void BfElementVisitor::Visit(BfArrayTypeRef* typeRef) { Visit((BfTypeReference*)typeRef); // Skip the Elemented part so we can put the element in the right spot - + VisitChild(typeRef->mElementType); VisitChild(typeRef->mOpenBracket); for (auto& val : typeRef->mParams) - VisitChild(val); + VisitChild(val); VisitChild(typeRef->mCloseBracket); } @@ -404,7 +412,7 @@ void BfElementVisitor::Visit(BfGenericInstanceTypeRef* typeRef) VisitChild(typeRef->mOpenChevron); for (auto& val : typeRef->mGenericArguments) - VisitChild(val); + VisitChild(val); if (typeRef->mCommas.mVals != NULL) { for (auto& val : typeRef->mCommas) @@ -419,7 +427,7 @@ void BfElementVisitor::Visit(BfTupleTypeRef* typeRef) VisitChild(typeRef->mOpenParen); for (auto& val : typeRef->mFieldNames) - VisitChild(val); + VisitChild(val); for (auto& val : typeRef->mFieldTypes) VisitChild(val); if (typeRef->mCommas.mVals != NULL) @@ -510,6 +518,8 @@ void BfElementVisitor::Visit(BfTypeAttrExpression* typeAttrExpr) void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr) { + Visit(offsetOfExpr->ToBase()); + VisitChild(offsetOfExpr->mToken); VisitChild(offsetOfExpr->mOpenParen); VisitChild(offsetOfExpr->mTypeRef); @@ -518,6 +528,16 @@ void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr) VisitChild(offsetOfExpr->mCloseParen); } +void BfElementVisitor::Visit(BfNameOfExpression* nameOfExpr) +{ + Visit(nameOfExpr->ToBase()); + + VisitChild(nameOfExpr->mToken); + VisitChild(nameOfExpr->mOpenParen); + VisitChild(nameOfExpr->mTarget); + VisitChild(nameOfExpr->mCloseParen); +} + void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr) { Visit(defaultExpr->ToBase()); @@ -587,16 +607,16 @@ void BfElementVisitor::Visit(BfLambdaBindExpression* lambdaBindExpr) Visit(lambdaBindExpr->ToBase()); VisitChild(lambdaBindExpr->mNewToken); - + VisitChild(lambdaBindExpr->mOpenParen); VisitChild(lambdaBindExpr->mCloseParen); for (auto& val : lambdaBindExpr->mParams) VisitChild(val); for (auto& val : lambdaBindExpr->mCommas) - VisitChild(val); + VisitChild(val); VisitChild(lambdaBindExpr->mFatArrowToken); VisitChild(lambdaBindExpr->mBody); // Either expression or block - + VisitChild(lambdaBindExpr->mDtor); } @@ -606,13 +626,13 @@ void BfElementVisitor::Visit(BfObjectCreateExpression* newExpr) VisitChild(newExpr->mNewNode); VisitChild(newExpr->mStarToken); - VisitChild(newExpr->mTypeRef); + VisitChild(newExpr->mTypeRef); VisitChild(newExpr->mOpenToken); - VisitChild(newExpr->mCloseToken); + VisitChild(newExpr->mCloseToken); for (auto& val : newExpr->mArguments) VisitChild(val); for (auto& val : newExpr->mCommas) - VisitChild(val); + VisitChild(val); } void BfElementVisitor::Visit(BfBoxExpression* boxExpr) @@ -644,7 +664,7 @@ void BfElementVisitor::Visit(BfThrowStatement* throwStmt) void BfElementVisitor::Visit(BfDeleteStatement* deleteStmt) { Visit(deleteStmt->ToBase()); - + VisitChild(deleteStmt->mDeleteToken); VisitChild(deleteStmt->mTargetTypeToken); VisitChild(deleteStmt->mAllocExpr); @@ -662,7 +682,7 @@ void BfElementVisitor::Visit(BfInvocationExpression* invocationExpr) for (auto& val : invocationExpr->mArguments) VisitChild(val); for (auto& val : invocationExpr->mCommas) - VisitChild(val); + VisitChild(val); } void BfElementVisitor::Visit(BfEnumCaseBindExpression* caseBindExpr) @@ -692,7 +712,7 @@ void BfElementVisitor::Visit(BfSwitchCase* switchCase) for (auto& val : switchCase->mCaseExpressions) VisitChild(val); for (auto& val : switchCase->mCaseCommas) - VisitChild(val); + VisitChild(val); VisitChild(switchCase->mColonToken); VisitChild(switchCase->mCodeBlock); VisitChild(switchCase->mEndingToken); @@ -787,13 +807,13 @@ void BfElementVisitor::Visit(BfDeferStatement* deferStmt) if (deferStmt->mBind != NULL) { auto bind = deferStmt->mBind; - - VisitChild(bind->mOpenBracket); + + VisitChild(bind->mOpenBracket); VisitChild(bind->mCloseBracket); for (auto& val : bind->mParams) VisitChild(val); for (auto& val : bind->mCommas) - VisitChild(val); + VisitChild(val); } VisitChild(deferStmt->mOpenParen); @@ -828,7 +848,6 @@ void BfElementVisitor::Visit(BfUsingStatement* usingStmt) VisitChild(usingStmt->mVariableDeclaration); VisitChild(usingStmt->mCloseParen); VisitChild(usingStmt->mEmbeddedStatement); - } void BfElementVisitor::Visit(BfDoStatement* doStmt) @@ -836,7 +855,7 @@ void BfElementVisitor::Visit(BfDoStatement* doStmt) Visit(doStmt->ToBase()); VisitChild(doStmt->mDoToken); - VisitChild(doStmt->mEmbeddedStatement); + VisitChild(doStmt->mEmbeddedStatement); } void BfElementVisitor::Visit(BfRepeatStatement* repeatStmt) @@ -894,14 +913,14 @@ void BfElementVisitor::Visit(BfForStatement* forStmt) for (auto& val : forStmt->mInitializers) VisitChild(val); for (auto& val : forStmt->mInitializerCommas) - VisitChild(val); + VisitChild(val); VisitChild(forStmt->mInitializerSemicolon); VisitChild(forStmt->mCondition); VisitChild(forStmt->mConditionSemicolon); for (auto& val : forStmt->mIterators) VisitChild(val); for (auto& val : forStmt->mIteratorCommas) - VisitChild(val); + VisitChild(val); VisitChild(forStmt->mCloseParen); VisitChild(forStmt->mEmbeddedStatement); } @@ -961,12 +980,12 @@ void BfElementVisitor::Visit(BfTupleExpression* tupleExpr) { VisitChild(val->mNameNode); VisitChild(val->mColonToken); - } + } } for (auto& val : tupleExpr->mValues) VisitChild(val); for (auto& val : tupleExpr->mCommas) - VisitChild(val); + VisitChild(val); VisitChild(tupleExpr->mCloseParen); } @@ -985,11 +1004,11 @@ void BfElementVisitor::Visit(BfIndexerExpression* indexerExpr) VisitChild(indexerExpr->mTarget); VisitChild(indexerExpr->mOpenBracket); - VisitChild(indexerExpr->mCloseBracket); + VisitChild(indexerExpr->mCloseBracket); for (auto& arg : indexerExpr->mArguments) VisitChild(arg); for (auto& comma : indexerExpr->mCommas) - VisitChild(comma); + VisitChild(comma); } void BfElementVisitor::Visit(BfUnaryOperatorExpression* binOpExpr) @@ -1019,6 +1038,12 @@ void BfElementVisitor::Visit(BfConstructorDeclaration* ctorDeclaration) VisitChild(ctorDeclaration->mInitializer); } +void BfElementVisitor::Visit(BfAutoConstructorDeclaration* ctorDeclaration) +{ + VisitChild(ctorDeclaration->mPrefix); + Visit(ctorDeclaration->ToBase()); +} + void BfElementVisitor::Visit(BfDestructorDeclaration* dtorDeclaration) { Visit(dtorDeclaration->ToBase()); @@ -1031,11 +1056,11 @@ void BfElementVisitor::Visit(BfMethodDeclaration* methodDeclaration) { Visit(methodDeclaration->ToBase()); - VisitChild(methodDeclaration->mAttributes); + VisitChild(methodDeclaration->mAttributes); VisitChild(methodDeclaration->mProtectionSpecifier); VisitChild(methodDeclaration->mReadOnlySpecifier); VisitChild(methodDeclaration->mStaticSpecifier); - + VisitChild(methodDeclaration->mExternSpecifier); VisitChild(methodDeclaration->mVirtualSpecifier); // either 'virtual', 'override', or 'abstract' VisitChild(methodDeclaration->mNewSpecifier); @@ -1051,7 +1076,7 @@ void BfElementVisitor::Visit(BfMethodDeclaration* methodDeclaration) for (auto& param : methodDeclaration->mParams) VisitChild(param); for (auto& comma : methodDeclaration->mCommas) - VisitChild(comma); + VisitChild(comma); VisitChild(methodDeclaration->mCloseParen); VisitChild(methodDeclaration->mGenericParams); VisitChild(methodDeclaration->mGenericConstraintsDeclaration); @@ -1088,26 +1113,26 @@ void BfElementVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression) Visit(propertyBodyExpression->ToBase()); VisitChild(propertyBodyExpression->mMutSpecifier); - VisitChild(propertyBodyExpression->mFatTokenArrow); + VisitChild(propertyBodyExpression->mFatTokenArrow); } void BfElementVisitor::Visit(BfPropertyDeclaration* propertyDeclaration) { Visit(propertyDeclaration->ToBase()); - VisitChild(propertyDeclaration->mAttributes); + VisitChild(propertyDeclaration->mAttributes); VisitChild(propertyDeclaration->mProtectionSpecifier); VisitChild(propertyDeclaration->mStaticSpecifier); VisitChild(propertyDeclaration->mVirtualSpecifier); // either 'virtual', 'override', or 'abstract' VisitChild(propertyDeclaration->mExplicitInterface); VisitChild(propertyDeclaration->mExplicitInterfaceDotToken); - + if (auto block = BfNodeDynCast(propertyDeclaration->mDefinitionBlock)) { VisitChild(block->mOpenBrace); for (auto& method : propertyDeclaration->mMethods) - VisitChild(method); + VisitChild(method); VisitChild(block->mCloseBrace); } else @@ -1135,7 +1160,7 @@ void BfElementVisitor::Visit(BfFieldDeclaration* fieldDeclaration) { Visit(fieldDeclaration->ToBase()); - VisitChild(fieldDeclaration->mAttributes); + VisitChild(fieldDeclaration->mAttributes); VisitChild(fieldDeclaration->mProtectionSpecifier); VisitChild(fieldDeclaration->mStaticSpecifier); @@ -1160,7 +1185,7 @@ void BfElementVisitor::Visit(BfEnumCaseDeclaration* enumCaseDeclaration) for (auto& entry : enumCaseDeclaration->mEntries) VisitChild(entry); for (auto& comma : enumCaseDeclaration->mCommas) - VisitChild(comma); + VisitChild(comma); } void BfElementVisitor::Visit(BfFieldDtorDeclaration* fieldDtorDeclaration) @@ -1178,7 +1203,7 @@ void BfElementVisitor::Visit(BfTypeDeclaration* typeDeclaration) VisitChild(typeDeclaration->mAttributes); VisitChild(typeDeclaration->mAbstractSpecifier); - VisitChild(typeDeclaration->mSealedSpecifier); + VisitChild(typeDeclaration->mSealedSpecifier); VisitChild(typeDeclaration->mProtectionSpecifier); VisitChild(typeDeclaration->mStaticSpecifier); VisitChild(typeDeclaration->mPartialSpecifier); @@ -1189,7 +1214,7 @@ void BfElementVisitor::Visit(BfTypeDeclaration* typeDeclaration) for (auto& baseClass : typeDeclaration->mBaseClasses) VisitChild(baseClass); for (auto& comma : typeDeclaration->mBaseClassCommas) - VisitChild(comma); + VisitChild(comma); VisitChild(typeDeclaration->mGenericParams); VisitChild(typeDeclaration->mGenericConstraintsDeclaration); @@ -1200,7 +1225,6 @@ void BfElementVisitor::Visit(BfTypeDeclaration* typeDeclaration) for (auto& member : *typeDeclaration->mDefineBlock) VisitChild(member); }*/ - } void BfElementVisitor::Visit(BfTypeAliasDeclaration* typeDeclaration) @@ -1216,7 +1240,7 @@ void BfElementVisitor::Visit(BfUsingDirective* usingDirective) { Visit(usingDirective->ToBase()); - VisitChild(usingDirective->mUsingToken); + VisitChild(usingDirective->mUsingToken); VisitChild(usingDirective->mNamespace); } diff --git a/IDEHelper/Compiler/BfElementVisitor.h b/IDEHelper/Compiler/BfElementVisitor.h index 4d08b799..dc8d1115 100644 --- a/IDEHelper/Compiler/BfElementVisitor.h +++ b/IDEHelper/Compiler/BfElementVisitor.h @@ -16,6 +16,7 @@ public: virtual void Visit(BfLabeledBlock* labeledBlock); virtual void Visit(BfExpression* expr); virtual void Visit(BfExpressionStatement* exprStmt); + virtual void Visit(BfNamedExpression* namedExpr); virtual void Visit(BfAttributedExpression* attribExpr); virtual void Visit(BfStatement* stmt); virtual void Visit(BfAttributedStatement* attribStmt); @@ -47,7 +48,7 @@ public: virtual void Visit(BfMixinExpression* thisExpr); virtual void Visit(BfSizedArrayCreateExpression* createExpr); virtual void Visit(BfInitializerExpression* initExpr); - virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); + virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr); virtual void Visit(BfTypeReference* typeRef); virtual void Visit(BfNamedTypeReference* typeRef); virtual void Visit(BfQualifiedTypeReference* qualifiedType); @@ -68,9 +69,10 @@ public: virtual void Visit(BfNullableTypeRef* typeRef); virtual void Visit(BfVariableDeclaration* varDecl); virtual void Visit(BfLocalMethodDeclaration* methodDecl); - virtual void Visit(BfParameterDeclaration* paramDecl); - virtual void Visit(BfTypeAttrExpression* typeAttrExpr); + virtual void Visit(BfParameterDeclaration* paramDecl); + virtual void Visit(BfTypeAttrExpression* typeAttrExpr); virtual void Visit(BfOffsetOfExpression* offsetOfExpr); + virtual void Visit(BfNameOfExpression* nameOfExpr); virtual void Visit(BfDefaultExpression* defaultExpr); virtual void Visit(BfIsConstExpression* isConstExpr); virtual void Visit(BfUninitializedExpression* uninitializedExpr); @@ -83,7 +85,7 @@ public: virtual void Visit(BfBoxExpression* boxExpr); virtual void Visit(BfScopedInvocationTarget* scopedTarget); virtual void Visit(BfInvocationExpression* invocationExpr); - virtual void Visit(BfDeferStatement* deferStmt); + virtual void Visit(BfDeferStatement* deferStmt); virtual void Visit(BfEnumCaseBindExpression* caseBindExpr); virtual void Visit(BfCaseExpression* caseExpr); virtual void Visit(BfSwitchCase* switchCase); @@ -117,6 +119,7 @@ public: virtual void Visit(BfUnaryOperatorExpression* binOpExpr); virtual void Visit(BfBinaryOperatorExpression* binOpExpr); virtual void Visit(BfConstructorDeclaration* ctorDeclaration); + virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration); virtual void Visit(BfDestructorDeclaration* dtorDeclaration); virtual void Visit(BfMethodDeclaration* methodDeclaration); virtual void Visit(BfOperatorDeclaration* operatorDeclaration); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index b623d8f4..a28f4e53 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -57,7 +57,7 @@ BfBaseClassWalker::BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* mod mTypes[0] = typeA->ToTypeInstance(); else mTypes[0] = NULL; - + if ((typeB != NULL) && (!typeB->IsInterface())) mTypes[1] = typeB->ToTypeInstance(); else @@ -122,7 +122,7 @@ BfBaseClassWalker::Entry BfBaseClassWalker::Next() auto checkInstance = mTypes[0]; if (mTypes[0] == NULL) checkInstance = mTypes[1]; - else if ((mTypes[1] != NULL) && (mTypes[1]->mInheritDepth > mTypes[0]->mInheritDepth)) + else if ((mTypes[1] != NULL) && (mTypes[1]->mInheritDepth > mTypes[0]->mInheritDepth)) checkInstance = mTypes[1]; if (checkInstance == NULL) return Entry(); @@ -155,16 +155,17 @@ BfMethodMatcher::BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMetho { mTargetSrc = targetSrc; mModule = module; - Init(/*arguments, */methodGenericArguments); + Init(/*arguments, */methodGenericArguments); mInterfaceMethodInstance = interfaceMethodInstance; mMethodName = mInterfaceMethodInstance->mMethodDef->mName; } void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArguments) { - //mArguments = arguments; + //mArguments = arguments; + mUsingLists = NULL; mActiveTypeDef = NULL; - mBestMethodDef = NULL; + mBestMethodDef = NULL; mBackupMethodDef = NULL; mBackupMatchKind = BackupMatchKind_None; mBestRawMethodInstance = NULL; @@ -173,6 +174,7 @@ void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArgument mSelfType = NULL; mMethodType = BfMethodType_Normal; mCheckReturnType = NULL; + mHasArgNames = false; mHadExplicitGenericArguments = false; mHadOpenGenericArguments = methodGenericArguments.mIsOpen; mHadPartialGenericArguments = methodGenericArguments.mIsPartial; @@ -188,7 +190,7 @@ void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArgument mAllowImplicitWrap = false; mHadVarConflictingReturnType = false; mAutoFlushAmbiguityErrors = true; - mMethodCheckCount = 0; + mMethodCheckCount = 0; mCheckedKind = BfCheckedKind_NotSet; mMatchFailKind = MatchFailKind_None; mBfEvalExprFlags = BfEvalExprFlags_None; @@ -206,6 +208,9 @@ void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArgument mHasVarArguments = true; } } + + if (arg.mNameNode != NULL) + mHasArgNames = true; } if (methodGenericArguments.mArguments != NULL) @@ -235,7 +240,7 @@ void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArgument } bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType) -{ +{ if (!declaringType->mIsPartial) return true; @@ -248,7 +253,7 @@ bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* de auto visibleProjectSet = mModule->GetVisibleProjectSet(); if ((visibleProjectSet != NULL) && (!typeInst->IsTypeMemberAccessible(declaringType, visibleProjectSet))) - { + { return false; } @@ -264,11 +269,11 @@ bool BfGenericInferContext::AddToCheckedSet(BfType* argType, BfType* wantType) bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, bool checkCheckedSet) { if (argType == NULL) - return false; - + return false; + if (!wantType->IsUnspecializedType()) - return true; - + return true; + if (checkCheckedSet) { if (!AddToCheckedSet(argType, wantType)) @@ -296,7 +301,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc if (methodGenericTypeConstraint != NULL) { if (methodGenericTypeConstraint->IsGenericTypeInstance()) - { + { auto wantGenericType = (BfTypeInstance*)methodGenericTypeConstraint; auto checkArgType = argType; @@ -337,15 +342,15 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc checkArgType = checkTypeInst->mBaseType; } } - } + } } if ((*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] == NULL) - mInferredCount++; + mInferredCount++; (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] = argType; if (!mPrevArgValues.IsEmpty()) - mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue; + mPrevArgValues[wantGenericParam->mGenericParamIdx] = argValue; }; - + if (argType->IsVar()) { _SetGeneric(); @@ -362,7 +367,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc { argType = mModule->CreateConstExprValueType(BfTypedValue(argValue, argType)); } - else if (!argType->IsConstExprValue()) + else if (!argType->IsConstExprValue()) { return false; } @@ -375,7 +380,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc argType = mModule->ResolveGenericType(genericParamInst->mTypeConstraint, NULL, mCheckMethodGenericArguments, mModule->mCurTypeInstance); if (argType == NULL) return true; - } + } } if (mPrevArgValues.IsEmpty()) @@ -384,13 +389,13 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc return true; } - auto prevGenericMethodArg = (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx]; + auto prevGenericMethodArg = (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx]; auto prevArgValue = mPrevArgValues[wantGenericParam->mGenericParamIdx]; - if (prevGenericMethodArg == NULL) + if (prevGenericMethodArg == NULL) { _SetGeneric(); return true; - } + } if ((prevGenericMethodArg->IsIntUnknown()) && (!argType->IsIntUnknown())) { @@ -408,7 +413,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc return true; } } - + if (argType->IsIntUnknown()) { // New int fits into previous arg type, that's good @@ -422,14 +427,14 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc // Prev is already best if (mModule->CanCast(mModule->GetFakeTypedValue(argType), prevGenericMethodArg)) return true; - } - + } + // New best? if (mModule->CanCast(mModule->GetFakeTypedValue(prevGenericMethodArg), argType)) { _SetGeneric(); return true; - } + } // No implicit conversion, FAIL! (*mCheckMethodGenericArguments)[wantGenericParam->mGenericParamIdx] = NULL; @@ -469,7 +474,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc } if ((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsGenericTypeInstance())) - InferGenericArgument(methodInstance, genericParam->mTypeConstraint, wantType, BfIRValue()); + InferGenericArgument(methodInstance, genericParam->mTypeConstraint, wantType, BfIRValue()); } if (argType->IsVar()) @@ -478,7 +483,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc { BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx]; if (!wantGenericArgument->IsUnspecializedType()) - continue; + continue; InferGenericArgument(methodInstance, mModule->GetPrimitiveType(BfTypeCode_Var), wantGenericArgument, BfIRValue()); } return true; @@ -500,12 +505,12 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc auto argGenericType = (BfTypeInstance*)argType; if (argGenericType->mTypeDef->GetDefinition() != wantGenericType->mTypeDef->GetDefinition()) return true; - + for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mGenericTypeInfo->mTypeGenericArguments.size(); genericArgIdx++) { BfType* wantGenericArgument = wantGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx]; if (!wantGenericArgument->IsUnspecializedType()) - continue; + continue; InferGenericArgument(methodInstance, argGenericType->mGenericTypeInfo->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue(), true); } return true; @@ -519,12 +524,12 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc // Match to non-ref InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue()); return true; - } + } auto argRefType = (BfRefType*)argType; //TODO: We removed this check so we still infer even if we have the wrong ref kind //if (wantRefType->mRefKind != argRefType->mRefKind) //return true; - return InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue()); + return InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue()); } if (wantType->IsPointer()) @@ -532,13 +537,13 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc if (!argType->IsPointer()) return true; auto wantPointerType = (BfPointerType*) wantType; - auto argPointerType = (BfPointerType*) argType; - return InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue()); + auto argPointerType = (BfPointerType*) argType; + return InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue()); } if (wantType->IsUnknownSizedArrayType()) { - auto wantArrayType = (BfUnknownSizedArrayType*)wantType; + auto wantArrayType = (BfUnknownSizedArrayType*)wantType; if (argType->IsUnknownSizedArrayType()) { auto argArrayType = (BfUnknownSizedArrayType*)argType; @@ -554,8 +559,8 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc } if (wantType->IsSizedArray()) - { - if (argType->IsSizedArray()) + { + if (argType->IsSizedArray()) { auto wantArrayType = (BfSizedArrayType*)wantType; auto argArrayType = (BfSizedArrayType*)argType; @@ -573,11 +578,11 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke"); auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke"); - + if ((argInvokeMethod != NULL) && (wantInvokeMethod != NULL) && (argInvokeMethod->GetParamCount() == wantInvokeMethod->GetParamCount())) { InferGenericArgument(methodInstance, argInvokeMethod->mReturnType, wantInvokeMethod->mReturnType, BfIRValue()); - for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++) + for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++) InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx), BfIRValue()); } } @@ -589,7 +594,7 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc auto argInvokeMethod = methodTypeRef->mMethodRef; auto delegateInfo = wantType->GetDelegateInfo(); - auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke"); + auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke"); if ((delegateInfo->mHasExplicitThis) && (argInvokeMethod->HasThis())) InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(-1), delegateInfo->mParams[0], BfIRValue()); @@ -602,8 +607,8 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx + wantInvokeOffset), BfIRValue()); } } - } - + } + return true; } @@ -640,7 +645,7 @@ bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamType->mGenericParamIdx]; else genericParam = mModule->GetGenericParamInstance(genericParamType); - + if (genericParam->mTypeConstraint != NULL) InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue()); for (auto argIfaceConstraint : genericParam->mInterfaceConstraints) @@ -663,8 +668,8 @@ void BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs) { - if ((lhs->IsRef()) && (rhs->IsRef())) - return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType()); + if ((lhs->IsRef()) && (rhs->IsRef())) + return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType()); if ((lhs->IsPointer()) && (rhs->IsPointer())) return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType()); @@ -672,8 +677,8 @@ int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs) if ((lhs->IsSizedArray()) && (rhs->IsSizedArray())) return GetMostSpecificType(lhs->GetUnderlyingType(), rhs->GetUnderlyingType()); - if (lhs->IsGenericParam()) - return rhs->IsGenericParam() ? -1 : 1; + if (lhs->IsGenericParam()) + return rhs->IsGenericParam() ? -1 : 1; if (rhs->IsGenericParam()) return 0; @@ -690,8 +695,8 @@ int BfMethodMatcher::GetMostSpecificType(BfType* lhs, BfType* rhs) bool hadLHSMoreSpecific = false; bool hadRHSMoreSpecific = false; - - for (int generigArgIdx = 0; generigArgIdx < (int)lhsTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); generigArgIdx++) + + for (int generigArgIdx = 0; generigArgIdx < (int)lhsTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); generigArgIdx++) { int argMoreSpecific = GetMostSpecificType(lhsTypeInst->mGenericTypeInfo->mTypeGenericArguments[generigArgIdx], rhsTypeInst->mGenericTypeInfo->mTypeGenericArguments[generigArgIdx]); @@ -745,9 +750,9 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp bool isBetter = false; bool isWorse = false; int argIdx; - + BfMethodDef* prevMethodDef = prevMethodInstance->mMethodDef; - BfMethodDef* newMethodDef = newMethodInstance->mMethodDef; + BfMethodDef* newMethodDef = newMethodInstance->mMethodDef; if (prevMethodDef == mBackupMethodDef) { @@ -757,7 +762,6 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp return; } - if (newMethodDef->mExplicitInterface != prevMethodDef->mExplicitInterface) { if (mModule->CompareMethodSignatures(newMethodInstance, prevMethodInstance)) @@ -768,7 +772,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp return; } } - + bool anyIsExtension = false; int newImplicitParamCount = newMethodInstance->GetImplicitParamCount(); @@ -812,24 +816,24 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp bool someArgWasBetter = false; bool someArgWasWorse = false; - + for (argIdx = anyIsExtension ? -1 : 0; argIdx < (int)mArguments.size(); argIdx++) { BfTypedValue arg; - BfResolvedArg* resolvedArg = NULL; + BfResolvedArg* resolvedArg = NULL; bool wasArgDeferred = false; - + if (argIdx == -1) { arg = mTarget; } else - { + { resolvedArg = &mArguments[argIdx]; wasArgDeferred = resolvedArg->mArgFlags != 0; arg = resolvedArg->mTypedValue; } - + int newArgIdx = argIdx + newImplicitParamCount; int prevArgIdx = argIdx + prevImplicitParamCount; @@ -851,11 +855,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp BfType* origPrevParamType = prevParamType; bool paramWasConstExpr = false; - bool prevParamWasConstExpr = false; + bool prevParamWasConstExpr = false; bool paramWasUnspecialized = paramType->IsUnspecializedType(); if ((genericArgumentsSubstitute != NULL) && (paramWasUnspecialized)) - { + { paramType = mModule->ResolveGenericType(paramType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance, allowSpecializeFail); paramType = mModule->FixIntUnknown(paramType); } @@ -872,10 +876,10 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp prevParamType = mModule->FixIntUnknown(prevParamType); } if (prevParamType->IsConstExprValue()) - { + { prevParamWasConstExpr = true; prevParamType = ((BfConstExprValueType*)prevParamType)->mType; - } + } bool paramsEquivalent = paramType == prevParamType; @@ -887,14 +891,14 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp { bool isUnspecializedParam = paramType->IsUnspecializedType(); bool isPrevUnspecializedParam = prevParamType->IsUnspecializedType(); - SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()), + SET_BETTER_OR_WORSE((!isUnspecializedParam) && (!paramType->IsVar()), (!isPrevUnspecializedParam) && (!prevParamType->IsVar())); - + if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0) { // Pick the one that can implicitly cast SET_BETTER_OR_WORSE( - mModule->CanCast(arg, paramType, implicitCastFlags), + mModule->CanCast(arg, paramType, implicitCastFlags), mModule->CanCast(arg, prevParamType, implicitCastFlags)); } @@ -946,7 +950,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp { SET_BETTER_OR_WORSE(paramType->IsIntegral(), prevParamType->IsIntegral()); } - } + } } } } @@ -966,7 +970,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp worseByGenericParam = true; } } - + if ((newArgIdx >= 0) && (newMethodInstance->GetParamKind(newArgIdx) == BfParamKind_Params)) usedExtendedForm = true; if ((prevArgIdx >= 0) && (prevMethodInstance->GetParamKind(prevArgIdx) == BfParamKind_Params)) @@ -978,7 +982,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp someArgWasBetter |= isBetter; someArgWasWorse |= isWorse; isBetter = false; - isWorse = false; + isWorse = false; } isBetter |= someArgWasBetter; isWorse |= someArgWasWorse; @@ -1006,17 +1010,17 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } if ((isBetter) || (isWorse)) - { + { RETURN_RESULTS; } } - + // Choose by return type for conversion operators if (((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) && (!isBetter) && (!isWorse)) { auto returnType = newMethodInstance->mReturnType; - auto prevReturnType = prevMethodInstance->mReturnType; - + auto prevReturnType = prevMethodInstance->mReturnType; + if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0) { // Pick the one that can implicitly cast @@ -1042,32 +1046,32 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } } - // Check for unused extended params as next param - that still counts as using extended form - usedExtendedForm = newMethodInstance->HasParamsArray(); - prevUsedExtendedForm = prevMethodInstance->HasParamsArray(); - - RETURN_BETTER_OR_WORSE(newMethodInstance->GetNumGenericArguments() == 0, prevMethodInstance->GetNumGenericArguments() == 0); + // Check for unused extended params as next param - that still counts as using extended form + usedExtendedForm = newMethodInstance->HasParamsArray(); + prevUsedExtendedForm = prevMethodInstance->HasParamsArray(); - // Not using generic delegate params is better + RETURN_BETTER_OR_WORSE(newMethodInstance->GetNumGenericArguments() == 0, prevMethodInstance->GetNumGenericArguments() == 0); + + // Not using generic delegate params is better RETURN_BETTER_OR_WORSE(!newMethodInstance->mHadGenericDelegateParams, !prevMethodInstance->mHadGenericDelegateParams); - // Normal form trumps extended form - RETURN_BETTER_OR_WORSE(!usedExtendedForm, !prevUsedExtendedForm); + // Normal form trumps extended form + RETURN_BETTER_OR_WORSE(!usedExtendedForm, !prevUsedExtendedForm); - // More used params trumps less params + // More used params trumps less params int paramDiff = (int) numUsedParams - (int) prevNumUsedParams; - RETURN_BETTER_OR_WORSE(paramDiff > 0, paramDiff < 0); + RETURN_BETTER_OR_WORSE(paramDiff > 0, paramDiff < 0); - // Fewer defaults trumps more defaults + // Fewer defaults trumps more defaults // Since we know the number of used params is the same (previous check), we infer that the rest are defaults paramDiff = (int) newMethodInstance->GetParamCount() - (int) prevMethodInstance->GetParamCount(); - RETURN_BETTER_OR_WORSE(paramDiff < 0, paramDiff > 0); + RETURN_BETTER_OR_WORSE(paramDiff < 0, paramDiff > 0); BfMethodInstance* typeUnspecNewMethodInstance = mModule->GetUnspecializedMethodInstance(newMethodInstance, true); BfMethodInstance* typeUnspecPrevMethodInstance = mModule->GetUnspecializedMethodInstance(prevMethodInstance, true); // Check specificity of args - + std::function _CompareParamTypes = [&](BfType* newType, BfType* prevType) { if ((newType->IsGenericParam()) && (prevType->IsGenericParam())) @@ -1101,20 +1105,20 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp //isWorse |= mModule->IsTypeMoreSpecific(prevType, newType); } }; - + int paramCheckCount = (int)BF_MIN(newMethodInstance->GetParamCount() - newImplicitParamCount, prevMethodInstance->GetParamCount() - prevImplicitParamCount); for (argIdx = 0; argIdx < (int)paramCheckCount/*mArguments.size()*/; argIdx++) { int newArgIdx = argIdx + newImplicitParamCount; - int prevArgIdx = argIdx + prevImplicitParamCount; + int prevArgIdx = argIdx + prevImplicitParamCount; _CompareParamTypes(typeUnspecNewMethodInstance->GetParamType(newArgIdx), typeUnspecPrevMethodInstance->GetParamType(prevArgIdx)); - } + } // Do generic constraint subset test directly to handle cases like "NotDisposed()" vs "NotDisposed() where T : IDisposable" if ((newMethodInstance->GetNumGenericArguments() > 0) && (newMethodInstance->GetNumGenericArguments() == prevMethodInstance->GetNumGenericArguments())) { for (int genericParamIdx = 0; genericParamIdx < (int)newMethodInstance->GetNumGenericArguments(); genericParamIdx++) - { + { auto newMethodGenericParam = newMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam)); @@ -1125,7 +1129,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp SET_BETTER_OR_WORSE(newMethodInstance->HasExternConstraints(), prevMethodInstance->HasExternConstraints()); } } - + if ((isBetter) || (isWorse)) { RETURN_RESULTS; @@ -1143,7 +1147,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } if ((newMethodInstance->mMethodDef->mExternalConstraints.size() != 0) || (prevMethodInstance->mMethodDef->mExternalConstraints.size() != 0)) - { + { struct GenericParamPair { BfGenericMethodParamInstance* mParams[2]; @@ -1161,7 +1165,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp for (int externConstraintIdx = 0; externConstraintIdx < (int)methodInstance->mMethodDef->mExternalConstraints.size(); externConstraintIdx++) { auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[methodInstance->mMethodDef->mGenericParams.size() + externConstraintIdx]; - BF_ASSERT(genericParam->mExternType != NULL); + BF_ASSERT(genericParam->mExternType != NULL); GenericParamPair* pairPtr = NULL; externConstraints.TryAdd(genericParam->mExternType, NULL, &pairPtr); pairPtr->mParams[idx] = genericParam; @@ -1182,7 +1186,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } } - // Does one have a body and one doesn't? Obvious! + // Does one have a body and one doesn't? Obvious! isBetter = prevMethodDef->IsEmptyPartial(); isWorse = newMethodDef->IsEmptyPartial(); if ((isBetter) && (isWorse)) @@ -1190,7 +1194,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp // If both are empty partials then just bind to either isWorse = true; RETURN_RESULTS; - } + } // For extensions, select the version in the most-specific project (only applicable for ctors) if ((!isBetter) && (!isWorse)) @@ -1209,7 +1213,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp { auto genericOwner = (BfTypeInstance*)owner; if (genericOwner->mGenericTypeInfo->mGenericExtensionInfo != NULL) - { + { BfGenericExtensionEntry* newGenericExtesionEntry = NULL; BfGenericExtensionEntry* prevGenericExtesionEntry = NULL; if ((genericOwner->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(newMethodDef->mDeclaringType, &newGenericExtesionEntry)) && @@ -1251,11 +1255,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType, BfResolveArgFlags flags) -{ +{ BfTypedValue argTypedValue = resolvedArg.mTypedValue; if ((resolvedArg.mArgFlags & BfArgFlag_DelegateBindAttempt) != 0) { - BfExprEvaluator exprEvaluator(mModule); + BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mExpectingType = checkType; BF_ASSERT(resolvedArg.mExpression->IsA()); auto delegateBindExpr = BfNodeDynCast(resolvedArg.mExpression); @@ -1267,7 +1271,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B if (exprEvaluator.CanBindDelegate(delegateBindExpr, &boundMethodInstance, bindType, genericArgumentsSubstitute)) { if (delegateBindExpr->mNewToken == NULL) - { + { if (boundMethodInstance->GetOwner()->IsFunction()) { return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), boundMethodInstance->GetOwner()); @@ -1290,15 +1294,15 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B } } else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0) - { - if ((argTypedValue) && (argTypedValue.mType->IsMethodRef()) && + { + if ((argTypedValue) && (argTypedValue.mType->IsMethodRef()) && ((checkType == NULL) || (!checkType->IsMethodRef()))) { // This may be from a previous checkMethod, clear it out argTypedValue = BfTypedValue(); } - BfExprEvaluator exprEvaluator(mModule); + BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mExpectingType = checkType; BF_ASSERT(resolvedArg.mExpression->IsA()); auto lambdaBindExpr = (BfLambdaBindExpression*)resolvedArg.mExpression; @@ -1307,12 +1311,12 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B { BfMethodInstance* methodInstance = mModule->GetRawMethodInstanceAtIdx(checkType->ToTypeInstance(), 0, "Invoke"); if (methodInstance != NULL) - { + { if (methodInstance->GetParamCount() == (int)lambdaBindExpr->mParams.size()) { if (lambdaBindExpr->mNewToken == NULL) { - if (!resolvedArg.mTypedValue) + if (!resolvedArg.mTypedValue) { // Resolve for real resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, checkType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete)); @@ -1365,14 +1369,14 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B { auto inferredReturnType = mModule->CreateValueFromExpression(lambdaBindExpr, tryType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_InferReturnType | BfEvalExprFlags_NoAutoComplete)); if (inferredReturnType.mType != NULL) - { + { (*genericArgumentsSubstitute)[returnMethodGenericArgIdx] = inferredReturnType.mType; - + if (((flags & BfResolveArgFlag_FromGenericParam) != 0) && (lambdaBindExpr->mNewToken == NULL)) { auto resolvedType = mModule->ResolveGenericType(origCheckType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance); if (resolvedType != NULL) - { + { // Resolve for real resolvedArg.mTypedValue = mModule->CreateValueFromExpression(lambdaBindExpr, resolvedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_NoAutoComplete)); argTypedValue = resolvedArg.mTypedValue; @@ -1382,7 +1386,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B success = true; } } - + if (!success) { // Put back @@ -1398,13 +1402,13 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B if ((checkType != NULL) && (checkType->IsPayloadEnum())) { // Should we actually check the member name? - argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); + argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); } } else if ((resolvedArg.mArgFlags & BfArgFlag_UntypedDefault) != 0) { if (checkType != NULL) - argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); + argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); } else if ((resolvedArg.mArgFlags & BfArgFlag_DeferredEval) != 0) { @@ -1413,8 +1417,8 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B if ((resolvedArg.mExpectedType != checkType) || (resolvedArg.mExpectedType == NULL)) // Did our last check match for this type? { SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); - SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); - + SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); + bool prevNoBind = false; if (mModule->mCurMethodState != NULL) { @@ -1423,8 +1427,8 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B } auto prevBlock = mModule->mBfIRBuilder->GetInsertBlock(); - - BfExprEvaluator exprEvaluator(mModule); + + BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags); exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowIntUnknown | BfEvalExprFlags_NoAutoComplete); if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) != 0) @@ -1442,13 +1446,13 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType())) expectType = mModule->ResolveGenericType(expectType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance, true); } - + exprEvaluator.mExpectingType = expectType; exprEvaluator.Evaluate(resolvedArg.mExpression); argTypedValue = exprEvaluator.GetResult(); if ((argTypedValue) && (argTypedValue.mType->IsVar())) argTypedValue = BfTypedValue(); - + if (mModule->mCurMethodState != NULL) mModule->mCurMethodState->mNoBind = prevNoBind; @@ -1468,12 +1472,12 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B resolvedArg.mWantsRecalc = true; } resolvedArg.mTypedValue = storeTypedValue; - + //BF_ASSERT(argTypedValue.mValue.mId != -1); } mModule->mBfIRBuilder->SetInsertPoint(prevBlock); - } + } } } else if ((resolvedArg.mArgFlags & BfArgFlag_VariableDeclaration) != 0) @@ -1487,10 +1491,10 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* checkMethod) { - MatchFailKind matchFailKind = MatchFailKind_None; + MatchFailKind matchFailKind = MatchFailKind_None; if (!mModule->CheckProtection(flags, checkTypeInstance, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, startTypeInstance)) { - if ((mBypassVirtual) && + if ((mBypassVirtual) && ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) && (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, startTypeInstance))) { @@ -1498,7 +1502,7 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst } else { - return false; + return false; } } @@ -1531,10 +1535,10 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan auto genericParamType = (BfGenericParamType*)genericParamInst->mExternType; if (genericParamType->mGenericParamKind != BfGenericParamKind_Method) - return false; + return false; BfType* checkArgType = NULL; - + for (auto& checkOpConstraint : genericParamInst->mOperatorConstraints) { auto leftType = checkOpConstraint.mLeftType; @@ -1574,7 +1578,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, BfBinOpFlag_NoClassify, leftValue, rightValue); } - + if (exprEvaluator.mResult) checkArgType = exprEvaluator.mResult.mType; } @@ -1588,8 +1592,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan StringT<128> failedOpName; if (checkOpConstraint.mCastToken == BfToken_Implicit) - { - + { } else { @@ -1598,18 +1601,17 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan if (checkOpConstraint.mCastToken == BfToken_Explicit) { - } else { BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mResult = rightValue; exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL, BfUnaryOpFlag_IsConstraintCheck); - + if (exprEvaluator.mResult) checkArgType = exprEvaluator.mResult.mType; } - } + } } } @@ -1619,7 +1621,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan { checkArgType = mModule->ResolveGenericMethodTypeRef(comptypeConstraint, methodInstance, genericParamInst, methodGenericArgs); if (checkArgType == NULL) - return false; + return false; } } @@ -1627,7 +1629,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan return false; if (checkArgType->IsVar()) return false; - + (*methodGenericArgs)[genericParamType->mGenericParamIdx] = checkArgType; return true; } @@ -1640,17 +1642,17 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst bool hadMatch = false; // Never consider overrides - they only get found at original method declaration - // mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct -- + // mBypassVirtual gets set when we are doing an explicit "base" call, or when we are a struct -- // because on structs we know the exact type if ((checkMethod->mIsOverride) && (!mBypassVirtual) && (!typeInstance->IsValueType())) return false; - + mMethodCheckCount++; - + BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod); - if (methodInstance == NULL) + if (methodInstance == NULL) return false; - BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true); + BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true); BfTypeVector* typeGenericArguments = NULL; if (typeInstance->mGenericTypeInfo != NULL) typeGenericArguments = &typeInstance->mGenericTypeInfo->mTypeGenericArguments; @@ -1669,11 +1671,19 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if ((methodInstance->mVirtualTableIdx < targetTypeInstance->mVirtualMethodTable.mSize) && (methodInstance->mVirtualTableIdx >= 0)) { BfVirtualMethodEntry& vEntry = targetTypeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx]; - auto implMethod = (BfMethodInstance*)vEntry.mImplementingMethod; - if ((implMethod != methodInstance) && (implMethod != NULL)) + if ((vEntry.mImplementingMethod.mTypeInstance != NULL) && (vEntry.mImplementingMethod.mTypeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) && + (mModule->mCompiler->IsAutocomplete())) { - SetAndRestoreValue prevBypassVirtual(mBypassVirtual, true); - return CheckMethod(targetTypeInstance, implMethod->GetOwner(), implMethod->mMethodDef, isFailurePass); + // Silently ignore + } + else + { + auto implMethod = (BfMethodInstance*)vEntry.mImplementingMethod; + if ((implMethod != methodInstance) && (implMethod != NULL)) + { + SetAndRestoreValue prevBypassVirtual(mBypassVirtual, true); + return CheckMethod(targetTypeInstance, implMethod->GetOwner(), implMethod->mMethodDef, isFailurePass); + } } } else @@ -1688,7 +1698,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst BfGenericInferContext genericInferContext; genericInferContext.mModule = mModule; - genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments; + genericInferContext.mCheckMethodGenericArguments = &mCheckMethodGenericArguments; HashSet allowEmptyGenericSet; BfAutoComplete* autoComplete = NULL; @@ -1706,18 +1716,18 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) - { + { BfAutoComplete::MethodMatchEntry methodMatchEntry; methodMatchEntry.mMethodDef = checkMethod; methodMatchEntry.mTypeInstance = typeInstance; methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance; - autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); + autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); } BfTypeVector* genericArgumentsSubstitute = NULL; int argIdx = 0; int argMatchCount = 0; - + bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) && ((!mHadExplicitGenericArguments) || (mHadPartialGenericArguments)); int paramIdx = 0; @@ -1741,15 +1751,15 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto NoMatch; } } - + for (auto& checkGenericArgRef : mCheckMethodGenericArguments) checkGenericArgRef = NULL; - mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size()); - + mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size()); + for (auto& genericArgRef : mCheckMethodGenericArguments) genericArgRef = NULL; - + if (mHadExplicitGenericArguments) { if (uniqueGenericStartIdx > 0) @@ -1777,7 +1787,39 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } else if (needInferGenericParams) genericArgumentsSubstitute = &mCheckMethodGenericArguments; - + + if (mHasArgNames) + { + checkMethod->BuildParamNameMap(); + + bool prevWasNull = false; + for (int argIdx = (int)mArguments.mSize - 1; argIdx >= 0; argIdx--) + { + auto& arg = mArguments[argIdx]; + if (arg.mNameNode != NULL) + { + if (prevWasNull) + { + if (argIdx >= checkMethod->mParams.mSize) + goto NoMatch; + if (checkMethod->mParams[argIdx]->mName != arg.mNameNode->ToStringView()) + goto NoMatch; + } + else + { + if (!checkMethod->mParamNameMap->ContainsKey(arg.mNameNode->ToStringView())) + goto NoMatch; + } + + prevWasNull = false; + } + else + { + prevWasNull = true; + } + } + } + if ((checkMethod->mIsMutating) && (targetTypeInstance != NULL) && (targetTypeInstance->IsValueType()) && ((mTarget.IsReadOnly()) || (!mTarget.IsAddr())) && (!targetTypeInstance->IsValuelessType())) @@ -1789,8 +1831,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst { //paramOfs = methodInstance->GetImplicitParamCount(); //paramIdx += paramOfs; - } - + } + if (needInferGenericParams) { genericInferContext.mPrevArgValues.resize(checkMethod->mGenericParams.size()); @@ -1798,7 +1840,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst int paramOfs = methodInstance->GetImplicitParamCount(); int paramCount = methodInstance->GetParamCount(); SizedArray deferredArgs; - + int argIdx = 0; int paramIdx = 0; @@ -1901,7 +1943,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))) wantType = wantType->GetUnderlyingType(); } - + if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue)) return ResultKind_Failed; } @@ -1920,10 +1962,10 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto NoMatch; } - if ((checkMethod->mParams.mSize > 0) && (methodInstance->GetParamKind(checkMethod->mParams.mSize - 1) == BfParamKind_Params)) + if ((methodInstance->mParams.mSize > 0) && (methodInstance->GetParamKind(methodInstance->mParams.mSize - 1) == BfParamKind_Params)) { // Handle `params int[C]` generic sized array params case - auto paramsType = methodInstance->GetParamType(checkMethod->mParams.mSize - 1); + auto paramsType = methodInstance->GetParamType(methodInstance->mParams.mSize - 1); if (paramsType->IsUnknownSizedArrayType()) { auto unknownSizedArray = (BfUnknownSizedArrayType*)paramsType; @@ -1946,7 +1988,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } while (!deferredArgs.IsEmpty()) - { + { int prevDeferredSize = (int)deferredArgs.size(); for (int i = 0; i < prevDeferredSize; i++) { @@ -1961,7 +2003,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto NoMatch; } } - + // { int paramIdx = (int)mArguments.size() + paramOfs; @@ -1994,11 +2036,11 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType())) - { + { if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue())) return ResultKind_Failed; } - + bool failed = false; bool inferredAllGenericArguments = false; for (int pass = 0; true; pass++) @@ -2017,7 +2059,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if (genericArg != NULL) { if (inferredAllGenericArguments) - genericInferContext.InferGenericArguments(methodInstance, genericArgIdx); + genericInferContext.InferGenericArguments(methodInstance, genericArgIdx); madeProgress = true; } hasUninferred = true; @@ -2048,16 +2090,16 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst { // Too many arguments if (paramIdx >= (int)methodInstance->GetParamCount()) - { + { break; } - + bool isDeferredEval = false; - + if ((argIdx >= 0) && (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params) && (paramsElementType == NULL)) { if (argIdx >= (int) mArguments.size()) - break; // No params + break; // No params BfTypedValue argTypedValue = ResolveArgTypedValue(mArguments[argIdx], NULL, genericArgumentsSubstitute); if (!argTypedValue) @@ -2068,26 +2110,26 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst auto paramsArrayType = methodInstance->GetParamType(paramIdx); paramsArrayType = mModule->ResolveGenericType(paramsArrayType, NULL, genericArgumentsSubstitute, mModule->mCurTypeInstance); - + if (paramsArrayType == NULL) goto NoMatch; if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0) - { + { // Direct-pass params if ((argTypedValue.IsUntypedValue()) || (mModule->CanCast(argTypedValue, paramsArrayType))) { argIdx++; argMatchCount++; - paramIdx++; + paramIdx++; break; } goto NoMatch; } - + if ((paramsArrayType->IsArray()) || (paramsArrayType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))) - { + { paramsElementType = paramsArrayType->GetUnderlyingType(); while (argIdx < (int)mArguments.size()) @@ -2103,12 +2145,12 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst argIdx++; argMatchCount++; } - } + } else goto NoMatch; break; } - + if (methodInstance->IsImplicitCapture(paramIdx)) { paramIdx++; @@ -2123,8 +2165,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst // We have unused params left over goto NoMatch; - } - + } + auto wantType = methodInstance->GetParamType(paramIdx); if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType())) { @@ -2202,7 +2244,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } } } - + paramIdx++; argIdx++; argMatchCount++; @@ -2217,24 +2259,24 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst int methodIdx = (int)methodMatchInfo->mInstanceList.size() - 1; if ((methodMatchInfo->mBestIdx != -1) && (methodMatchInfo->mBestIdx < (int)methodMatchInfo->mInstanceList.size())) - { + { auto prevMethodMatchEntry = &methodMatchInfo->mInstanceList[methodMatchInfo->mBestIdx]; if (checkMethod->mParams.size() < mArguments.size()) - { + { isWorse = true; } else if ((prevMethodMatchEntry->mMethodDef != NULL) && (prevMethodMatchEntry->mMethodDef->mParams.size() < (int) mArguments.size())) { isBetter = true; - } - } + } + } } } } - + // Too many arguments (not all incoming arguments processed) if (argIdx < (int)mArguments.size()) - { + { if (!methodInstance->IsVarArgs()) goto NoMatch; } @@ -2248,7 +2290,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto NoMatch; } if ((genericArgumentsSubstitute != NULL) && (returnType->IsUnspecializedType())) - { + { auto resolvedType = mModule->ResolveGenericType(returnType, typeGenericArguments, genericArgumentsSubstitute, mModule->mCurTypeInstance, false); if (resolvedType == NULL) goto NoMatch; @@ -2264,7 +2306,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst } if ((genericArgumentsSubstitute != NULL) && (genericArgumentsSubstitute->size() != 0)) - { + { for (int checkGenericIdx = uniqueGenericStartIdx; checkGenericIdx < (int)genericArgumentsSubstitute->size(); checkGenericIdx++) { auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams; @@ -2278,8 +2320,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if (genericArg == NULL) goto NoMatch; - - if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL)) + + if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL)) goto NoMatch; } } @@ -2307,7 +2349,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst auto genericParamType = (BfGenericParamType*)externType; if (genericParamType->mGenericParamKind == BfGenericParamKind_Method) { - if (genericArgumentsSubstitute != NULL) + if (genericArgumentsSubstitute != NULL) { auto genericArg = (*genericArgumentsSubstitute)[genericParamType->mGenericParamIdx]; if (genericArg == NULL) @@ -2335,8 +2377,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst // { // if (genericConstraintExpr->mExpression == NULL) // continue; -// BfConstResolver constResolver(mModule); -// constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_Boolean); +// BfConstResolver constResolver(mModule); +// constResolver.mExpectingType = mModule->GetPrimitiveType(BfTypeCode_Boolean); // constResolver.Resolve(genericConstraintExpr->mExpression, constResolver.mExpectingType); // } // } @@ -2353,7 +2395,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst if (mModule->mCurMethodInstance != NULL) allowSpecializeFail = mModule->mCurMethodInstance->mIsUnspecialized; - CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail); + CompareMethods(prevMethodInstance, &mBestMethodGenericArguments, methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, allowSpecializeFail); // If we had both a 'better' and 'worse', that's ambiguous because the methods are each better in different ways (not allowed) // And if neither better nor worse then they are equally good, which is not allowed either @@ -2381,7 +2423,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst _CheckMethodInfo(methodInstance); _CheckMethodInfo(prevMethodInstance); } - + if (mHasVarArguments) { if (methodInstance->mReturnType != prevMethodInstance->mReturnType) @@ -2401,11 +2443,11 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst goto Done; } } - + if (!isBetter) goto Done; } - + if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) { auto methodMatchInfo = autoComplete->mMethodMatchInfo; @@ -2428,17 +2470,17 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst NoMatch: if (!hadMatch) - { + { if (mBestMethodDef != NULL) return false; - + if (checkMethod->mMethodType == BfMethodType_Extension) { auto thisParam = methodInstance->GetParamType(0); auto resolveThisParam = mModule->ResolveGenericType(thisParam, NULL, &mCheckMethodGenericArguments, mModule->mCurTypeInstance); if (resolveThisParam == NULL) return false; - if (!mModule->CanCast(mTarget, resolveThisParam, + if (!mModule->CanCast(mTarget, resolveThisParam, ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_NoConversionOperator) : BfCastFlags_Explicit)) return false; } @@ -2462,7 +2504,7 @@ NoMatch: // We search from the most specific type, so don't prefer a less specific type if (mBestMethodTypeInstance != typeInstance) return false; - } + } } if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) @@ -2470,7 +2512,7 @@ NoMatch: auto methodMatchInfo = autoComplete->mMethodMatchInfo; if ((methodMatchInfo->mPrevBestIdx == -1) && (!methodMatchInfo->mHadExactMatch)) { - methodMatchInfo->mBestIdx = (int)methodMatchInfo->mInstanceList.size() - 1; + methodMatchInfo->mBestIdx = (int)methodMatchInfo->mInstanceList.size() - 1; } } @@ -2480,9 +2522,9 @@ NoMatch: // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL) hadMatch = true; } - + if (hadMatch) - { + { mBestMethodTypeInstance = typeInstance; if (genericArgumentsSubstitute != &mBestMethodGenericArguments) { @@ -2504,11 +2546,11 @@ NoMatch: Done: if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (genericArgumentsSubstitute != NULL)) { - auto methodMatchInfo = autoComplete->mMethodMatchInfo; + auto methodMatchInfo = autoComplete->mMethodMatchInfo; if (!methodMatchInfo->mInstanceList.IsEmpty()) { - methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1].mGenericArguments = *genericArgumentsSubstitute; - } + methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1].mGenericArguments = *genericArgumentsSubstitute; + } } return mBestMethodDef == checkMethod; @@ -2517,7 +2559,7 @@ Done: void BfMethodMatcher::FlushAmbiguityError() { if (!mAmbiguousEntries.empty()) - { + { if (mModule->PreFail()) { BfError* error; @@ -2527,8 +2569,7 @@ void BfMethodMatcher::FlushAmbiguityError() error = mModule->Fail("Ambiguous method call", mTargetSrc); if (error != NULL) { - auto unspecializedType = mModule->GetUnspecializedTypeInstance(mBestMethodTypeInstance); - BfMethodInstance* bestMethodInstance = mModule->GetRawMethodInstance(unspecializedType, mBestMethodDef); + BfMethodInstance* bestMethodInstance = mModule->GetUnspecializedMethodInstance(mBestRawMethodInstance, true); BfTypeVector* typeGenericArguments = NULL; if (mBestMethodTypeInstance->mGenericTypeInfo != NULL) typeGenericArguments = &mBestMethodTypeInstance->mGenericTypeInfo->mTypeGenericArguments; @@ -2579,17 +2620,17 @@ bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type) if (constant == NULL) return false; - auto toPrimType = type->ToPrimitiveType(); + auto toPrimType = type->ToPrimitiveType(); if (!mModule->mBfIRBuilder->IsInt(toPrimType->mTypeDef->mTypeCode)) return false; if (type->mSize == 8) return false; - + int64 minVal = -(1LL << (8 * type->mSize - 1)); int64 maxVal = (1LL << (8 * type->mSize - 1)) - 1; - if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal)) - return true; + if ((constant->mInt64 >= minVal) && (constant->mInt64 <= maxVal)) + return true; return false; } @@ -2597,12 +2638,12 @@ bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type) // This method checks all base classes before checking interfaces. Is that correct? bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck) { - BfMethodDef* prevBesstMethodDef = mBestMethodDef; + BfMethodDef* prevBestMethodDef = mBestMethodDef; auto curTypeInst = typeInstance; auto curTypeDef = typeInstance->mTypeDef; - + int checkInterfaceIdx = 0; - + bool targetIsBase = target.IsBase(); bool checkExtensionBase = false; if (targetIsBase) @@ -2614,7 +2655,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe else { curTypeInst = curTypeInst->mBaseType; - } + } } BfTypeInstance* targetTypeInstance = NULL; @@ -2626,7 +2667,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe bool doSearch = true; if ((mMethodType == BfMethodType_Extension) && (!curTypeDef->mHasExtensionMethods)) doSearch = false; - + BfMethodDef* nextMethodDef = NULL; if (doSearch) { @@ -2672,7 +2713,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe checkTypeState = checkTypeState->mPrevState; } - if (isResolvingVarField) + if (isResolvingVarField) { BF_ASSERT(mModule->mBfIRBuilder->mIgnoreWrites); @@ -2680,12 +2721,12 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe // we are not allowed to generate methods when our field types are unknown. We may fix this in the future, // but currently it breaks out expected order of operations. One issue is that our call signatures change // depending on whether we are valueless or splattable, which depend on underlying type information - break; + break; } } if ((checkExtensionBase) && (curTypeInst == mModule->mCurTypeInstance)) - { + { // Accept either a method in the same project but that's the root definition, OR a method that's in a dependent project bool accept = false; if (activeTypeDef->mProject == checkMethod->mDeclaringType->mProject) @@ -2693,7 +2734,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe else accept = activeTypeDef->mProject->ContainsReference(checkMethod->mDeclaringType->mProject); - if (!accept) + if (!accept) continue; } @@ -2701,12 +2742,12 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe { continue; } - + if (checkMethod->mMethodType != mMethodType) continue; // if (checkMethod->mName != mMethodName) -// continue; +// continue; if ((checkMethod->mDeclaringType->IsExtension()) && (mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoExtensionAttributeTypeDef))) @@ -2716,28 +2757,28 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe } if (!isDelegate) - { + { if ((!curTypeInst->IsTypeMemberIncluded(checkMethod->mDeclaringType, activeTypeDef, mModule)) || (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet))) continue; - } + } MatchFailKind matchFailKind = MatchFailKind_None; if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkMethod->mProtection, typeInstance)) { - if ((mBypassVirtual) && + if ((mBypassVirtual) && ((checkMethod->mProtection == BfProtection_Protected) || (checkMethod->mProtection == BfProtection_ProtectedInternal)) && (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, typeInstance))) { // Allow explicit 'base' call - } + } else { if (!isFailurePass) continue; - matchFailKind = MatchFailKind_Protection; + matchFailKind = MatchFailKind_Protection; } - } + } if (mCheckedKind != checkMethod->mCheckedKind) { @@ -2758,21 +2799,105 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe continue; matchFailKind = MatchFailKind_CheckedMismatch; } - } + } CheckMethod(targetTypeInstance, curTypeInst, checkMethod, isFailurePass); if ((isFailurePass) && ((mBestMethodDef == checkMethod) || (mBackupMethodDef == checkMethod))) - mMatchFailKind = matchFailKind; + mMatchFailKind = matchFailKind; } if ((mBestMethodDef != NULL) && (mMethodType != BfMethodType_Extension)) - { + { + if ((mUsingLists != NULL) && (mUsingLists->mSize != 0)) + mUsingLists->Clear(); + if (mAutoFlushAmbiguityErrors) FlushAmbiguityError(); return true; } + if ((mUsingLists != NULL) && (curTypeInst->mTypeDef->mHasUsingFields)) + mModule->PopulateUsingFieldData(curTypeInst); + + if (mUsingLists != NULL) + { + auto _CheckUsingData = [&](BfUsingFieldData* usingData) + { + BfUsingFieldData::Entry* entry = NULL; + if (!usingData->mMethods.TryGetValue(mMethodName, &entry)) + return; + + for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++) + { + bool passesProtection = true; + auto& entryList = entry->mLookups[listIdx]; + for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++) + { + auto& entry = entryList[entryIdx]; + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; + if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject, + (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curTypeInst)) + { + passesProtection = false; + break; + } + } + if (!passesProtection) + continue; + + auto& entry = entryList.back(); + BF_ASSERT(entry.mKind == BfUsingFieldData::MemberRef::Kind_Method); + auto methodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx]; + CheckMethod(curTypeInst, entry.mTypeInstance, methodDef, isFailurePass); + if ((mBestMethodDef != methodDef) && (mBackupMethodDef != methodDef)) + { + bool foundAmbiguous = false; + for (int checkIdx = 0; checkIdx < mAmbiguousEntries.mSize; checkIdx++) + { + if (mAmbiguousEntries[checkIdx].mMethodInstance->mMethodDef == methodDef) + { + mAmbiguousEntries.RemoveAt(checkIdx); + foundAmbiguous = true; + break; + } + } + + if (!foundAmbiguous) + continue; + } + + if (mUsingLists->mSize == 0) + { + mUsingLists->Add(&entryList); + } + else + { + if (entryList.mSize < (*mUsingLists)[0]->mSize) + { + // New is shorter + mUsingLists->Clear(); + mUsingLists->Add(&entryList); + } + else if (entryList.mSize > (*mUsingLists)[0]->mSize) + { + // Ignore longer + } + else + { + mUsingLists->Add(&entryList); + } + } + } + }; + + if ((curTypeInst->mTypeInfoEx != NULL) && (curTypeInst->mTypeInfoEx->mUsingFieldData != NULL)) + _CheckUsingData(curTypeInst->mTypeInfoEx->mUsingFieldData); + + if (mBestMethodDef != NULL) + break; + } + auto baseType = curTypeInst->mBaseType; if (baseType == NULL) { @@ -2803,14 +2928,14 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe if ((isFailurePass) && (mBackupMethodDef != NULL)) break; } - + if (mBestMethodDef == NULL) - { + { // FAILED, but select the first method which will fire an actual error on param type matching mBestMethodDef = mBackupMethodDef; - } + } - if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) || + if (((mBestMethodDef == NULL) && (!target) && (mAllowImplicitThis)) || (forceOuterCheck)) { // No explicit target - maybe this was a static call in the outer type? @@ -2822,7 +2947,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe if (mAutoFlushAmbiguityErrors) FlushAmbiguityError(); - return mBestMethodDef != prevBesstMethodDef; + return mBestMethodDef != prevBestMethodDef; } void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult) @@ -2849,17 +2974,17 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori if (checkType->IsWrappableType()) checkType = mModule->GetWrappedStructType(checkType); if ((checkType != NULL) && (checkType->IsTypeInstance()) && (!checkType->IsInterface())) - { + { BfTypeInterfaceEntry* bestIFaceEntry = NULL; - auto checkTypeInst = checkType->ToTypeInstance(); + auto checkTypeInst = checkType->ToTypeInstance(); if (mBestMethodTypeInstance->IsInstanceOf(mModule->mCompiler->mIHashableTypeDef)) { if ((origTarget != NULL) && (origTarget->mType->IsPointer()) && (staticResult != NULL)) - { + { BfTypedValue ptrVal = mModule->LoadValue(*origTarget); *staticResult = BfTypedValue(mModule->mBfIRBuilder->CreatePtrToInt(ptrVal.mValue, BfTypeCode_IntPtr), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); - return; + return; } } @@ -2867,7 +2992,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori { mModule->PopulateType(checkTypeInst, BfPopulateType_DataAndMethods); for (auto&& iface : checkTypeInst->mInterfaces) - { + { //TODO: Why did we have this check? This caused Dictionary to not be able to devirtualize // calls to TKey GetHashCode when TKey was from a user's project... /*if (!checkTypeInst->IsTypeMemberAccessible(iface.mDeclaringType, activeTypeDef)) @@ -2883,7 +3008,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori bool isBetter; bool isWorse; - mModule->CompareDeclTypes(iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse); + mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { // Failed @@ -2892,7 +3017,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori { if (isBetter) bestIFaceEntry = &iface; - } + } } } @@ -2909,7 +3034,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori break; } } - + if (bestIFaceEntry != NULL) { auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + mBestMethodDef->mIdx]; @@ -2927,7 +3052,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori { // Assert error state? mBestMethodTypeInstance = ifaceMethodEntry.mMethodRef.mTypeInstance; - mBestMethodDef = bestMethodInstance->mMethodDef; + mBestMethodDef = bestMethodInstance->mMethodDef; mBestMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, bestMethodInstance->mMethodDef, mBestMethodGenericArguments, bestMethodInstance->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None, bestMethodInstance->GetForeignType()); @@ -2935,10 +3060,9 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori } else { - // Failed + // Failed mFakeConcreteTarget = true; } - } } } @@ -2946,7 +3070,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori if ((target.mType->IsValueType()) && (mBestMethodTypeInstance->IsObject()) && (mBestMethodDef->mIsVirtual)) { auto structType = target.mType->ToTypeInstance(); - + auto virtualMethodInstance = mModule->GetMethodInstance(mBestMethodTypeInstance, mBestMethodDef, BfTypeVector()); BF_ASSERT(virtualMethodInstance.mMethodInstance->mVirtualTableIdx != -1); @@ -2965,7 +3089,7 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori boxedType = mModule->mContext->mBfObjectType; } - auto methodRef = boxedType->mVirtualMethodTable[virtualMethodInstance.mMethodInstance->mVirtualTableIdx]; + auto methodRef = boxedType->mVirtualMethodTable[virtualMethodInstance.mMethodInstance->mVirtualTableIdx]; if (methodRef.mImplementingMethod.mTypeInstance->IsBoxed()) { auto useModule = mModule->mContext->mUnreifiedModule; @@ -2978,10 +3102,10 @@ void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* ori } else { - mBestMethodTypeInstance = methodRef.mImplementingMethod.mTypeInstance; + mBestMethodTypeInstance = methodRef.mImplementingMethod.mTypeInstance; mBestMethodInstance = mModule->ReferenceExternalMethodInstance(methodRef.mImplementingMethod); - mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef; - } + mBestMethodDef = mBestMethodInstance.mMethodInstance->mMethodDef; + } mBypassVirtual = true; } } @@ -3024,12 +3148,12 @@ void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, if ((checkMethod->mMethodType != mMethodType) || (!checkMethod->mIsStatic)) continue; if (checkMethod->mName != mMethodName) - continue; + continue; if ((!isFailurePass) && (!mModule->CheckProtection(checkMethod->mProtection, NULL, allowProtected, allowPrivate))) continue; - CheckMethod(typeInstance, curTypeInst, checkMethod, isFailurePass); + CheckMethod(typeInstance, curTypeInst, checkMethod, isFailurePass); } if (mBestMethodDef != NULL) @@ -3037,7 +3161,7 @@ void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, auto baseType = curTypeInst->mBaseType; if (baseType == NULL) - break; + break; curTypeDef = baseType->mTypeDef; curTypeInst = baseType; @@ -3048,9 +3172,9 @@ void BfMethodMatcher::CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, } if (mBestMethodDef == NULL) - { + { // FAILED, but select the first method which will fire an actual error on param type matching - mBestMethodDef = mBackupMethodDef; + mBestMethodDef = mBackupMethodDef; } if (mBestMethodDef == NULL) @@ -3087,28 +3211,28 @@ void BfResolvedArgs::HandleFixits(BfModule* module) BfExprEvaluator::BfExprEvaluator(BfModule* module) { mBfEvalExprFlags = BfEvalExprFlags_None; - mModule = module; + mModule = module; mPropDef = NULL; mPropSrc = NULL; mPropGetMethodFlags = BfGetMethodInstanceFlag_None; mPropCheckedKind = BfCheckedKind_NotSet; mUsedAsStatement = false; - mPropDefBypassVirtual = false; - mExpectingType = NULL; - mFunctionBindResult = NULL; - mExplicitCast = false; + mPropDefBypassVirtual = false; + mExpectingType = NULL; + mFunctionBindResult = NULL; + mExplicitCast = false; mDeferCallRef = NULL; mDeferScopeAlloc = NULL; - mPrefixedAttributeState = NULL; + mPrefixedAttributeState = NULL; mResolveGenericParam = true; mNoBind = false; mResultLocalVar = NULL; mResultFieldInstance = NULL; mResultLocalVarField = 0; mResultLocalVarFieldCount = 0; - mResultLocalVarRefNode = NULL; + mResultLocalVarRefNode = NULL; mIsVolatileReference = false; - mIsHeapReference = false; + mIsHeapReference = false; mResultIsTempComposite = false; mAllowReadOnlyReference = false; mInsidePendingNullable = false; @@ -3129,7 +3253,7 @@ BfAutoComplete* BfExprEvaluator::GetAutoComplete() // For local methods- only process autocomplete on capture phase if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (!mModule->mCurMethodState->mClosureState->mCapturing)) return NULL; - + // if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->mIsLocalMethod)) // return NULL; return mModule->mCompiler->mResolvePassData->mAutoComplete; @@ -3160,7 +3284,7 @@ int BfExprEvaluator::GetStructRetIdx(BfMethodInstance* methodInstance, bool forc } BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) -{ +{ if ((mModule->mCurMethodState == NULL) || (mModule->mCurMethodInstance == NULL) || (bindType == NULL)) return bindType; @@ -3171,21 +3295,49 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) return bindType; BF_ASSERT((!mModule->mCurMethodInstance->mIsUnspecializedVariation) || (mModule->mIsComptimeModule)); - + auto parser = node->GetSourceData()->ToParserData(); if (parser == NULL) return bindType; int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart(); auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings; + auto methodInstance = mModule->mCurMethodInstance; - if ((mModule->mCurMethodInstance->mIsUnspecialized) && (!mModule->mCurMethodInstance->mIsUnspecializedVariation)) + bool isMixinBind = false; + if (mModule->mCurMethodState->mMixinState != NULL) { + auto mixinMethodInstance = mModule->mCurMethodState->mMixinState->mMixinMethodInstance; + if (!mixinMethodInstance->mMethodDef->mGenericParams.IsEmpty()) + { + auto unspecMixinMethodInstance = mModule->GetUnspecializedMethodInstance(mixinMethodInstance, false); + + if (!unspecMixinMethodInstance->mHasBeenProcessed) + { + // Make sure the unspecialized method is processed so we can take its bindings + // Clear mCurMethodState so we don't think we're in a local method + SetAndRestoreValue prevMethodState_Unspec(mModule->mCurMethodState, NULL); + if (unspecMixinMethodInstance->mMethodProcessRequest == NULL) + unspecMixinMethodInstance->mDeclModule->mIncompleteMethodCount++; + mModule->mContext->ProcessMethod(unspecMixinMethodInstance); + } + + isMixinBind = true; + methodInstance = mixinMethodInstance; + genericTypeBindings = &unspecMixinMethodInstance->mMethodInfoEx->mGenericTypeBindings; + } + } + + if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation)) + { + if (isMixinBind) + return bindType; + if (!bindType->IsGenericParam()) return bindType; - if (genericTypeBindings == NULL) - return bindType; + if (genericTypeBindings == NULL) + return bindType; (*genericTypeBindings)[nodeId] = bindType; return bindType; @@ -3198,7 +3350,7 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) BfType** typePtr = NULL; if (genericTypeBindings->TryGetValue(nodeId, &typePtr)) return *typePtr; - + return bindType; } } @@ -3222,7 +3374,7 @@ BfType * BfExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateTyp void BfExprEvaluator::ResolveGenericType() { if (mResult) - { + { if (mModule->IsUnboundGeneric(mResult.mType)) mResult.mType = mModule->GetPrimitiveType(BfTypeCode_Var); //mResult.mType = mModule->ResolveGenericType(mResult.mType, true); @@ -3232,11 +3384,11 @@ void BfExprEvaluator::ResolveGenericType() void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional, bool ignoreNullConditional, bool allowSplat) { BP_ZONE("BfExprEvaluator::Evaluate"); - + // ParenthesizedExpression breaks null conditional chain if (astNode->IsExact()) propogateNullConditional = false; - + bool scopeWasConditional = false; BfPendingNullConditional* pendingNullCond = NULL; @@ -3252,16 +3404,16 @@ void BfExprEvaluator::Evaluate(BfAstNode* astNode, bool propogateNullConditional mInsidePendingNullable = true; mModule->mCurMethodState->mCurScope->mIsConditional = true; } - } - - astNode->Accept(this); + } + + astNode->Accept(this); GetResult(); if ((mResultIsTempComposite) && (mResult.IsAddr())) mResult.mKind = BfTypedValueKind_TempAddr; if ((!allowSplat) && (mResult.IsSplat())) - mResult = mModule->AggregateSplat(mResult); + mResult = mModule->AggregateSplat(mResult); if ((mBfEvalExprFlags & BfEvalExprFlags_AllowIntUnknown) == 0) mModule->FixIntUnknown(mResult); @@ -3315,11 +3467,11 @@ void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr) { BfAttributeState attributeState; attributeState.mSrc = attribExpr->mAttributes; - attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess); - if (auto block = BfNodeDynCast(attribExpr->mExpression)) + attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess); + if (auto block = BfNodeDynCast(attribExpr->mExpression)) attributeState.mTarget = BfAttributeTargets_Block; - attributeState.mCustomAttributes = mModule->GetCustomAttributes(attribExpr->mAttributes, attributeState.mTarget); + attributeState.mCustomAttributes = mModule->GetCustomAttributes(attribExpr->mAttributes, attributeState.mTarget); SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); if (auto ignoreErrorsAttrib = attributeState.mCustomAttributes->Get(mModule->mCompiler->mIgnoreErrorsAttributeTypeDef)) @@ -3333,7 +3485,7 @@ void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr) } VisitChild(attribExpr->mExpression); attributeState.mUsed = true; - + if ((!mResult) || ((mResult) && (mResult.mType->IsVar()))) { @@ -3362,7 +3514,13 @@ void BfExprEvaluator::Visit(BfAttributedExpression* attribExpr) VisitChild(attribExpr->mExpression); } - mModule->FinishAttributeState(&attributeState); + mModule->FinishAttributeState(&attributeState); +} + +void BfExprEvaluator::Visit(BfNamedExpression* namedExpr) +{ + if (namedExpr->mExpression != NULL) + VisitChild(namedExpr->mExpression); } void BfExprEvaluator::Visit(BfBlock* blockExpr) @@ -3377,7 +3535,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr) if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(blockExpr))) { // Don't show outer method match info when our cursor is inside a block (being passed as a parameter) - autoComplete->RemoveMethodMatchInfo(); + autoComplete->RemoveMethodMatchInfo(); } if (blockExpr->mChildArr.IsEmpty()) @@ -3394,12 +3552,12 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr) } else if (blockExpr->mChildArr.GetLast()->IsExpression()) { - // Expression + // Expression } else { mModule->Fail("Expression blocks must end with an expression", blockExpr); - } + } mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None); } @@ -3421,7 +3579,7 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir checkChild = parentNodeEntry->mNode; parentNodeEntry = parentNodeEntry->mPrev; } - } + } auto _Fail = [&](const StringImpl& errorStr, BfAstNode* node) { @@ -3437,7 +3595,7 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir }; while (parentNodeEntry != NULL) - { + { BfAstNode* checkParent = parentNodeEntry->mNode; if (auto binOpExpr = BfNodeDynCastExact(checkParent)) @@ -3449,16 +3607,16 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir } else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue)) { - if ((binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild))) + if ((binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild))) { - return _Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken); + return _Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken); } } else { if (exprMustBeTrue) { - return _Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken); + return _Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken); } } } @@ -3467,7 +3625,7 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir // This is okay } else if (auto unaryOp = BfNodeDynCast(checkParent)) - { + { if (exprMustBeTrue) { return _Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken); @@ -3475,8 +3633,8 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir } if (childWasAndRHS) - { - return _Fail("Operator may allow conditional short-circuiting to skip variable initialization", unaryOp->mOpToken); + { + return _Fail("Operator may allow conditional short-circuiting to skip variable initialization", unaryOp->mOpToken); } } else if (auto ifStmt = BfNodeDynCast(checkParent)) @@ -3489,7 +3647,7 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir { if (requireSimpleIfExpr) { - return _Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode); + return _Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode); } break; } @@ -3508,7 +3666,7 @@ bool BfExprEvaluator::HasVariableDeclaration(BfAstNode* checkNode) } void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl) -{ +{ mModule->UpdateExprSrcPos(varDecl); if ((mModule->mCurMethodState == NULL) || (!mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations)) @@ -3517,10 +3675,10 @@ void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl) if (varDecl->mInitializer != NULL) { VisitChild(varDecl->mInitializer); - } + } return; } - + CheckVariableDeclaration(varDecl, true, false, false); if (varDecl->mInitializer == NULL) { @@ -3534,7 +3692,7 @@ void BfExprEvaluator::Visit(BfVariableDeclaration* varDecl) mModule->HandleTupleVariableDeclaration(varDecl); } else - mModule->HandleVariableDeclaration(varDecl, this); + mModule->HandleVariableDeclaration(varDecl, this); } void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) @@ -3556,14 +3714,14 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) if (caseValAddr.mType != NULL) mModule->mBfIRBuilder->PopulateType(caseValAddr.mType); - + if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mDeferredLocalAssignData != NULL)) mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain(); if (auto bindExpr = BfNodeDynCast(caseExpr->mCaseExpression)) - { + { if (caseValAddr) - { + { BfTypedValue enumTagVal; if (caseValAddr.mType->IsPayloadEnum()) { @@ -3582,9 +3740,9 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) bool isPayloadEnum = (caseValAddr.mType != NULL) && (caseValAddr.mType->IsPayloadEnum()); auto tupleExpr = BfNodeDynCast(caseExpr->mCaseExpression); - if ((caseValAddr) && + if ((caseValAddr) && ((isPayloadEnum) || (tupleExpr != NULL))) - { + { bool hasVariable = false; bool hasOut = false; bool clearOutOnMismatch = false; @@ -3594,25 +3752,25 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) { if (auto varDecl = BfNodeDynCast(arg)) { - hasVariable = true; + hasVariable = true; } else if (auto unaryOpExpr = BfNodeDynCast(arg)) { - if (unaryOpExpr->mOpToken->mToken == BfToken_Out) + if ((unaryOpExpr->mOpToken != NULL) && (unaryOpExpr->mOpToken->mToken == BfToken_Out)) { hasOut = true; } } } } - + if (hasVariable) { CheckVariableDeclaration(caseExpr, false, true, false); } // We can avoid clearing on mismatch if we can be sure we ONLY enter the true block on a match. - // An example of requiring clearing is: if ((result case .Ok(out val)) || (force)) + // An example of requiring clearing is: if ((result case .Ok(out val)) || (force)) if (hasOut) clearOutOnMismatch = !CheckVariableDeclaration(caseExpr, true, true, true); @@ -3622,21 +3780,20 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) int dscrDataIdx; auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx); auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2)); - int uncondTagId = -1; + int uncondTagId = -1; mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, false); } else { mResult = mModule->TryCaseTupleMatch(caseValAddr, tupleExpr, NULL, NULL, NULL, hadConditional, clearOutOnMismatch, false); } - + if (mResult) return; - } if ((caseValAddr) && (IsVar(caseValAddr.mType))) - { + { auto invocationExpr = BfNodeDynCast(caseExpr->mCaseExpression); if (invocationExpr != NULL) { @@ -3656,8 +3813,8 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean); mResult = mModule->GetDefaultTypedValue(boolType); - return; - } + return; + } auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean); BfTypedValue caseMatch; @@ -3673,7 +3830,7 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) { if (((caseValAddr.mType->IsEnum()) && (caseValAddr.mType->IsStruct())) && ((caseMatch) && (caseMatch.mType->IsPayloadEnum()) && (caseMatch.mValue.IsConst()))) - { + { BfTypedValue enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2)); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseMatch.mValue), boolType); return; @@ -3688,7 +3845,7 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr) // Is it possible this could throw an error twice? Hope not. caseMatch = mModule->CreateValueFromExpression(caseExpr->mCaseExpression, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); } - } + } PerformBinaryOperation(caseExpr->mCaseExpression, caseExpr->mValueExpression, BfBinaryOp_Equality, caseExpr->mEqualsNode, BfBinOpFlag_None, caseValAddr, caseMatch); } @@ -3711,6 +3868,49 @@ static bool IsCharType(BfTypeCode typeCode) } } +bool BfExprEvaluator::CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName) +{ + BF_ASSERT((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0); + + auto autoComplete = GetAutoComplete(); + + while (typeInst != NULL) + { + auto typeDef = typeInst->mTypeDef; + typeDef->PopulateMemberSets(); + + BfMemberSetEntry* memberSetEntry; + if (typeDef->mMethodSet.TryGetWith(findName, &memberSetEntry)) + { + if (mModule->mCompiler->mResolvePassData != NULL) + mModule->mCompiler->mResolvePassData->HandleMethodReference(refNode, typeDef, (BfMethodDef*)memberSetEntry->mMemberDef); + + if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(refNode))) + { + autoComplete->SetDefinitionLocation(((BfMethodDef*)memberSetEntry->mMemberDef)->GetRefNode()); + if ((autoComplete->mResolveType == BfResolveType_GetSymbolInfo) && (autoComplete->mDefType == NULL)) + { + autoComplete->mDefType = typeDef; + autoComplete->mDefMethod = (BfMethodDef*)memberSetEntry->mMemberDef; + } + } + + if (mModule->mCompiler->mResolvePassData != NULL) + { + if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(refNode)) + sourceClassifier->SetElementType(refNode, BfSourceElementType_Method); + } + + mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOfSuccess); + return true; + } + + typeInst = typeInst->mBaseType; + } + + return false; +} + bool BfExprEvaluator::IsVar(BfType* type, bool forceIgnoreWrites) { if (type->IsVar()) @@ -3735,11 +3935,11 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant) } break; case BfTypeCode_CharPtr: - { + { if ((mExpectingType != NULL) && (mExpectingType->IsSizedArray())) { auto sizedArray = (BfSizedArrayType*)mExpectingType; - + if (sizedArray->mElementType == mModule->GetPrimitiveType(BfTypeCode_Char8)) { if (variant.mString->GetLength() > sizedArray->mElementCount) @@ -3802,9 +4002,9 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant) mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, variant.mUInt64), mExpectingType); break; } - } + } - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode)); + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(variant.mTypeCode, variant.mUInt64), mModule->GetPrimitiveType(variant.mTypeCode)); break; case BfTypeCode_Float: @@ -3862,7 +4062,7 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef))) { mModule->mAttributeState->mUsed = true; - mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); + mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); } if (IsConstEval()) @@ -3886,7 +4086,7 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression); } - } + } if (stringInterpolationExpression->mAllocNode != NULL) { @@ -3913,7 +4113,7 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation mResult = newString; return; - } + } mModule->Fail("Invalid use of string interpolation expression. Consider adding an allocation specifier such as 'scope'.", stringInterpolationExpression); @@ -3924,11 +4124,11 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation } BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef) -{ +{ if (!mModule->mIsInsideAutoComplete) - varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; + varDecl->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; - // The Beef backend prefers readonly addrs since that reduces register pressure, whereas + // The Beef backend prefers readonly addrs since that reduces register pressure, whereas // LLVM prefers values to avoid memory loads. This only applies to primitive types... bool preferValue = (varDecl->mResolvedType->IsPrimitiveType()) && (!mModule->IsTargetingBeefBackend()); @@ -3939,13 +4139,11 @@ BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef) } else if (varDecl->mConstValue) { - localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false); + localResult = BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType, false); } else if (varDecl->mIsSplat) - { - if ((!preferValue) && (varDecl->mAddr)) - localResult = BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_SplatHead); - else if (!varDecl->mResolvedType->IsValuelessType()) + { + if (!varDecl->mResolvedType->IsValuelessType()) localResult = BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_SplatHead); else if ((varDecl->mResolvedType->IsRef()) && (!allowRef)) { @@ -4048,16 +4246,16 @@ BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef) if (varType->IsRef()) { BfRefType* refType = (BfRefType*)varType; - allocType = refType->mElementType; + allocType = refType->mElementType; } auto declType = varDecl->mResolvedType; if (declType->IsRef()) { BfRefType* refType = (BfRefType*)declType; - declType = refType->mElementType; + declType = refType->mElementType; } - + mModule->PopulateType(allocType); varDecl->mAddr = mModule->mBfIRBuilder->CreateAlloca(mModule->mBfIRBuilder->MapType(allocType)); localResult = BfTypedValue(varDecl->mAddr, declType, true); @@ -4066,7 +4264,7 @@ BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef) if ((varDecl->mIsThis) && (localResult.mKind == BfTypedValueKind_Value)) localResult.mKind = BfTypedValueKind_ThisValue; - + return localResult; } @@ -4093,13 +4291,13 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if ((mModule->mCompiler->mCeMachine != NULL) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL)) { - auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger; + auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger; auto ceContext = ceDebugger->mCurDbgState->mCeContext; auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame; if (activeFrame->mFunction->mDbgInfo != NULL) { int varSkipCountLeft = varSkipCount; - int instIdx = activeFrame->GetInstIdx(); + int instIdx = activeFrame->GetInstIdx(); for (int i = activeFrame->mFunction->mDbgInfo->mVariables.mSize - 1; i >= 0; i--) { @@ -4135,7 +4333,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if (mModule->mCurMethodState != NULL) { auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); - + auto checkMethodState = mModule->mCurMethodState; bool isMixinOuterVariablePass = false; @@ -4147,7 +4345,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing)) { closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType; - } + } int varSkipCountLeft = varSkipCount; @@ -4158,7 +4356,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if (varDecl != NULL) varSkipCountLeft -= varDecl->mNamePrefixCount; - + while ((varSkipCountLeft > 0) && (varDecl != NULL)) { varDecl = varDecl->mShadowedLocal; @@ -4174,7 +4372,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI { if ((closureTypeInst != NULL) && (wantName == "this")) break; - + if ((varDecl->mCompositeCount >= 0) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) == 0)) { mModule->Fail("Invalid use of 'params' parameter", refNode); @@ -4199,7 +4397,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI (mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCurMethodInstance != NULL) && (!mModule->mCurMethodState->IsTemporary())) mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, varDecl->mNameNode, mModule->mCurTypeInstance->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, varDecl->mLocalVarId); } - + if (!isMixinOuterVariablePass) { mResultLocalVar = varDecl; @@ -4212,14 +4410,14 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI // Check for the captured locals. It's important we do it here so we get local-first precedence still if (closureTypeInst != NULL) - { + { int varSkipCountLeft = varSkipCount; closureTypeInst->mTypeDef->PopulateMemberSets(); BfMemberSetEntry* memberSetEntry = NULL; if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith((StringImpl&)findName, &memberSetEntry)) - { - auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef; + { + auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef; auto& field = closureTypeInst->mFieldInstances[fieldDef->mIdx]; if (!field.mResolvedType->IsValuelessType()) { @@ -4261,13 +4459,13 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI bool isLocalMixinProcessing = false; if ((checkMethodState->mClosureState != NULL) && (!checkMethodState->mClosureState->mCapturing) && (closureTypeInst == NULL) && (mModule->mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)) - isLocalMixinProcessing = true; + isLocalMixinProcessing = true; if (!isLocalMixinProcessing) break; isMixinOuterVariablePass = true; checkMethodState = checkMethodState->mPrevMethodState; - } + } } if ((mModule->mCurMethodInstance == NULL) && (mModule->mCurTypeInstance != NULL) && (mModule->mCurTypeInstance->IsEnum())) @@ -4285,9 +4483,9 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI } checkTypeState = checkTypeState->mPrevState; } - - if ((resolvingFieldDef != NULL) && - (mModule->mCompiler->mResolvePassData != NULL) && + + if ((resolvingFieldDef != NULL) && + (mModule->mCompiler->mResolvePassData != NULL) && (!mModule->mCompiler->mResolvePassData->mParsers.IsEmpty()) && (mModule->mCompiler->mResolvePassData->mParsers[0] == resolvingFieldDef->mFieldDeclaration->GetParser()) && (GetAutoComplete() != NULL)) @@ -4298,7 +4496,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI { auto enumType = mModule->mCurTypeInstance; if (!enumType->mFieldInstances.IsEmpty()) - { + { auto fieldInstance = &mModule->mCurTypeInstance->mFieldInstances[resolvingFieldDef->mIdx - 1]; if ((fieldInstance->mConstIdx != -1) && (fieldInstance->mResolvedType == mModule->mCurTypeInstance)) @@ -4339,7 +4537,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI MakeBaseConcrete(baseValue); } mModule->MarkUsingThis(); - return baseValue; + return baseValue; } if (!mModule->mCurMethodState->HasNonStaticMixin()) @@ -4350,15 +4548,15 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI } } - if (!thisValue.HasType()) - { + if (!thisValue.HasType()) + { if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mType == mModule->mCurTypeInstance) && (mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes)) { // Can't do static lookups yet } else - thisValue = BfTypedValue(mModule->mCurTypeInstance); + thisValue = BfTypedValue(mModule->mCurTypeInstance); } BfTypedValue result; @@ -4369,8 +4567,8 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI { mResultLocalVar = NULL; mResultLocalVarRefNode = NULL; - } - } + } + } if (mPropDef != NULL) { @@ -4402,7 +4600,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI result = LookupField(identifierNode, thisValue, findName); if ((result) || (mPropDef != NULL)) return result; - } + } } auto staticSearch = mModule->GetStaticSearch(); @@ -4469,7 +4667,7 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI if (thisLocal->mIsThis) return BfTypedValue(mModule->mBfIRBuilder->CreateLoad(thisLocal->mAddr), thisLocal->mResolvedType); } - } + } } return result; @@ -4484,21 +4682,21 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode, auto qualifiedResult = mResult; mResult = BfTypedValue(); return qualifiedResult; - } + } StringT<128> identifierStr; identifierNode->ToString(identifierStr); - return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError); + return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError); } void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode) { auto autoComplete = GetAutoComplete(); - + if (autoComplete != NULL) autoComplete->CheckIdentifier(identifierNode, true); - - mResult = LookupIdentifier(identifierNode); + + mResult = LookupIdentifier(identifierNode); if ((!mResult) && (mPropDef == NULL)) { mModule->CheckTypeRefFixit(identifierNode); @@ -4506,7 +4704,7 @@ void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode) { if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing)) { - // During this phase we don't have lambda and local method params available so they would result in erroneous fixits + // During this phase we don't have lambda and local method params available so they would result in erroneous fixits } else if (mModule->mCurMethodInstance != NULL) { @@ -4524,7 +4722,7 @@ void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode) continue; if (!typeDef->IsGlobalsContainer()) continue; - + typeDef->PopulateMemberSets(); String findName = identifierNode->ToString(); @@ -4536,10 +4734,13 @@ void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode) if (mModule->GetActiveTypeDef()->mProject->ContainsReference(typeDef->mProject)) autoComplete->FixitAddNamespace(identifierNode, typeDef->mNamespace.ToString()); } - } + } } } + if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (mModule->mCurTypeInstance != NULL) && (CheckForMethodName(identifierNode, mModule->mCurTypeInstance, identifierNode->ToString()))) + return; + if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0) mModule->Fail("Identifier not found", identifierNode); } @@ -4559,7 +4760,7 @@ void BfExprEvaluator::Visit(BfAttributedIdentifierNode* attrIdentifierNode) SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); mModule->mAttributeState->mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierNode->mAttributes, mModule->mAttributeState->mTarget); VisitChild(attrIdentifierNode->mIdentifier); - } + } } static int gPropIdx = 0; @@ -4567,7 +4768,7 @@ static int gPropIdx = 0; void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic) { if (fieldType == NULL) - { + { fieldType = mExpectingType; } @@ -4580,8 +4781,18 @@ void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance); } +BfTypedValue BfExprEvaluator::TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken) +{ + auto arrowValue = PerformUnaryOperation_TryOperator(typedValue, NULL, BfUnaryOp_Arrow, arrowToken, BfUnaryOpFlag_None); + if (arrowValue) + return arrowValue; + if (mModule->PreFail()) + mModule->Fail(StrFormat("Type '%s' does not contain a '->' operator", mModule->TypeToString(typedValue.mType).c_str()), arrowToken); + return typedValue; +} + BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInlined) -{ +{ if ((flags & BfLookupFieldFlag_IsAnonymous) == 0) mModule->SetElementType(targetSrc, BfSourceElementType_Method); @@ -4617,7 +4828,7 @@ BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue ta mModule->TypeToString(typeInstance).c_str(), mPropDef->mName.c_str()), targetSrc); } } - + bool isBaseLookup = (target.mType) && (typeInstance != target.mType); if ((isBaseLookup) && (target.mType->IsWrappableType())) isBaseLookup = false; @@ -4646,6 +4857,8 @@ BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue ta } mOrigPropTarget = mPropTarget; + if (prop->mIsStatic) + mOrigPropTarget = target; if ((flags & BfLookupFieldFlag_IsAnonymous) == 0) { @@ -4733,7 +4946,7 @@ BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue ta mPropDef = NULL; mPropSrc = NULL; - mOrigPropTarget = NULL; + mOrigPropTarget = BfTypedValue(); return result; } } @@ -4770,7 +4983,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe } auto resolvePassData = mModule->mCompiler->mResolvePassData; - if ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field)) + if ((resolvePassData != NULL) && (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && ((flags & BfLookupFieldFlag_IsAnonymous) == 0)) { resolvePassData->HandleFieldReference(targetSrc, typeInstance->mTypeDef, fieldDef); } @@ -4880,7 +5093,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), targetSrc); } - // Target must be an implicit 'this', or an error (accessing a static with a non-static target). + // Target must be an implicit 'this', or an error (accessing a static with a non-static target). // Not actually needed in either case since this is a static lookup. mResultLocalVar = NULL; } @@ -4953,6 +5166,42 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe bool isStaticCtor = (mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) && (mModule->mCurMethodInstance->mMethodDef->mIsStatic); + + if ((mModule->mCompiler->mOptions.mRuntimeChecks) && (fieldInstance->IsAppendedObject()) && (!mModule->mBfIRBuilder->mIgnoreWrites) && + (!mModule->IsSkippingExtraResolveChecks())) + { + auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); + auto intPtrType = mModule->CreatePointerType(intType); + auto intPtrVal = mModule->mBfIRBuilder->CreateBitCast(retVal.mValue, mModule->mBfIRBuilder->MapType(intPtrType)); + auto intVal = mModule->mBfIRBuilder->CreateLoad(intPtrVal); + + auto oobBlock = mModule->mBfIRBuilder->CreateBlock("oob", true); + auto contBlock = mModule->mBfIRBuilder->CreateBlock("cont", true); + + auto cmpRes = mModule->mBfIRBuilder->CreateCmpEQ(intVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0)); + mModule->mBfIRBuilder->CreateCondBr(cmpRes, oobBlock, contBlock); + + mModule->mBfIRBuilder->SetInsertPoint(oobBlock); + auto internalType = mModule->ResolveTypeDef(mModule->mCompiler->mInternalTypeDef); + auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowObjectNotInitialized"); + if (oobFunc.mFunc) + { + if (mModule->mIsComptimeModule) + mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc); + + SizedArray args; + args.push_back(mModule->GetConstValue(0)); + mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args); + mModule->mBfIRBuilder->CreateUnreachable(); + } + else + { + mModule->Fail("System.Internal class must contain method 'ThrowObjectNotInitialized'", fieldDef->GetRefNode()); + } + + mModule->mBfIRBuilder->SetInsertPoint(contBlock); + } + if ((fieldDef->mIsReadOnly) && (!isStaticCtor)) { if (retVal.IsAddr()) @@ -4964,7 +5213,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe } else if (!target) { - if (mModule->PreFail()) + if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (mModule->PreFail())) { if ((flags & BfLookupFieldFlag_CheckingOuter) != 0) mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(typeInstance).c_str(), fieldDef->mName.c_str()), @@ -5020,7 +5269,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe mModule->mBfIRBuilder->CreateStore(target.mValue, elementAddr); target = BfTypedValue(allocaInst, primStructType, true); } - + BfTypedValue targetValue; if ((target.mType != typeInstance) && (!target.IsSplat())) { @@ -5080,8 +5329,16 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe if ((targetValue.IsAddr()) && (!typeInstance->IsValueType())) targetValue = mModule->LoadValue(targetValue); - retVal = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx/*, fieldDef->mName*/), - resolvedFieldType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); + if (fieldInstance->IsAppendedObject()) + { + auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx); + retVal = BfTypedValue(mModule->mBfIRBuilder->CreateBitCast(elemPtr, mModule->mBfIRBuilder->MapType(resolvedFieldType)), resolvedFieldType); + } + else + { + retVal = BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(targetValue.mValue, 0, fieldInstance->mDataIdx/*, fieldDef->mName*/), + resolvedFieldType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); + } } if (!retVal.IsSplat()) @@ -5093,6 +5350,9 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe } } + if ((fieldDef->mIsVolatile) && (retVal.IsAddr())) + retVal.mKind = BfTypedValueKind_VolatileAddr; + if (wantsLoadValue) retVal = mModule->LoadValue(retVal, NULL, mIsVolatileReference); else @@ -5127,7 +5387,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar { auto result = LookupField(targetSrc, BfTypedValue(target.mValue, iface), fieldName, flags); if ((result) || (mPropDef != NULL)) - { + { return result; } } @@ -5145,7 +5405,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if (genericParamInst->mTypeConstraint != NULL) { - target.mType = genericParamInst->mTypeConstraint; + target.mType = genericParamInst->mTypeConstraint; } else target.mType = mModule->mContext->mBfObjectType; @@ -5200,11 +5460,11 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar return BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true); BfTypeInstance* startCheckType = mModule->mCurTypeInstance; - mPropDef = NULL; + mPropDef = NULL; mPropDefBypassVirtual = false; - + if (target) - { + { if ((!target.mType->IsValueType()) && (target.IsAddr())) target = mModule->LoadValue(target); @@ -5224,9 +5484,9 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar } } //BF_ASSERT(startCheckType != NULL); - } + } else if (target.mType != NULL) - { + { startCheckType = target.mType->ToTypeInstance(); } @@ -5240,14 +5500,6 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar mModule->PopulateType(startCheckType, BfPopulateType_BaseType); } - if ((startCheckType != NULL) && (mModule->mContext->mCurTypeState != NULL)) - { - // Don't allow lookups yet - if ((mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes) && - (startCheckType == mModule->mContext->mCurTypeState->mType)) - return BfTypedValue(); - } - String findName; int varSkipCount = 0; if (fieldName.StartsWith('@')) @@ -5261,7 +5513,6 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar } else findName.Reference(fieldName); - auto activeTypeDef = mModule->GetActiveTypeDef(); for (int pass = 0; pass < 2; pass++) @@ -5271,10 +5522,35 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if (isFailurePass) flags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsFailurePass); - + bool isBaseLookup = false; while (curCheckType != NULL) { + /// + { + bool isPopulatingType = false; + + auto checkTypeState = mModule->mContext->mCurTypeState; + while (checkTypeState != NULL) + { + if (curCheckType == checkTypeState->mType) + { + isPopulatingType = true; + if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes) + { + // Don't allow lookups yet + return BfTypedValue(); + } + } + checkTypeState = checkTypeState->mPrevState; + } + if ((!isPopulatingType) && (curCheckType->mDefineState < Beefy::BfTypeDefineState_Defined)) + { + // We MAY have emitted fields so we need to do this + mModule->mContext->mUnreifiedModule->PopulateType(curCheckType, Beefy::BfPopulateType_Interfaces_All); + } + } + curCheckType->mTypeDef->PopulateMemberSets(); BfFieldDef* nextField = NULL; BfMemberSetEntry* entry; @@ -5320,12 +5596,12 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if (((flags & BfLookupFieldFlag_IgnoreProtection) == 0) && (!isFailurePass) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, field->mDeclaringType->mProject, checkProtection, startCheckType))) - { - continue; - } - + { + continue; + } + bool isResolvingFields = curCheckType->mResolvingConstField || curCheckType->mResolvingVarField; - + if (curCheckType->mFieldInstances.IsEmpty()) { mModule->PopulateType(curCheckType, BfPopulateType_Data); @@ -5344,7 +5620,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx]; if (!fieldInstance->mFieldIncluded) continue; - + if (curCheckType->IsUnspecializedType()) { // The check for non-unspecialized types is already handled in mFieldIncluded @@ -5374,11 +5650,11 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if (matchedField != NULL) return LoadField(targetSrc, target, curCheckType, matchedField, flags); - - BfPropertyDef* nextProp = NULL; + + BfPropertyDef* nextProp = NULL; if (curCheckType->mTypeDef->mPropertySet.TryGetWith(fieldName, &entry)) nextProp = (BfPropertyDef*)entry->mMemberDef; - + if (nextProp != NULL) { BfCheckedKind checkedKind = BfCheckedKind_NotSet; @@ -5409,21 +5685,21 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar auto prop = nextProp; nextProp = nextProp->mNextWithSameName; - if ((!isFailurePass) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType))) + if ((!isFailurePass) && ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) == 0) && (!mModule->CheckProtection(protectionCheckFlags, curCheckType, prop->mDeclaringType->mProject, prop->mProtection, startCheckType))) { continue; } - + if (!prop->mMethods.IsEmpty()) { BfMethodDef* checkMethod = prop->mMethods[0]; // Properties with explicit interfaces or marked as overrides can only be called indirectly - if ((checkMethod->mExplicitInterface != NULL) || (checkMethod->mIsOverride)) + if ((checkMethod->mExplicitInterface != NULL) || (checkMethod->mIsOverride)) continue; } - - if ((!target.IsStatic()) || (prop->mIsStatic)) - { + + if ((!target.IsStatic()) || (prop->mIsStatic) || ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0)) + { if (!mModule->IsInSpecializedSection()) { if ((!curCheckType->IsTypeMemberIncluded(prop->mDeclaringType, activeTypeDef, mModule)) || @@ -5453,187 +5729,140 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar return LoadProperty(targetSrc, target, curCheckType, matchedProp, flags, checkedKind, isInlined); } - if ((curCheckType->mTypeDef->mHasUsingFields) && ((flags & BfLookupFieldFlag_BindOnly) == 0)) + if (curCheckType->mTypeDef->mHasUsingFields) + mModule->PopulateUsingFieldData(curCheckType); + + /// { - auto usingFieldData = curCheckType->mTypeDef->mUsingFieldData; - - BfUsingFieldData::Entry* usingEntry = NULL; - if (usingFieldData->mEntries.TryAdd(findName, NULL, &usingEntry)) + Array*> foundLists; + + auto _CheckUsingData = [&](BfUsingFieldData* usingData) { - HashSet checkedTypeSet; - BfUsingFieldData::FieldRef firstFoundField; + BfUsingFieldData::Entry* entry = NULL; + if (!usingData->mEntries.TryGetValue(findName, &entry)) + return; - std::function _CheckTypeDef = [&](BfTypeInstance* usingType) + for (int listIdx = 0; listIdx < entry->mLookups.mSize; listIdx++) { - if (!checkedTypeSet.Add(usingType)) - return false; - - BfFieldDef* matchedField = NULL; - BfTypeInstance* matchedTypeInst = NULL; - - if (curCheckType != usingType) + bool passesProtection = true; + auto& entryList = entry->mLookups[listIdx]; + for (int entryIdx = 0; entryIdx < entryList.mSize; entryIdx++) { - auto curUsingType = usingType; - while (curUsingType != NULL) + auto& entry = entryList[entryIdx]; + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; + if (!mModule->CheckProtection(protectionCheckFlags, entry.mTypeInstance, entry.GetDeclaringType(mModule)->mProject, + (entryIdx < entryList.mSize - 1) ? entry.GetUsingProtection() : entry.GetProtection(), curCheckType)) { - curUsingType->mTypeDef->PopulateMemberSets(); - - BfFieldDef* nextField = NULL; - BfMemberSetEntry* entry; - if (curUsingType->mTypeDef->mFieldSet.TryGetWith(findName, &entry)) - nextField = (BfFieldDef*)entry->mMemberDef; - - while (nextField != NULL) - { - auto field = nextField; - nextField = nextField->mNextWithSameName; - - if (!mModule->CheckProtection(protectionCheckFlags, curUsingType, field->mDeclaringType->mProject, field->mProtection, usingType)) - continue; - - matchedTypeInst = curUsingType; - matchedField = field; - break; - } - - if (matchedField == NULL) - { - BfPropertyDef* nextProp = NULL; - if (curUsingType->mTypeDef->mPropertySet.TryGetWith(findName, &entry)) - nextProp = (BfPropertyDef*)entry->mMemberDef; - while (nextProp != NULL) - { - auto propDef = nextProp; - nextProp = nextProp->mNextWithSameName; - - if (!mModule->CheckProtection(protectionCheckFlags, curUsingType, propDef->mDeclaringType->mProject, propDef->mProtection, usingType)) - continue; - - matchedTypeInst = curUsingType; - matchedField = propDef; - break; - } - } - - if (matchedField != NULL) - { - if (firstFoundField.mTypeInstance == NULL) - { - firstFoundField = BfUsingFieldData::FieldRef(curUsingType, matchedField); - } - else - { - usingEntry->mConflicts.Add(firstFoundField); - usingEntry->mConflicts.Add(BfUsingFieldData::FieldRef(curUsingType, matchedField)); - } - break; - } - - curUsingType = curUsingType->mBaseType; - } - } - - auto curUsingType = usingType; - while (curUsingType != NULL) - { - if (curUsingType->mTypeDef->mUsingFieldData != NULL) - { - for (auto fieldDef : curUsingType->mTypeDef->mUsingFieldData->mUsingFields) - { - if (!mModule->CheckProtection(protectionCheckFlags, curUsingType, fieldDef->mDeclaringType->mProject, fieldDef->mUsingProtection, usingType)) - continue; - - if (fieldDef->mIsProperty) - { - auto propDef = (BfPropertyDef*)fieldDef; - for (auto methodDef : propDef->mMethods) - { - if (methodDef->mMethodType == BfMethodType_PropertyGetter) - { - auto methodInstance = mModule->GetRawMethodInstance(curUsingType, methodDef); - if (methodInstance == NULL) - continue; - BfType* returnType = methodInstance->mReturnType; - if ((returnType->IsRef()) || (returnType->IsPointer())) - returnType = returnType->GetUnderlyingType(); - auto fieldTypeInst = returnType->ToTypeInstance(); - if ((fieldTypeInst != NULL) && (_CheckTypeDef(fieldTypeInst))) - usingEntry->mLookup.Insert(0, BfUsingFieldData::FieldRef(curUsingType, fieldDef)); - } - } - } - else - { - if (curUsingType->mFieldInstances.IsEmpty()) - mModule->PopulateType(curCheckType, BfPopulateType_Data); - BF_ASSERT(fieldDef->mIdx < (int)curUsingType->mFieldInstances.size()); - auto fieldInstance = &curUsingType->mFieldInstances[fieldDef->mIdx]; - if (!fieldInstance->mFieldIncluded) - continue; - auto fieldType = fieldInstance->mResolvedType; - if (fieldType->IsPointer()) - fieldType = fieldType->GetUnderlyingType(); - auto fieldTypeInst = fieldType->ToTypeInstance(); - if ((fieldTypeInst != NULL) && (_CheckTypeDef(fieldTypeInst))) - usingEntry->mLookup.Insert(0, BfUsingFieldData::FieldRef(curUsingType, fieldDef)); - } - } + passesProtection = false; + break; } - curUsingType = curUsingType->mBaseType; } - - if ((matchedField != NULL) && (usingEntry->mLookup.IsEmpty())) + if (!passesProtection) + continue; + + if (foundLists.mSize == 0) { - usingEntry->mLookup.Add(BfUsingFieldData::FieldRef(matchedTypeInst, matchedField)); - return true; + foundLists.Add(&entryList); } - - return false; - }; - _CheckTypeDef(curCheckType); - } - - if ((!usingEntry->mConflicts.IsEmpty()) && (mModule->PreFail())) - { - BfError* error = mModule->Fail("Ambiguous 'using' field reference", targetSrc); - if (error != NULL) - { - for (auto& conflict : usingEntry->mConflicts) + else { - mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("'%s.%s' is a candidate", mModule->TypeToString(conflict.mTypeInstance).c_str(), conflict.mFieldDef->mName.c_str()), conflict.mFieldDef->GetRefNode()); + if (entryList.mSize < foundLists[0]->mSize) + { + // New is shorter + foundLists.Clear(); + foundLists.Add(&entryList); + } + else if (entryList.mSize > foundLists[0]->mSize) + { + // Ignore longer + } + else + { + foundLists.Add(&entryList); + } } } - } + }; - if (!usingEntry->mLookup.IsEmpty()) + if ((curCheckType->mTypeInfoEx != NULL) && (curCheckType->mTypeInfoEx->mUsingFieldData != NULL)) + _CheckUsingData(curCheckType->mTypeInfoEx->mUsingFieldData); + + if (!foundLists.IsEmpty()) { - auto initialFieldDef = usingEntry->mLookup[0].mFieldDef; - if ((initialFieldDef->mIsStatic == target.IsStatic()) && - (mModule->CheckProtection(protectionCheckFlags, curCheckType, initialFieldDef->mDeclaringType->mProject, initialFieldDef->mUsingProtection, startCheckType))) - { - BfTypeInstance* curTypeInst = curCheckType; - BfTypedValue curResult = target; - for (int i = 0; i < usingEntry->mLookup.mSize; i++) - { - auto& fieldRef = usingEntry->mLookup[i]; - if (mPropDef != NULL) - { - SetAndRestoreValue prevResult(mResult, BfTypedValue()); - mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend); - curResult = GetResult(); - if (!curResult) - return curResult; - } + auto foundList = foundLists[0]; - auto useFlags = flags; - if (i < usingEntry->mLookup.mSize - 1) - useFlags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsAnonymous); - curResult = LoadField(targetSrc, curResult, fieldRef.mTypeInstance, fieldRef.mFieldDef, useFlags); - if ((!curResult) && (mPropDef == NULL)) + if (foundLists.mSize > 1) + { + BfError* error = mModule->Fail("Ambiguous 'using' field reference", targetSrc); + if (error != NULL) + { + for (auto checkList : foundLists) + { + String errorStr = "'"; + for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++) + { + if (entryIdx == 0) + errorStr += (*checkList)[entryIdx].GetFullName(mModule); + else + { + errorStr += "."; + errorStr += (*checkList)[entryIdx].GetName(mModule); + } + } + errorStr += "' is a candidate"; + mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule)); + } + } + } + + BfTypedValue curResult = target; + for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++) + { + if ((entryIdx == 0) && (foundList->back().IsStatic())) + entryIdx = (int)foundList->mSize - 1; + + auto& entry = (*foundList)[entryIdx]; + if (mPropDef != NULL) + { + SetAndRestoreValue prevResult(mResult, BfTypedValue()); + mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend); + curResult = GetResult(); + if (!curResult) return curResult; } - return curResult; + + auto useFlags = flags; + if (entryIdx < foundList->mSize - 1) + useFlags = (BfLookupFieldFlags)(flags | BfLookupFieldFlag_IsAnonymous); + + if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field) + { + curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags); + } + else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property) + { + curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false); + } + else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local) + { + auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx]; + curResult = LoadLocal(localDef); + } + if ((!curResult) && (mPropDef == NULL)) + return curResult; + + if (entryIdx == foundList->mSize - 1) + { + auto autoComplete = GetAutoComplete(); + if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc))) + autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule)); + + if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc))) + autoComplete->FixitAddFullyQualify(targetSrc, findName, *foundList); + } } + + return curResult; } } @@ -5648,15 +5877,15 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar // Check statics in outer type return LookupField(targetSrc, BfTypedValue(outerTypeDef), fieldName, BfLookupFieldFlag_CheckingOuter); } - + return BfTypedValue(); } void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags) -{ +{ static int idx = 0; idx++; - int curIdx = idx; + int curIdx = idx; if (resolvedArgs.mArguments == NULL) return; @@ -5681,7 +5910,7 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr SizedArray deferredArgs; int argIdx = 0; - + while (true) { //printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize); @@ -5723,10 +5952,10 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr BfResolvedArg resolvedArg; resolvedArg.mTypedValue = typedValueExpr->mTypedValue; resolvedArg.mExpression = typedValueExpr->mRefNode; - resolvedArgs.mResolvedArgs.push_back(resolvedArg); + resolvedArgs.mResolvedArgs.push_back(resolvedArg); continue; } - + BfResolvedArg resolvedArg; if (isDeferredArg) resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_StringInterpolateArg); @@ -5739,6 +5968,12 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr bool handled = false; bool evaluated = false; + if (auto namedExpression = BfNodeDynCastExact(argExpr)) + { + resolvedArg.mNameNode = namedExpression->mNameNode; + argExpr = namedExpression->mExpression; + } + if (auto interpolateExpr = BfNodeDynCastExact(argExpr)) { if ((interpolateExpr->mAllocNode == NULL) || ((flags & BfResolveArgsFlag_InsideStringInterpolationAlloc) != 0)) @@ -5768,15 +6003,15 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr { BfDeferEvalChecker deferEvalChecker; deferEvalChecker.mDeferDelegateBind = false; - argExpr->Accept(&deferEvalChecker); + deferEvalChecker.Check(argExpr); deferParamEval = deferEvalChecker.mNeedsDeferEval; } } - + if (deferParamEval) { resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredEval); - handled = true; + handled = true; } else if (auto delegateBindExpression = BfNodeDynCast(argExpr)) { @@ -5814,21 +6049,21 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UntypedDefault); handled = true; } - } + } else if (auto varDeclExpr = BfNodeDynCast(argExpr)) { resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_VariableDeclaration); handled = true; - } + } else if (auto unaryExpr = BfNodeDynCast(argExpr)) { if (unaryExpr->mOp == BfUnaryOp_Params) { - resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr); + resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr); } } else if (auto uninitExpr = BfNodeDynCast(argExpr)) - { + { resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UninitializedExpr); handled = true; } @@ -5850,9 +6085,9 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr bool deferParamValues = (flags & BfResolveArgsFlag_DeferParamValues) != 0; SetAndRestoreValue ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, mModule->mBfIRBuilder->mIgnoreWrites || deferParamValues); auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock(); - if (deferParamValues) + if (deferParamValues) resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_DeferredValue); - + if (!evaluated) { exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowParamsExpr); @@ -5862,13 +6097,13 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr exprEvaluator.Evaluate(argExpr, false, false, true); } - + if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL)) { auto localVar = exprEvaluator.mResultLocalVar; int fieldIdx = mResultLocalVarField - 1; - - auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar); + + auto methodState = mModule->mCurMethodState->GetMethodStateForLocal(localVar); if (localVar->mCompositeCount >= 0) { if ((resolvedArg.mArgFlags & BfArgFlag_ParamsExpr) == 0) @@ -5891,19 +6126,19 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr } continue; - } + } } - exprEvaluator.CheckResultForReading(exprEvaluator.mResult); - auto argValue = exprEvaluator.mResult; + exprEvaluator.CheckResultForReading(exprEvaluator.mResult); + auto argValue = exprEvaluator.mResult; if (argValue) { mModule->mBfIRBuilder->PopulateType(argValue.mType); resolvedArg.mResolvedType = argValue.mType; if (resolvedArg.mResolvedType->IsRef()) argValue.mKind = BfTypedValueKind_Value; - else if ((!resolvedArg.mResolvedType->IsStruct()) && (!resolvedArg.mResolvedType->IsSizedArray()) && (!resolvedArg.mResolvedType->IsValuelessType())) - argValue = mModule->LoadValue(argValue, NULL, exprEvaluator.mIsVolatileReference); + if (exprEvaluator.mIsVolatileReference) + resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Volatile); } resolvedArg.mUncastedTypedValue = argValue; resolvedArg.mTypedValue = argValue; @@ -5922,11 +6157,11 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc) { BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes(); - if (customAttributes != NULL) - mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc); + if (customAttributes != NULL) + mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc); } -BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags) +BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags, BfType* origTargetType) { // static int sCallIdx = 0; // if (!mModule->mCompiler->mIsResolveOnly) @@ -5944,7 +6179,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if ((funcCallInst) && (importCallKind != BfImportCallKind_None)) { if ((funcCallInst.IsFake()) && (!mModule->mBfIRBuilder->mIgnoreWrites)) - { + { mModule->mFuncReferences.TryGetValue(methodInstance, &funcCallInst); } @@ -5967,7 +6202,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* auto condVal = mModule->mBfIRBuilder->CreateIsNull(checkVal); mModule->mBfIRBuilder->CreateCondBr(condVal, nullBlock, doneBlock); - + mModule->mBfIRBuilder->AddBlock(nullBlock); mModule->mBfIRBuilder->SetInsertPoint(nullBlock); auto loadSharedLibsFunc = mModule->GetBuiltInFunc(BfBuiltInFuncType_LoadSharedLibraries); @@ -6034,7 +6269,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* { if (methodInstance->GetOwner()->IsInterface()) { - // We're attempting to directly invoke a non-virtual interface method, if we're return an interface then + // We're attempting to directly invoke a non-virtual interface method, if we're return an interface then // it is a concrete interface if (returnType->IsInterface()) returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance()); @@ -6069,7 +6304,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* sretVal = *mReceivingValue; sret = &sretVal; - auto ptrType = mModule->CreatePointerType(returnType); + auto ptrType = mModule->CreatePointerType(returnType); if (returnType != sret->mType) { sret->mValue = mModule->mBfIRBuilder->CreateBitCast(sret->mValue, mModule->mBfIRBuilder->MapType(ptrType)); @@ -6080,7 +6315,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } if (sret == NULL) - { + { sretVal = BfTypedValue(mModule->CreateAlloca(returnType), returnType, BfTypedValueKind_RestrictedTempAddr); sret = &sretVal; } @@ -6094,7 +6329,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* { if ((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) { - // We need to perform call such as Compiler.Mixin and String.ConstF + // We need to perform call such as Compiler.Mixin and String.ConstF } else return _GetDefaultReturnValue(); @@ -6107,19 +6342,28 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* bool wantQuickEval = true; if (IsComptime()) - { + { auto autoComplete = mModule->mCompiler->mResolvePassData->mAutoComplete; - wantQuickEval = + wantQuickEval = ((autoComplete->mResolveType != BfResolveType_Autocomplete) && (autoComplete->mResolveType != BfResolveType_Autocomplete_HighPri) && (autoComplete->mResolveType != BfResolveType_GetResultString)); + + for (auto& entry : mModule->mCompiler->mResolvePassData->mEmitEmbedEntries) + { + if (entry.mValue.mCursorIdx >= 0) + { + // Needed for Go To Definition in Compiler.Mixin + wantQuickEval = false; + } + } } if (wantQuickEval) { // In an autocomplete pass we may have stale method references that need to be resolved - // in the full classify pass, and in the full classify pass while just refreshing internals, we - // may have NULL funcs temporarily. We simply skip generating the method call here. + // in the full classify pass, and in the full classify pass while just refreshing internals, we + // may have NULL funcs temporarily. We simply skip generating the method call here. if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) { if (methodInstance->mReturnType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)) @@ -6153,7 +6397,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* bool doConstReturn = false; if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) - { + { if (mFunctionBindResult != NULL) { forceBind = true; @@ -6161,7 +6405,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0) { mModule->Fail("Const evaluation not allowed with cascade operator", targetSrc); - } + } else if (((methodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && (!mModule->mIsComptimeModule)) { // This either generated an error already or this is just the non-const type check pass for a comptime-only method @@ -6185,12 +6429,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* CeEvalFlags evalFlags = CeEvalFlags_None; if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0) evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild); - + if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL)) { auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState; if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0) - { + { ceDbgState->mHadSideEffects = true; //SetAndRestoreValue prevDebugger(mModule->mCompiler->mCeMachine->mDebugger, NULL); @@ -6202,12 +6446,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } else { - ceDbgState->mBlockedSideEffects = true; + ceDbgState->mBlockedSideEffects = true; } - } + } else - { - auto constRet = mModule->mCompiler->mCeMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType); + { + CeCallSource ceCallSource(targetSrc); + ceCallSource.mOrigCalleeType = origTargetType; + auto constRet = mModule->mCompiler->mCeMachine->Call(ceCallSource, mModule, methodInstance, irArgs, evalFlags, mExpectingType); if (constRet) { auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue); @@ -6225,10 +6471,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } doConstReturn = true; } - } + } } else if (mModule->mIsComptimeModule) - { + { if (methodInstance->mIsUnspecialized) { doConstReturn = true; @@ -6257,7 +6503,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* return mModule->GetDefaultTypedValue(mExpectingType, true, BfDefaultValueKind_Undef); } } - + if (methodInstance->mReturnType->IsValuelessType()) return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType); return mModule->GetDefaultTypedValue(returnType, true, BfDefaultValueKind_Undef); @@ -6278,11 +6524,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } if (methodInstance->mVirtualTableIdx != -1) - { + { if ((!bypassVirtual) && (mDeferCallRef == NULL)) { if ((methodDef->mIsOverride) && (mModule->mCurMethodInstance->mIsReified)) - { + { // Ensure that declaring method gets referenced auto typeInstance = methodInstance->GetOwner(); auto& vEntry = typeInstance->mVirtualMethodTable[methodInstance->mVirtualTableIdx]; @@ -6370,7 +6616,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* //vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + methodInstance->GetOwner()->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots); vDataIdx = mModule->mBfIRBuilder->GetConfigConst(BfIRConfigConst_VirtualMethodOfs, BfTypeCode_Int32); - vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, + vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, (methodInstance->mVirtualTableIdx - typeInst->GetImplBaseVTableSize()) + typeInst->GetOrigImplBaseVTableSize())); } } @@ -6397,19 +6643,19 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else // non-virtual { if (methodInstance->GetOwner()->IsInterface()) - { + { // We're attempting to directly invoke a non-virtual interface method, this will happen during the unspecialized pass // OR if we had an error and didn't find an implementing member in the actual target if ((!mModule->mCurMethodInstance->mIsUnspecialized) && (!mModule->mCurTypeInstance->IsInterface())) mModule->AssertErrorState(); - + if (returnType->IsInterface()) returnType = mModule->CreateConcreteInterfaceType(returnType->ToTypeInstance()); return _GetDefaultReturnValue(); - } + } } - + if (mFunctionBindResult != NULL) { mFunctionBindResult->mFunc = funcCallInst; @@ -6443,8 +6689,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (mDeferCallRef != NULL) { - mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, func), irArgs, mDeferScopeAlloc, mDeferCallRef); - //return _GetDefaultReturnValue(); + mModule->AddDeferredCall(BfModuleMethodInstance(methodInstance, func), irArgs, mDeferScopeAlloc, mDeferCallRef, bypassVirtual); return mModule->GetFakeTypedValue(returnType); } @@ -6455,16 +6700,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* // This can happen either from an error, or from the resolver while doing Internals_Changed processing mModule->AssertErrorState(); } - //return mModule->GetDefaultTypedValue(returnType,/*, true*/false, returnType->IsComposite()); return _GetDefaultReturnValue(); } - + bool hasResult = !methodInstance->mReturnType->IsValuelessType(); BfIRValue firstArg; if (irArgs.size() != 0) firstArg = irArgs[0]; - + auto methodInstOwner = methodInstance->GetOwner(); auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstance); if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this")) @@ -6479,17 +6723,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* // Emit a NOP so we always have a "step over" point mModule->EmitEnsureInstructionAt(); } - + if (returnType->IsComposite()) mModule->mBfIRBuilder->PopulateType(returnType); - + methodInstance->mMethodInstanceGroup->mHasEmittedReference = true; BfIRValue callInst; int callIRArgCount = (int)irArgs.size(); if (sret != NULL) { - SizedArray sretIRArgs; + SizedArray sretIRArgs; int sretIdx = GetStructRetIdx(methodInstance); int inIdx = 0; for (int outIdx = 0; outIdx < irArgs.size() + 1; outIdx++) @@ -6507,24 +6751,24 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else { callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs); - + if ((hasResult) && (!methodDef->mName.IsEmpty()) && (!methodInstance->mIsIntrinsic)) mModule->mBfIRBuilder->SetName(callInst, methodDef->mName); } if ((expectCallingConvention != BfIRCallingConv_CDecl) && (!methodInstance->mIsIntrinsic)) mModule->mBfIRBuilder->SetCallCallingConv(callInst, expectCallingConvention); - + if ((methodDef->mIsNoReturn) && (!methodInstance->mIsIntrinsic)) mModule->mBfIRBuilder->Call_AddAttribute(callInst, -1, BfIRAttribute_NoReturn); - bool hadAttrs = false; + bool hadAttrs = false; int paramIdx = 0; bool doingThis = methodInstance->HasThis(); - int argIdx = 0; + int argIdx = 0; if (methodDef->mHasExplicitThis) paramIdx++; - + int paramCount = methodInstance->GetParamCount(); for ( ; argIdx < callIRArgCount ; ) @@ -6546,7 +6790,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting(paramIdx))) { BfTypeCode loweredTypeCode = BfTypeCode_None; - BfTypeCode loweredTypeCode2 = BfTypeCode_None; + BfTypeCode loweredTypeCode2 = BfTypeCode_None; if (paramType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2)) { argIdx++; @@ -6614,7 +6858,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* BfType* paramType = NULL; if (doingThis) - { + { int thisIdx = methodInstance->GetThisIdx(); paramType = methodInstance->GetThisType(); if (paramType->IsValuelessType()) @@ -6655,7 +6899,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* paramIdx++; continue; } - + if ((methodInstance->GetParamIsSplat(paramIdx)) && (!IsComptime())) { BfTypeUtils::SplatIterate(_HandleParamType, paramType); @@ -6672,15 +6916,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* paramIdx++; //argIdx++; } - + if ((callFlags & BfCreateCallFlags_TailCall) != 0) - mModule->mBfIRBuilder->SetTailCall(callInst); + mModule->mBfIRBuilder->SetTailCall(callInst); if (methodDef->mIsNoReturn) { mModule->mBfIRBuilder->CreateUnreachable(); // For debuggability when looking back at stack trace - //mModule->ExtendLocalLifetimes(0); + //mModule->ExtendLocalLifetimes(0); if (mModule->IsTargetingBeefBackend()) { @@ -6708,12 +6952,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else if (hasResult) { BfTypeCode loweredRetType = BfTypeCode_None; - BfTypeCode loweredRetType2 = BfTypeCode_None; + BfTypeCode loweredRetType2 = BfTypeCode_None; if ((!IsComptime()) && (methodInstance->GetLoweredReturnType(&loweredRetType, &loweredRetType2)) && (loweredRetType != BfTypeCode_None)) { auto retVal = mModule->CreateAlloca(methodInstance->mReturnType); - BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2); - loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType); + BfIRType loweredIRType = mModule->GetIRLoweredType(loweredRetType, loweredRetType2); + loweredIRType = mModule->mBfIRBuilder->GetPointerTo(loweredIRType); auto castedRetVal = mModule->mBfIRBuilder->CreateBitCast(retVal, loweredIRType); mModule->mBfIRBuilder->CreateStore(callInst, castedRetVal); result = BfTypedValue(retVal, methodInstance->mReturnType, BfTypedValueKind_RestrictedTempAddr); @@ -6736,11 +6980,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* return result; } - - BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target) -{ - auto moduleMethodInstance = GetSelectedMethod(*methodMatcher); +{ + auto moduleMethodInstance = GetSelectedMethod(*methodMatcher); if (moduleMethodInstance.mMethodInstance == NULL) return BfTypedValue(); if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner())) @@ -6748,10 +6990,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTyped auto castedTarget = mModule->Cast(methodMatcher->mTargetSrc, target, moduleMethodInstance.mMethodInstance->GetOwner()); BF_ASSERT(castedTarget); target = castedTarget; - } + } PerformCallChecks(moduleMethodInstance.mMethodInstance, methodMatcher->mTargetSrc); - + BfCreateCallFlags callFlags = BfCreateCallFlags_None; if (methodMatcher->mAllowImplicitRef) callFlags = (BfCreateCallFlags)(callFlags | BfCreateCallFlags_AllowImplicitRef); @@ -6764,16 +7006,16 @@ void BfExprEvaluator::MakeBaseConcrete(BfTypedValue& typedValue) { auto baseType = mModule->mCurTypeInstance->mBaseType; if (baseType == NULL) - baseType = mModule->mContext->mBfObjectType; + baseType = mModule->mContext->mBfObjectType; mModule->PopulateType(baseType, BfPopulateType_Data); typedValue = mModule->Cast(NULL, typedValue, baseType, BfCastFlags_Explicit); } } void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& irArgs) -{ +{ if (value.IsSplat()) - { + { int componentIdx = 0; BfTypeUtils::SplatIterate([&](BfType* checkType) { irArgs.push_back(mModule->ExtractSplatValue(value, componentIdx++, checkType)); }, value.mType); @@ -6785,7 +7027,7 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i { BfType* checkType = curValue.mType; if (checkType->IsStruct()) - { + { auto checkTypeInstance = checkType->ToTypeInstance(); if ((checkTypeInstance->mBaseType != NULL) && (!checkTypeInstance->mBaseType->IsValuelessType())) { @@ -6801,13 +7043,13 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i { auto unionInnerType = checkTypeInstance->GetUnionInnerType(); if (!unionInnerType->IsValuelessType()) - { + { BfTypedValue unionValue = mModule->ExtractValue(curValue, NULL, 1); checkTypeLambda(unionValue); } if (checkTypeInstance->IsEnum()) - { + { BfTypedValue dscrValue = mModule->ExtractValue(curValue, NULL, 2); checkTypeLambda(dscrValue); } @@ -6818,7 +7060,7 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i { auto fieldInstance = (BfFieldInstance*)&checkTypeInstance->mFieldInstances[fieldIdx]; if (fieldInstance->mDataIdx >= 0) - { + { BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx); checkTypeLambda(fieldValue); } @@ -6836,10 +7078,10 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i if (methodRefType->WantsDataPassedAsSplat(dataIdx)) { BF_ASSERT(dataIdx == 0); - + auto ptrType = mModule->CreatePointerType(checkType); auto elemPtr = mModule->mBfIRBuilder->CreateBitCast(curValue.mValue, mModule->mBfIRBuilder->MapType(ptrType)); - checkTypeLambda(BfTypedValue(elemPtr, checkType, BfTypedValueKind_Addr)); + checkTypeLambda(BfTypedValue(elemPtr, checkType, BfTypedValueKind_Addr)); //BfTypedValue fieldValue = mModule->ExtractValue(curValue, fieldInstance, fieldInstance->mDataIdx); //checkTypeLambda(fieldValue); @@ -6868,14 +7110,14 @@ void BfExprEvaluator::SplatArgs(BfTypedValue value, SizedArrayImpl& i void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& irArgs, bool disableSplat, bool disableLowering, bool isIntrinsic, bool createCompositeCopy) { MakeBaseConcrete(argVal); - + if (IsVar(argVal.mType)) { argVal = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType); } if (argVal.mType->IsValuelessType()) - return; + return; bool wantSplat = false; if ((argVal.mType->IsSplattable()) && (!disableSplat) && (!IsComptime())) { @@ -6895,9 +7137,9 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir SplatArgs(argVal, irArgs); } else - { + { if (argVal.mType->IsComposite()) - { + { if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) { // Const eval entry - we want any incoming consts as they are @@ -6905,10 +7147,10 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir else if (isIntrinsic) { // We can handle composites either by value or not - } + } else argVal = mModule->MakeAddressable(argVal); - + if ((!IsComptime()) && (!disableLowering) && (!isIntrinsic)) { BfTypeCode loweredTypeCode = BfTypeCode_None; @@ -6921,7 +7163,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir if (argVal.mType->mSize < loweredSize) { auto allocaVal = mModule->CreateAlloca(mModule->GetPrimitiveType(BfTypeCode_UInt8), true, NULL, mModule->GetConstValue(loweredSize)); - mModule->mBfIRBuilder->SetAllocaAlignment(allocaVal, + mModule->mBfIRBuilder->SetAllocaAlignment(allocaVal, BF_MAX(argVal.mType->mAlign, BF_MAX(mModule->mBfIRBuilder->GetSize(loweredTypeCode), mModule->mBfIRBuilder->GetSize(loweredTypeCode2)))); auto castedPtr = mModule->mBfIRBuilder->CreateBitCast(allocaVal, mModule->mBfIRBuilder->MapType(mModule->CreatePointerType(argVal.mType))); @@ -6929,7 +7171,7 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir mModule->mBfIRBuilder->CreateAlignedStore(argIRVal, castedPtr, argVal.mType->mAlign); argPtrVal = castedPtr; } - + auto primType = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode); auto ptrType = mModule->mBfIRBuilder->GetPointerTo(primType); BfIRValue primPtrVal = mModule->mBfIRBuilder->CreateBitCast(argPtrVal, ptrType); @@ -6941,11 +7183,11 @@ void BfExprEvaluator::PushArg(BfTypedValue argVal, SizedArrayImpl& ir auto primType2 = mModule->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2); auto ptrType2 = mModule->mBfIRBuilder->GetPointerTo(primType2); BfIRValue primPtrVal2; - if (mModule->mBfIRBuilder->GetSize(loweredTypeCode) < mModule->mBfIRBuilder->GetSize(loweredTypeCode2)) - primPtrVal2 = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateBitCast(primPtrVal, ptrType2), 1); - else + if (mModule->mBfIRBuilder->GetSize(loweredTypeCode) < mModule->mBfIRBuilder->GetSize(loweredTypeCode2)) + primPtrVal2 = mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateBitCast(primPtrVal, ptrType2), 1); + else primPtrVal2 = mModule->mBfIRBuilder->CreateBitCast(mModule->mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), ptrType2); - + auto primVal2 = mModule->mBfIRBuilder->CreateLoad(primPtrVal2); irArgs.Add(primVal2); } @@ -6981,16 +7223,16 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth return; } - if (methodDef->mIsMutating) - { + if (methodDef->mIsMutating) + { bool checkMut = false; if (argVal.mType->IsGenericParam()) { // For capturing mutability - if (mResultLocalVar != NULL) - mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; + if (mResultLocalVar != NULL) + mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } - + if (((argVal.mType->IsComposite()) || (argVal.mType->IsTypedPrimitive()))) { if (argVal.IsCopyOnMutate()) @@ -7014,17 +7256,16 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth { if (mResultLocalVar != NULL) { - // When we are capturing, we need to note that we require capturing by reference here + // When we are capturing, we need to note that we require capturing by reference here mResultLocalVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } } } - } if (argVal.mType->IsValuelessType()) return; - + auto owner = methodInstance->GetOwner(); bool allowThisSplatting; @@ -7039,7 +7280,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth irArgs.push_back(argVal.mValue); return; } - + auto thisType = methodInstance->GetThisType(); PushArg(argVal, irArgs, !methodInstance->AllowsSplatting(-1), thisType->IsPointer()); } @@ -7047,8 +7288,8 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl& argValues) { for (int argIdx = 0; argIdx < argValues.size(); argIdx++) - { - auto& argValue = argValues[argIdx].mTypedValue; + { + auto& argValue = argValues[argIdx].mTypedValue; if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0) { if (!argValue) @@ -7057,17 +7298,17 @@ void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl& argValu if (expr != NULL) argValue = mModule->CreateValueFromExpression(expr); } - } + } } } void BfExprEvaluator::FinishDeferredEvals(BfResolvedArgs& argValues) -{ +{ for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++) { auto& argValue = argValues.mResolvedArgs[argIdx].mTypedValue; if ((argValues.mResolvedArgs[argIdx].mArgFlags & (BfArgFlag_VariableDeclaration)) != 0) - { + { auto variableDeclaration = BfNodeDynCast((*argValues.mArguments)[argIdx]); if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL)) { @@ -7119,6 +7360,31 @@ void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance) //TODO: delete argumentsZ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateCallFlags callFlags, SizedArrayImpl& argValues, BfTypedValue* argCascade) { + SetAndRestoreValue prevEvalExprFlag(mBfEvalExprFlags); + + if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef))) + { + mModule->mAttributeState->mUsed = true; + mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); + } + else if ((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) + { + mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); + } + else if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && (!mModule->mIsComptimeModule)) + { + if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) + mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); + } + + if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && + ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && + ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) && + (!mModule->mIsComptimeModule)) + { + mModule->Fail(StrFormat("Method '%s' can only be invoked at comptime. Consider adding [Comptime] to the current method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc); + } + bool bypassVirtual = (callFlags & BfCreateCallFlags_BypassVirtual) != 0; bool skipThis = (callFlags & BfCreateCallFlags_SkipThis) != 0;; @@ -7131,16 +7397,16 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu NOP; } - // Temporarily disable so we don't capture calls in params - SetAndRestoreValue prevBindResult(mFunctionBindResult, NULL); + // Temporarily disable so we don't capture calls in params + SetAndRestoreValue prevBindResult(mFunctionBindResult, NULL); SetAndRestoreValue prevAllowVariableDeclarations; if (mModule->mCurMethodState != NULL) - prevAllowVariableDeclarations.Init(mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations, false); + prevAllowVariableDeclarations.Init(mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations, false); - BfMethodInstance* methodInstance = moduleMethodInstance.mMethodInstance; + BfMethodInstance* methodInstance = moduleMethodInstance.mMethodInstance; SizedArray irArgs; - + if ((methodDef->mIsAbstract) && (bypassVirtual)) { mModule->Fail(StrFormat("Abstract base method '%s' cannot be invoked", mModule->MethodToString(methodInstance).c_str()), targetSrc); @@ -7149,7 +7415,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual); BfType* returnType = methodInstance->mReturnType; /*if (returnType->IsSelf()) - { + { returnType = methodInstance->GetOwner(); BF_ASSERT(returnType->IsInterface()); }*/ @@ -7168,7 +7434,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu moduleMethodInstance.mFunc = mModule->mBfIRBuilder->CreateIntToPtr(target.mValue, funcPtrType); } else if (!methodDef->mIsStatic) - { + { if ((!target) && (prevBindResult.mPrevVal != NULL)) { auto bindResult = prevBindResult.mPrevVal; @@ -7179,7 +7445,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (delegateInfo != NULL) { if (delegateInfo->mHasExplicitThis) - { + { target = mModule->GetDefaultTypedValue(delegateInfo->mParams[0], false, BfDefaultValueKind_Addr); bypassVirtual = true; } @@ -7188,7 +7454,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu { BfMethodInstance* invokeMethodInstance = mModule->GetRawMethodInstanceAtIdx(bindResult->mBindType->ToTypeInstance(), 0, "Invoke"); if (!invokeMethodInstance->mMethodDef->mIsStatic) - { + { target = mModule->GetDefaultTypedValue(invokeMethodInstance->GetThisType(), false, BfDefaultValueKind_Addr); } } @@ -7196,7 +7462,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } if (!target) - { + { FinishDeferredEvals(argValues); auto error = mModule->Fail(StrFormat("An instance reference is required to %s the non-static method '%s'", (prevBindResult.mPrevVal != NULL) ? "bind" : "invoke", @@ -7241,19 +7507,19 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else PushThis(targetSrc, target, moduleMethodInstance.mMethodInstance, irArgs, skipMutCheck); } - } + } else if (methodDef->mMethodType == BfMethodType_Extension) { // Handled in args } - else - { + else + { mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner); if (target) { FinishDeferredEvals(argValues); - mModule->Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead", + mModule->Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead", mModule->MethodToString(methodInstance).c_str()), targetSrc); return mModule->GetDefaultTypedValue(returnType); } @@ -7267,16 +7533,91 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu return mModule->GetDefaultTypedValue(returnType); } + bool hasNamedArgs = false; + for (auto& arg : argValues) + if (arg.mNameNode != NULL) + hasNamedArgs = true; + if (hasNamedArgs) + { + methodDef->BuildParamNameMap(); + + BfIdentifierNode* outOfPlaceName = NULL; + int curParamIdx = 0; + + SizedArrayImpl origArgValues = argValues; + argValues.Clear(); + + for (int argIdx = 0; argIdx < origArgValues.mSize; argIdx++) + { + int paramIdx = curParamIdx; + + auto& argValue = origArgValues[argIdx]; + if (argValue.mNameNode != NULL) + { + int namedParamIdx = -1; + if (methodDef->mParamNameMap->TryGetValue(argValue.mNameNode->ToStringView(), &namedParamIdx)) + { + paramIdx = namedParamIdx; + } + else + { + if (mModule->PreFail()) + { + mModule->Fail(StrFormat("The best overload for '%s' does not have a parameter named '%s'", methodInstance->mMethodDef->mName.c_str(), + argValue.mNameNode->ToString().c_str()), argValue.mNameNode); + } + } + + if (paramIdx != curParamIdx) + outOfPlaceName = argValue.mNameNode; + } + else if (outOfPlaceName != NULL) + { + if (mModule->PreFail()) + mModule->Fail(StrFormat("Named argument '%s' is used out-of-position but is followed by an unnamed argument", outOfPlaceName->ToString().c_str()), outOfPlaceName); + outOfPlaceName = NULL; + } + + if ((paramIdx < methodInstance->GetParamCount()) && (paramIdx != argIdx)) + { + if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Normal) + { + auto wantType = methodInstance->GetParamType(paramIdx); + auto resolvedValue = ResolveArgValue(argValue, wantType); + if (resolvedValue) + { + argValue.mTypedValue = resolvedValue; + argValue.mArgFlags = (BfArgFlags)(argValue.mArgFlags | BfArgFlag_Finalized); + } + } + } + + while (paramIdx >= argValues.mSize) + argValues.Add(BfResolvedArg()); + if (argValues[paramIdx].mExpression != NULL) + { + if (argValue.mNameNode != NULL) + { + if (mModule->PreFail()) + mModule->Fail(StrFormat("Named argument '%s' cannot be specified multiple times", argValue.mNameNode->ToString().c_str()), argValue.mNameNode); + } + } + argValues[paramIdx] = argValue; + + curParamIdx++; + } + } + int argIdx = 0; int paramIdx = 0; - + BfIRValue expandedParamAlloca; BfTypedValue expandedParamsArray; BfType* expandedParamsElementType = NULL; int extendedParamIdx = 0; AddCallDependencies(methodInstance); - + bool wasCapturingMatchInfo = false; auto autoComplete = GetAutoComplete(); if (autoComplete != NULL) @@ -7299,7 +7640,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu while (true) { int argExprIdx = argIdx; - if (methodDef->mMethodType == BfMethodType_Extension) + if (methodDef->mMethodType == BfMethodType_Extension) argExprIdx--; bool isThis = (paramIdx == -1) || ((methodDef->mHasExplicitThis) && (paramIdx == 0)); @@ -7312,8 +7653,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (argExprIdx >= (int)argValues.size()) break; - BfTypedValue argValue = ResolveArgValue(argValues[argExprIdx], NULL); - if (argValue) + BfTypedValue argValue = ResolveArgValue(argValues[argExprIdx], NULL); + if (argValue) { auto typeInst = argValue.mType->ToTypeInstance(); @@ -7327,13 +7668,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu argValue = mModule->Cast(argValues[argExprIdx].mExpression, argValue, charPtrType); } PushArg(argValue, irArgs, true, false); - } + } argIdx++; continue; - } + } if (argExprIdx < (int)argValues.size()) - { + { if (mModule->PreFail()) { BfAstNode* errorRef = argValues[argExprIdx].mExpression; @@ -7363,7 +7704,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode()); } failed = true; - break; + break; } break; } @@ -7371,12 +7712,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu // Only create actual params if we're not just trying to bind the function if ((prevBindResult.mPrevVal != NULL) && (!prevBindResult.mPrevVal->mWantsArgs)) break; - + BfType* wantType = NULL; bool wantsSplat = false; - if (expandedParamsElementType != NULL) + if (expandedParamsElementType != NULL) { - wantType = expandedParamsElementType; + wantType = expandedParamsElementType; } else { @@ -7385,15 +7726,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu { auto paramType = methodInstance->GetParamType(paramIdx); if (mModule->mCurMethodInstance->IsMixin()) - { - // Don't bother, also- can fail on captures + { + // Don't bother, also- can fail on captures } else { // static int captureIdx = 0; // captureIdx++; // int curCaptureIdx = captureIdx; -// +// // if (curCaptureIdx == 0x91) // { // NOP; @@ -7401,7 +7742,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu auto lookupVal = DoImplicitArgCapture(targetSrc, methodInstance, paramIdx, failed, BfImplicitParamKind_General, origTarget); if (lookupVal) - { + { if (wantsSplat) { SplatArgs(lookupVal, irArgs); @@ -7424,7 +7765,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu // Resolve `Self` types if (wantType->IsUnspecializedTypeVariation()) { - wantType = mModule->ResolveSelfType(wantType, methodInstance->GetOwner()); + wantType = mModule->ResolveSelfType(wantType, methodInstance->GetOwner()); } } @@ -7509,17 +7850,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu mModule->mBfIRBuilder->PopulateType(wantType); auto genericTypeInst = wantType->ToGenericTypeInstance(); expandedParamsElementType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0]; - + expandedParamsArray = BfTypedValue(mModule->CreateAlloca(wantType), wantType, true); expandedParamAlloca = mModule->CreateAlloca(genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[0], true, NULL, mModule->GetConstValue(numElements)); mModule->mBfIRBuilder->CreateAlignedStore(expandedParamAlloca, mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1), mModule->mSystem->mPtrSize); mModule->mBfIRBuilder->CreateAlignedStore(mModule->GetConstValue(numElements), mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 2), mModule->mSystem->mPtrSize); - + PushArg(expandedParamsArray, irArgs, !wantsSplat); continue; } else if (wantType->IsSizedArray()) - { + { mModule->PopulateType(wantType); mModule->mBfIRBuilder->PopulateType(wantType); BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)wantType; @@ -7528,7 +7869,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (numElements != sizedArrayType->mElementCount) { BfAstNode* refNode = targetSrc; - if (argExprIdx < (int)argValues.size()) + if (argExprIdx < (int)argValues.size()) refNode = argValues[argExprIdx].mExpression; mModule->Fail(StrFormat("Incorrect number of arguments to match params type '%s'", mModule->TypeToString(wantType).c_str()), refNode); } @@ -7567,15 +7908,18 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu mModule->Warn(BfWarning_BF4205_StringInterpolationParam, "Expanded string interpolation argument not used as 'params'. If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef); } - if ((arg == NULL) && (argValues[argExprIdx].mExpression != NULL)) +// if ((arg == NULL) && (argValues[argExprIdx].mExpression != NULL)) +// hadMissingArg = true; + + if ((arg == NULL) && (!argValues[argExprIdx].mTypedValue)) hadMissingArg = true; } else hadMissingArg = true; } - + BfTypedValue argValue; - + if (hadMissingArg) { if (expandedParamsArray) @@ -7591,10 +7935,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu refNode = checkExpr; } - BfAstNode* prevNode = NULL; + BfAstNode* prevNode = NULL; if (targetSrc == NULL) { - // We must be in BfModule::EmitCtorBody + // We must be in BfModule::EmitCtorBody } else if (auto tupleExpr = BfNodeDynCastExact(targetSrc)) { @@ -7604,11 +7948,11 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu prevNode = tupleExpr->mOpenParen; if (tupleExpr->mCloseParen != NULL) refNode = tupleExpr->mCloseParen; - } + } else if (mModule->mParentNodeEntry != NULL) { if (auto objectCreateExpr = BfNodeDynCast(mModule->mParentNodeEntry->mNode)) - { + { if (objectCreateExpr->mCommas.size() > 0) prevNode = objectCreateExpr->mCommas.back(); else @@ -7632,12 +7976,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu refNode = invokeExpr->mCloseParen; } } - + if ((autoComplete != NULL) && (prevNode != NULL)) - autoComplete->CheckEmptyStart(prevNode, wantType); + autoComplete->CheckEmptyStart(prevNode, wantType); BfError* error = NULL; - + if (mModule->mParentNodeEntry != NULL) { bool showCtorError = false; @@ -7650,7 +7994,6 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (auto typerDecl = BfNodeDynCast(mModule->mParentNodeEntry->mNode)) showCtorError = true; - if (showCtorError) { @@ -7659,23 +8002,29 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu error = mModule->Fail(StrFormat("No parameterless constructor is available for base class. Consider calling base constructor '%s'.", mModule->MethodToString(methodInstance).c_str()), refNode); } - + auto srcNode = mModule->mCurMethodInstance->mMethodDef->GetRefNode(); if ((autoComplete != NULL) && (autoComplete->CheckFixit(srcNode))) autoComplete->FixitAddConstructor(mModule->mCurTypeInstance); - } + } } if (mModule->PreFail()) { if (error == NULL) - error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode); + { + if (hasNamedArgs) + error = mModule->Fail(StrFormat("There is no argument given that corresponds to the required formal parameter '%s' of '%s'.", + methodInstance->GetParamName(paramIdx).c_str(), mModule->MethodToString(methodInstance).c_str()), refNode); + else + error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode); + } if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL)) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode()); } failed = true; break; - } + } auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx]; auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(foreignDefaultVal.mValue); @@ -7707,7 +8056,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName; argValue = BfTypedValue(mModule->GetStringObjectValue(filePath), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)); - } + } else if (strcmp(globalVar->mName, "#CallerFileName") == 0) { String filePath = ""; @@ -7767,7 +8116,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else { argValue = mModule->GetCompilerFieldValue(globalVar->mName); - } + } } } else if (foreignConst->mConstType == BfConstType_GEP32_2) @@ -7803,20 +8152,20 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } if (!argValue) - { + { argValue = mModule->GetTypedValueFromConstant(foreignConst, methodInstance->GetOwner()->mConstHolder, foreignDefaultVal.mType); if (!argValue) mModule->Fail("Default parameter value failed", targetSrc); mModule->mBfIRBuilder->PopulateType(foreignDefaultVal.mType); - } + } } else - { - if (argExprIdx == -1) + { + if (argExprIdx == -1) argValue = target; else - argValue = argValues[argExprIdx].mTypedValue; - + argValue = argValues[argExprIdx].mTypedValue; + if ((argValue.IsParams()) && (!isDirectPass)) { BfAstNode* refNode = arg; @@ -7858,9 +8207,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu paramIdx++; argIdx++; continue; - } + } else if (argExprIdx >= 0) - { + { BfParamKind paramKind = BfParamKind_Normal; BfIdentifierNode* paramNameNode = NULL; if (paramIdx < methodInstance->GetParamCount()) @@ -7873,10 +8222,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu argValue = ResolveArgValue(argValues[argExprIdx], wantType, NULL, paramKind, paramNameNode); } } - + if (!argValue) { - failed = true; + failed = true; } if ((arg != NULL) && (autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(arg))) @@ -7922,7 +8271,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } if (argValue) - { + { if ((isThis) && (argValue.mType->IsRef())) { // Convert a 'ref this' to a 'this*' @@ -7961,7 +8310,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (!argValue) { if ((argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0)) - { + { BfAstNode* errorRef = NULL; int checkIdx = argExprIdx - 1; while (checkIdx >= 0) @@ -7977,7 +8326,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu mModule->Warn(0, "If string allocation was intended then consider adding a specifier such as 'scope'.", errorRef); } - failed = true; + failed = true; } else if ((wantType->IsComposite()) && (!expandedParamsArray)) { @@ -7997,7 +8346,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else if (!wantType->IsRef()) argValue = mModule->LoadValue(argValue); } - + if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0)) { mUsedAsStatement = true; @@ -8006,7 +8355,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else argCascades.Add(argValue); } - + if (expandedParamsArray) { if (argValue) @@ -8021,13 +8370,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else if (expandedParamAlloca) { argValue = mModule->LoadValue(argValue); - auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx); + auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamAlloca, extendedParamIdx); auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, addr, argValue.mType->mAlign); } - else + else { auto firstElem = mModule->GetFieldByName(expandedParamsArray.mType->ToTypeInstance(), "mFirstElement"); - if (firstElem != NULL) + if (firstElem != NULL) { argValue = mModule->LoadValue(argValue); auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, firstElem->mDataIdx); @@ -8037,7 +8386,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu else mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign); } - } + } } extendedParamIdx++; } @@ -8057,10 +8406,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } if (argValue) - { + { if (isThis) PushThis(targetSrc, argValue, methodInstance, irArgs); - else if (wantsSplat) + else if (wantsSplat) SplatArgs(argValue, irArgs); else PushArg(argValue, irArgs, true, false, methodInstance->mIsIntrinsic, methodInstance->mCallingConvention != BfCallingConvention_Unspecified); @@ -8076,7 +8425,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu while (argIdx < argValues.size()) { mModule->AssertErrorState(); - auto argValue = argValues[argIdx].mTypedValue; + auto argValue = argValues[argIdx].mTypedValue; if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0) { if (!argValue) @@ -8088,7 +8437,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } argIdx++; } - + return mModule->GetDefaultTypedValue(returnType, false, BfDefaultValueKind_Addr); } @@ -8136,7 +8485,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu errorString = "Unable to dynamically dispatch '%s' because generic methods can only be directly dispatched"; if (methodInstance->mReturnType->IsConcreteInterfaceType()) errorString = "Unable to dynamically dispatch '%s' because the concrete return type is unknown"; - + mModule->Fail(StrFormat(errorString.c_str(), mModule->MethodToString(methodInstance).c_str()), targetSrc); } @@ -8158,7 +8507,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } else { - //BF_ASSERT(!methodInstance->GetOwner()->IsInterface()); + //BF_ASSERT(!methodInstance->GetOwner()->IsInterface()); } if (target.mType != NULL) @@ -8181,17 +8530,17 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if ((origTarget.mType != NULL) && (origTarget.mType->IsGenericParam())) physCallFlags = (BfCreateCallFlags)(physCallFlags | BfCreateCallFlags_GenericParamThis); - auto func = moduleMethodInstance.mFunc; - BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs, NULL, physCallFlags); + auto func = moduleMethodInstance.mFunc; + BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs, NULL, physCallFlags, origTarget.mType); - if ((methodInstance->mMethodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_IsExpressionBody) != 0) && + if ((methodInstance->mMethodDef->mIsNoReturn) && ((mBfEvalExprFlags & BfEvalExprFlags_IsExpressionBody) != 0) && (mExpectingType != NULL) && (callResult.mType != mExpectingType)) { callResult = mModule->GetDefaultTypedValue(mExpectingType); } // This gets triggered for non-sret (ie: comptime) composite returns so they aren't considered readonly - if ((callResult.mKind == BfTypedValueKind_Value) && (!callResult.mValue.IsConst()) && + if ((callResult.mKind == BfTypedValueKind_Value) && (!callResult.mValue.IsConst()) && (!callResult.mType->IsValuelessType()) && (callResult.mType->IsComposite()) && (!methodInstance->GetLoweredReturnType())) { bool makeAddressable = true; @@ -8226,18 +8575,18 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou SetAndRestoreValue prevBindResult(mFunctionBindResult, NULL); static int sCtorCount = 0; - sCtorCount++; - + sCtorCount++; + BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, BfMethodGenericArguments()); methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags; - + BfTypeVector typeGenericArguments; auto curTypeInst = targetType; auto curTypeDef = targetType->mTypeDef; - + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; - + auto activeTypeDef = mModule->GetActiveTypeDef(); auto visibleProjectSet = mModule->GetVisibleProjectSet(); bool isFailurePass = false; @@ -8247,9 +8596,9 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou curTypeDef->PopulateMemberSets(); BfMethodDef* nextMethodDef = NULL; - BfMemberSetEntry* entry; + BfMemberSetEntry* entry; if (curTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry)) - nextMethodDef = (BfMethodDef*)entry->mMemberDef; + nextMethodDef = (BfMethodDef*)entry->mMemberDef; while (nextMethodDef != NULL) { auto checkMethod = nextMethodDef; @@ -8274,7 +8623,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou (!curTypeInst->IsTypeMemberAccessible(checkMethod->mDeclaringType, visibleProjectSet))) continue; } - + auto checkProt = checkMethod->mProtection; if (!isFailurePass) @@ -8291,24 +8640,24 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou else { if ((checkProt == BfProtection_Protected) || (checkProt == BfProtection_ProtectedInternal)) // Treat protected constructors as private - checkProt = BfProtection_Private; + checkProt = BfProtection_Private; if (!mModule->CheckProtection(protectionCheckFlags, curTypeInst, checkMethod->mDeclaringType->mProject, checkProt, curTypeInst)) continue; } } - methodMatcher.CheckMethod(NULL, curTypeInst, checkMethod, isFailurePass); + methodMatcher.CheckMethod(NULL, curTypeInst, checkMethod, isFailurePass); } if ((methodMatcher.mBestMethodDef != NULL) || (methodMatcher.mBackupMethodDef != NULL)) - break; + break; } - + if (methodMatcher.mBestMethodDef == NULL) methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef; if (methodMatcher.mBestMethodDef == NULL) - { + { mModule->Fail("No constructor available", targetSrc); return BfTypedValue(); } @@ -8320,7 +8669,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou // There should always be a constructor BF_ASSERT(methodMatcher.mBestMethodDef != NULL); - auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments); + auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher.mBestMethodGenericArguments); if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc)) { return BfTypedValue(); @@ -8328,9 +8677,9 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou BfAutoComplete* autoComplete = GetAutoComplete(); if (autoComplete != NULL) - { - BfTypeInstance* resolvedTypeInstance = target.mType->ToTypeInstance(); - auto ctorDecl = BfNodeDynCast(methodDef->mMethodDeclaration); + { + BfTypeInstance* resolvedTypeInstance = target.mType->ToTypeInstance(); + auto ctorDecl = BfNodeDynCast(methodDef->mMethodDeclaration); if ((autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(targetSrc)) && (!BfNodeIsA(targetSrc))) { if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) && @@ -8344,7 +8693,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou else if (resolvedTypeInstance->mTypeDef->mTypeDeclaration != NULL) autoComplete->SetDefinitionLocation(resolvedTypeInstance->mTypeDef->mTypeDeclaration->mNameNode, true); } - } + } else if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (autoComplete->IsAutocompleteNode(targetSrc)) && (moduleMethodInstance.mMethodInstance != NULL)) { @@ -8379,16 +8728,16 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou resolvedArg.mTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), intPtrRefType); } else - { + { BFMODULE_FATAL(mModule, "Bad"); } } methodMatcher.mArguments.Insert(0, resolvedArg); } } - + if (isFailurePass) - mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc); + mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc); prevBindResult.Restore(); return CreateCall(methodMatcher.mTargetSrc, target, BfTypedValue(), methodMatcher.mBestMethodDef, moduleMethodInstance, BfCreateCallFlags_None, methodMatcher.mArguments); } @@ -8398,6 +8747,9 @@ static int sInvocationIdx = 0; BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind, BfIdentifierNode* paramNameNode) { BfTypedValue argValue = resolvedArg.mTypedValue; + if ((resolvedArg.mArgFlags & BfArgFlag_Finalized) != 0) + return argValue; + if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0) { if ((!argValue) || (argValue.mValue.IsFake()) || (resolvedArg.mWantsRecalc)) @@ -8432,7 +8784,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType // We should have already had an error on the first call SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, mModule->mHadBuildError); auto expr = BfNodeDynCast(resolvedArg.mExpression); - BF_ASSERT(expr != NULL); + BF_ASSERT(expr != NULL); argValue = mModule->CreateValueFromExpression(expr, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr)); resolvedArg.mUncastedTypedValue = argValue; if ((argValue) && (wantType != NULL)) @@ -8445,8 +8797,8 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0) { auto variableDeclaration = BfNodeDynCast(resolvedArg.mExpression); - - auto variableType = wantType; + + auto variableType = wantType; bool isLet = (variableDeclaration != NULL) && (variableDeclaration->mTypeRef->IsExact()); bool isVar = (variableDeclaration == NULL) || (variableDeclaration->mTypeRef->IsExact()); @@ -8480,7 +8832,6 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType mModule->Fail("Variable type required for 'var' parameter types", variableDeclaration); } } - if (wantType->IsRef()) { @@ -8493,7 +8844,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode); mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast); } - + BfLocalVariable* localVar = new BfLocalVariable(); if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL)) { @@ -8501,7 +8852,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType localVar->mNameNode = BfNodeDynCast(variableDeclaration->mNameNode); } else - { + { if (paramNameNode != NULL) { localVar->mName = "__"; @@ -8512,7 +8863,7 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType else localVar->mName = "__" + StrFormat("%d", mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId); } - + localVar->mResolvedType = variableType; if (!variableType->IsValuelessType()) localVar->mAddr = mModule->CreateAlloca(variableType); @@ -8522,10 +8873,10 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional; mModule->CheckVariableDef(localVar); localVar->Init(); - mModule->AddLocalVariableDef(localVar, true); + mModule->AddLocalVariableDef(localVar, true); CheckVariableDeclaration(resolvedArg.mExpression, false, false, false); - + argValue = BfTypedValue(localVar->mAddr, mModule->CreateRefType(variableType, BfRefType::RefKind_Out)); auto curScope = mModule->mCurMethodState->mCurScope; @@ -8572,19 +8923,19 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst if (fieldDef == NULL) continue; if ((fieldInstance->mIsEnumPayloadCase) && (fieldDef->mName == caseName)) - { + { if ((!enumType->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) || (!enumType->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef))) continue; auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) - { + { BfAutoComplete::MethodMatchEntry methodMatchEntry; methodMatchEntry.mPayloadEnumField = fieldInstance; methodMatchEntry.mTypeInstance = enumType; methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance; - autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); + autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); } if (resolvePassData != NULL) @@ -8614,12 +8965,12 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst mResultIsTempComposite = true; enumValue = mModule->CreateAlloca(enumType); result = BfTypedValue(enumValue, fieldInstance->mOwner, BfTypedValueKind_TempAddr); - } + } BF_ASSERT(fieldInstance->mResolvedType->IsTuple()); auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType; mModule->mBfIRBuilder->PopulateType(tupleType); - + bool constFailed = false; SizedArray constTupleMembers; BfIRValue fieldPtr; @@ -8636,7 +8987,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst auto mappedPtrType = mModule->mBfIRBuilder->MapType(tuplePtrType); tuplePtr = mModule->mBfIRBuilder->CreateBitCast(fieldPtr, mappedPtrType); } - + for (int tupleFieldIdx = 0; tupleFieldIdx < (int)tupleType->mFieldInstances.size(); tupleFieldIdx++) { auto tupleFieldInstance = &tupleType->mFieldInstances[tupleFieldIdx]; @@ -8653,7 +9004,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst if (invokeExpr->mCloseParen != NULL) refNode = invokeExpr->mCloseParen; } - } + } BfError* error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)argValues.mArguments->size()), refNode); if (error != NULL) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See enum declaration"), fieldDef->mFieldDeclaration); @@ -8661,7 +9012,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst constFailed = true; break; } - + BfTypedValue receivingValue; BfIRValue tupleFieldPtr; if (tuplePtr) @@ -8671,7 +9022,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst } auto argValue = ResolveArgValue(argValues.mResolvedArgs[tupleFieldIdx], resolvedFieldType, &receivingValue); - + if (!argValue) { if (wantConst) @@ -8711,7 +9062,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst } // argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple, - // but we have a value that needs to be attempted to be casted to void + // but we have a value that needs to be attempted to be casted to void argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType, wantConst ? BfCastFlags_WantsConst : BfCastFlags_None); if (wantConst) { @@ -8745,8 +9096,8 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst if (wantConst) constFailed = true; - } - + } + auto dscrType = enumType->GetDiscriminatorType(); auto dscrField = &enumType->mFieldInstances.back(); int tagIdx = -fieldInstance->mDataIdx - 1; @@ -8755,13 +9106,13 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst { auto unionType = enumType->GetUnionInnerType(); auto constTuple = mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType, BfIRPopulateType_Full), constTupleMembers); - + Array memArr; memArr.Resize(unionType->mSize); if (!mModule->mBfIRBuilder->WriteConstant(constTuple, memArr.mVals, tupleType)) { constFailed = true; - } + } else { auto unionValue = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, unionType); @@ -8778,8 +9129,8 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst return BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(enumType, BfIRPopulateType_Full), constEnumMembers), enumType); } } - } - + } + if (constFailed) { return mModule->GetDefaultTypedValue(enumType, false, BfDefaultValueKind_Addr); @@ -8801,7 +9152,7 @@ bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfR auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)genericParamType, genericParamFlags, typeConstraint); bool success = true; - + if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0)) { mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc); @@ -8821,12 +9172,12 @@ bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfR { mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc); success = false; - } + } return success; } -BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName, +BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName, BfResolvedArgs& argValues, const BfMethodGenericArguments& methodGenericArgs, BfCheckedKind checkedKind) { BP_ZONE("MatchMethod"); @@ -8844,9 +9195,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (mFunctionBindResult != NULL) { BF_ASSERT(!mFunctionBindResult->mOrigTarget); - mFunctionBindResult->mOrigTarget = origTarget; + mFunctionBindResult->mOrigTarget = origTarget; } - + if (target) { if (target.mType->IsConcreteInterfaceType()) @@ -8864,7 +9215,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } } - if ((!target.mType->IsGenericParam()) && (!target.IsSplat()) && (!IsVar(target.mType))) + if ((!target.mType->IsGenericParam()) && + ((!target.IsSplat()) || (target.mType->IsWrappableType())) && + (!IsVar(target.mType))) target = MakeCallableTarget(targetSrc, target); } @@ -8885,16 +9238,16 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = false; } defer - ( + ( if (mModule->mCurMethodState != NULL) - mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = prevAllowVariableDeclarations; + mModule->mCurMethodState->mCurScope->mAllowVariableDeclarations = prevAllowVariableDeclarations; ); // Temporarily disable so we don't capture calls in params SetAndRestoreValue prevBindResult(mFunctionBindResult, NULL); - + sInvocationIdx++; - + bool wantCtor = methodName.IsEmpty(); BfAutoComplete::MethodMatchInfo* restoreCapturingMethodMatchInfo = NULL; @@ -8919,7 +9272,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp /*if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo->mInstanceList.size() != 0)) autoComplete->mIsCapturingMethodMatchInfo = false;*/ - bool isUnboundCall = false; + bool isUnboundCall = false; if (target.mType != NULL) { if (target.mType->IsGenericParam()) @@ -8933,7 +9286,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { auto varType = mModule->GetPrimitiveType(BfTypeCode_Var); target.mType = varType; - } + } } } else if (IsVar(target.mType)) @@ -8941,7 +9294,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } /*if (mPrefixedAttributeState != NULL) - { + { auto customAttr = mPrefixedAttributeState->mCustomAttributes->Get(mModule->mCompiler->mUnboundAttributeTypeDef); if (customAttr != NULL) { @@ -8979,15 +9332,15 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++) { if ((argValues.mResolvedArgs[argIdx].mArgFlags & BfArgFlag_DeferredEval) != 0) - { + { mModule->CreateValueFromExpression((*argValues.mArguments)[argIdx], varType); } } - + return BfTypedValue(mModule->GetDefaultValue(varType), varType); } } - + SetAndRestoreValue prevNoBind(mNoBind, mNoBind || isUnboundCall); bool wantsExtensionCheck = target; @@ -8996,17 +9349,17 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp BfType* selfType = NULL; BfTypeInstance* targetTypeInst = NULL; bool checkNonStatic = true; - + if (target) { if (IsVar(targetType)) - return mModule->GetDefaultTypedValue(targetType); - targetTypeInst = targetType->ToTypeInstance(); + return mModule->GetDefaultTypedValue(targetType); + targetTypeInst = targetType->ToTypeInstance(); if (targetTypeInst != NULL) - curTypeDef = targetTypeInst->mTypeDef; + curTypeDef = targetTypeInst->mTypeDef; } else if (targetType != NULL) // Static targeted - { + { if (targetType->IsWrappableType()) { if ((targetType->IsPrimitiveType()) && (methodName.IsEmpty())) @@ -9018,7 +9371,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp else if (argValues.mArguments->mSize == 1) { FinishDeferredEvals(argValues); - + // This is just a primitive cast auto& resolvedArg = argValues.mResolvedArgs[0]; BfTypedValue castedValue; @@ -9079,12 +9432,12 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { checkNonStatic = false; } - else + else { if (mModule->mCurMethodState->mMixinState != NULL) - { + { targetTypeInst = mModule->mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner(); - curTypeDef = targetTypeInst->mTypeDef; + curTypeDef = targetTypeInst->mTypeDef; } if (mModule->mCurMethodState->mTempKind != BfMethodState::TempKind_None) @@ -9107,19 +9460,24 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp lookupTypeInst = NULL; } + if ((mModule->mIsReified) && (targetTypeInst != NULL) && (!targetTypeInst->mIsReified) && (!targetTypeInst->mModule->mReifyQueued)) + mModule->PopulateType(targetTypeInst); + BfMethodDef* methodDef = NULL; BfTypeVector checkMethodGenericArguments; BfTypeInstance* curTypeInst = targetTypeInst; + Array*> methodUsingLists; BfMethodMatcher methodMatcher(targetSrc, mModule, methodName, argValues.mResolvedArgs, methodGenericArgs); + methodMatcher.mUsingLists = &methodUsingLists; methodMatcher.mOrigTarget = origTarget; methodMatcher.mTarget = target; methodMatcher.mCheckedKind = checkedKind; methodMatcher.mAllowImplicitThis = allowImplicitThis; methodMatcher.mAllowStatic = !target.mValue; methodMatcher.mAllowNonStatic = !methodMatcher.mAllowStatic; - methodMatcher.mAutoFlushAmbiguityErrors = !wantsExtensionCheck; + methodMatcher.mAutoFlushAmbiguityErrors = !wantsExtensionCheck; if (allowImplicitThis) { if (mModule->mCurMethodState == NULL) @@ -9152,9 +9510,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp BfLocalMethod* matchedLocalMethod = NULL; if (target.mType == NULL) - { + { CheckLocalMethods(targetSrc, curTypeInst, methodName, methodMatcher, BfMethodType_Normal); - + if (methodMatcher.mBestMethodDef == NULL) methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef; @@ -9167,24 +9525,24 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp auto identifierNode = BfNodeDynCast(targetSrc); mModule->mCompiler->mResolvePassData->HandleLocalReference(identifierNode, curTypeInst->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, ~methodDef->mIdx); auto autoComplete = GetAutoComplete(); - if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode))) + if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode))) { - autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true); + autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true); if (autoComplete->mDefType == NULL) - { + { autoComplete->mDefMethod = mModule->mCurMethodState->GetRootMethodState()->mMethodInstance->mMethodDef; autoComplete->mDefType = curTypeDef; - autoComplete->mReplaceLocalId = ~methodDef->mIdx; + autoComplete->mReplaceLocalId = ~methodDef->mIdx; } } if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) - { + { BfAutoComplete::MethodMatchEntry methodMatchEntry; methodMatchEntry.mMethodDef = methodDef; methodMatchEntry.mTypeInstance = mModule->mCurTypeInstance; methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance; - autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); + autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); } } @@ -9196,7 +9554,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { FinishDeferredEvals(argValues); - // If we are recursive then we won't even have a completed methodInstance yet to look at + // If we are recursive then we won't even have a completed methodInstance yet to look at return mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType); } } @@ -9215,7 +9573,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp else if (isUnboundCall) { //auto resolvedType = mModule->ResolveGenericType(lookupType); - } else if (lookupType->IsGenericParam()) { @@ -9237,18 +9594,18 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } }; - auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget); + auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget, true); _HandleGenericParamInstance(genericParamInstance); - + // Check method generic constraints if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL)) { - for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); + for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) { auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; if (genericParam->mExternType == lookupType) - _HandleGenericParamInstance(genericParam); + _HandleGenericParamInstance(genericParam); } } } @@ -9272,14 +9629,14 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } } } - } + } bool isFailurePass = false; if (methodMatcher.mBestMethodDef == NULL) { isFailurePass = true; if (lookupTypeInst != NULL) - methodMatcher.CheckType(lookupTypeInst, target, true); + methodMatcher.CheckType(lookupTypeInst, target, true); } BfTypedValue staticResult; @@ -9295,18 +9652,108 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp bypassVirtual |= methodMatcher.mBypassVirtual; if (methodMatcher.mBestMethodDef != NULL) - { + { curTypeInst = methodMatcher.mBestMethodTypeInstance; - methodDef = methodMatcher.mBestMethodDef; + methodDef = methodMatcher.mBestMethodDef; } if ((methodDef) && (!methodDef->mIsStatic) && (!target) && (allowImplicitThis)) { - target = mModule->GetThis(); + target = mModule->GetThis(); } - // If we call "GetType" on a value type, statically determine the type rather than boxing and then dispatching - if ((methodDef) && (target) && (curTypeInst == mModule->mContext->mBfObjectType) && + if (!methodUsingLists.IsEmpty()) + { + auto foundList = methodUsingLists[0]; + + if (methodUsingLists.mSize > 1) + { + BfError* error = mModule->Fail("Ambiguous 'using' method reference", targetSrc); + if (error != NULL) + { + for (auto checkList : methodUsingLists) + { + String errorStr = "'"; + for (int entryIdx = 0; entryIdx < checkList->mSize; entryIdx++) + { + if (entryIdx == 0) + errorStr += (*checkList)[entryIdx].GetFullName(mModule); + else + { + errorStr += "."; + errorStr += (*checkList)[entryIdx].GetName(mModule); + } + } + errorStr += "' is a candidate"; + mModule->mCompiler->mPassInstance->MoreInfo(errorStr, (*checkList)[0].GetRefNode(mModule)); + } + } + } + + BfTypedValue curResult = target; + for (int entryIdx = 0; entryIdx < foundList->mSize; entryIdx++) + { + if ((entryIdx == 0) && (foundList->back().IsStatic())) + entryIdx = (int)foundList->mSize - 1; + + auto& entry = (*foundList)[entryIdx]; + if (mPropDef != NULL) + { + SetAndRestoreValue prevResult(mResult, BfTypedValue()); + mPropGetMethodFlags = (BfGetMethodInstanceFlags)(mPropGetMethodFlags | BfGetMethodInstanceFlag_Friend); + curResult = GetResult(); + if (!curResult) + break; + } + + auto useFlags = BfLookupFieldFlag_None; + if (entryIdx < foundList->mSize - 1) + useFlags = (BfLookupFieldFlags)(useFlags | BfLookupFieldFlag_IsAnonymous); + + if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Field) + { + curResult = LoadField(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mFields[entry.mIdx], useFlags); + } + else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Property) + { + curResult = LoadProperty(targetSrc, curResult, entry.mTypeInstance, entry.mTypeInstance->mTypeDef->mProperties[entry.mIdx], useFlags, BfCheckedKind_NotSet, false); + } + else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local) + { + auto localDef = mModule->mCurMethodState->mLocals[entry.mIdx]; + curResult = LoadLocal(localDef); + } + else if (entry.mKind == BfUsingFieldData::MemberRef::Kind_Local) + { + auto checkMethodDef = entry.mTypeInstance->mTypeDef->mMethods[entry.mIdx]; + BF_ASSERT(methodDef == checkMethodDef); + break; + } + + if ((!curResult) && (mPropDef == NULL)) + break; + + if (entryIdx == foundList->mSize - 1) + { + auto autoComplete = GetAutoComplete(); + if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetSrc))) + autoComplete->SetDefinitionLocation(entry.GetRefNode(mModule)); + + if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc))) + autoComplete->FixitAddFullyQualify(targetSrc, methodName, *foundList); + } + } + + if (methodDef->mIsStatic) + target = BfTypedValue(curTypeInst); + else if (curResult) + target = curResult; + else if ((!methodDef->mIsStatic) && (curTypeInst != NULL)) + target = mModule->GetDefaultTypedValue(curTypeInst); + } + + // If we call "GetType" on a value type, statically determine the type rather than boxing and then dispatching + if ((methodDef) && (target) && (curTypeInst == mModule->mContext->mBfObjectType) && (methodDef->mName == "GetType") && (target.mType->IsValueType()) && (argValues.mArguments->IsEmpty())) { BfType* targetType = target.mType; @@ -9315,8 +9762,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); - return BfTypedValue(mModule->CreateTypeDataRef(targetType), typeType); - } + return BfTypedValue(mModule->CreateTypeDataRef(targetType), typeType); + } bool skipThis = false; @@ -9326,25 +9773,25 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp // Fail, check for delegate field invocation if ((methodDef == NULL) && ((methodGenericArguments == NULL) || (methodGenericArguments->size() == 0))) { - // Check for payload enum initialization first + // Check for payload enum initialization first BfTypedValue enumResult; - BfTypeInstance* enumType = NULL; + BfTypeInstance* enumType = NULL; if ((!target) && (target.HasType()) && (targetType->IsPayloadEnum())) { - enumType = targetType->ToTypeInstance(); + enumType = targetType->ToTypeInstance(); } else if ((!target) && (!target.HasType()) && (mModule->mCurTypeInstance->IsPayloadEnum())) { - enumType = mModule->mCurTypeInstance; + enumType = mModule->mCurTypeInstance; } if (enumType != NULL) - { + { enumResult = CheckEnumCreation(targetSrc, enumType, methodName, argValues); } if (enumResult) - { + { if (mModule->mCompiler->mResolvePassData != NULL) { if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(targetSrc)) @@ -9354,9 +9801,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } return enumResult; } - + if (allowImplicitThis) - { + { auto identifierNode = BfNodeDynCast(targetSrc); if (identifierNode != NULL) fieldVal = LookupIdentifier(identifierNode); @@ -9383,13 +9830,13 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if ((getMethodInstance != NULL) && ((getMethodInstance->mReturnType->IsDelegate()) || (getMethodInstance->mReturnType->IsFunction()))) wantsExtensionCheck = false; - } + } } } if ((!methodDef) && (!target.mValue)) { - // Check to see if we're constructing a struct via a call like: "Struct structVal = Struct()" + // Check to see if we're constructing a struct via a call like: "Struct structVal = Struct()" int wantNumGenericArgs = 0; if ((methodGenericArguments != NULL) && (methodGenericArguments->size() > 0)) wantNumGenericArgs = (int)methodGenericArguments->size(); @@ -9399,7 +9846,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp resolvedTypeInstance = targetTypeInst; } else if (targetType != NULL) - { + { if (auto invocationExpr = BfNodeDynCast(methodBoundExpr)) { auto resolvedType = mModule->ResolveTypeRef(invocationExpr->mTarget, methodGenericArguments); @@ -9407,7 +9854,6 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (resolvedType != NULL) resolvedTypeInstance = resolvedType->ToTypeInstance(); } - } else { @@ -9467,15 +9913,24 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (resolvedTypeInstance != NULL) { - if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive())) + if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0) { - if (mModule->PreFail()) - mModule->Fail("Objects must be allocated through 'new' or 'scope'", targetSrc); - return BfTypedValue(); + if ((!resolvedTypeInstance->IsStruct()) && (!resolvedTypeInstance->IsTypedPrimitive())) + { + if (mModule->PreFail()) + mModule->Fail("Objects must be allocated through 'new' or 'scope'", targetSrc); + return BfTypedValue(); + } } - + if (auto identifier = BfNodeDynCastExact(targetSrc)) - mModule->SetElementType(identifier, resolvedTypeInstance->IsEnum() ? BfSourceElementType_Type : BfSourceElementType_Struct); + { + auto elementType = resolvedTypeInstance->IsEnum() ? BfSourceElementType_Type : BfSourceElementType_Struct; + if (resolvedTypeInstance->IsObject()) + elementType = BfSourceElementType_RefType; + mModule->SetElementType(identifier, elementType); + } + if (mModule->mCompiler->mResolvePassData != NULL) { if (!BfNodeIsA(targetSrc)) @@ -9502,37 +9957,37 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { structInst = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeInstance, true); } - + mResultLocalVar = NULL; mResultFieldInstance = NULL; - mResultLocalVarRefNode = NULL; - auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, false); + mResultLocalVarRefNode = NULL; + auto result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, resolvedTypeInstance->IsObject()); if ((result) && (!result.mType->IsVoid())) return result; mModule->ValidateAllocation(resolvedTypeInstance, targetSrc); - + mModule->AddDependency(resolvedTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); if (mUsedAsStatement) { mModule->Warn(0, "Struct constructor being used as a statement", targetSrc); } - + return structInst; } - } + } // For for extensions in current type if (wantsExtensionCheck) { - auto checkTypeInst = mModule->mCurTypeInstance; + auto checkTypeInst = mModule->mCurTypeInstance; methodMatcher.mMethodType = BfMethodType_Extension; - if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true)) - { + if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true)) + { isFailurePass = false; curTypeInst = methodMatcher.mBestMethodTypeInstance; methodDef = methodMatcher.mBestMethodDef; - } + } } // Look in globals. Always check for extension methods. @@ -9550,14 +10005,14 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (globalContainer.mTypeInst == NULL) continue; methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal; - if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false)) + if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false)) { isFailurePass = false; curTypeInst = methodMatcher.mBestMethodTypeInstance; - methodDef = methodMatcher.mBestMethodDef; + methodDef = methodMatcher.mBestMethodDef; } } - } + } } // Look in static search. Always check for extension methods. @@ -9569,11 +10024,11 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp for (auto typeInst : staticSearch->mStaticTypes) { methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal; - if (methodMatcher.CheckType(typeInst, BfTypedValue(), false)) + if (methodMatcher.CheckType(typeInst, BfTypedValue(), false)) { isFailurePass = false; curTypeInst = methodMatcher.mBestMethodTypeInstance; - methodDef = methodMatcher.mBestMethodDef; + methodDef = methodMatcher.mBestMethodDef; } } } @@ -9602,7 +10057,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_AllowParamsExpr; - exprEvaluator.Evaluate((*argValues.mArguments)[0]); + auto argExpr = (*argValues.mArguments)[0]; + if (argExpr != NULL) + exprEvaluator.Evaluate(argExpr); if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL)) { auto localVar = exprEvaluator.mResultLocalVar; @@ -9638,7 +10095,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp return MatchMethod(targetSrc, NULL, fieldVal, false, false, "Invoke", argValues, methodGenericArgs, checkedKind); } if (IsVar(fieldVal.mType)) - { + { FinishDeferredEvals(argValues); return BfTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType); } @@ -9723,6 +10180,10 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } } + if (methodDef == NULL) + { + } + // This will flush out any new ambiguity errors from extension methods methodMatcher.FlushAmbiguityError(); @@ -9730,21 +10191,21 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { FinishDeferredEvals(argValues); auto compiler = mModule->mCompiler; - if ((compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(targetSrc))) - { - mModule->CheckTypeRefFixit(targetSrc); + if ((autoComplete != NULL) && (autoComplete->CheckFixit(targetSrc))) + { + mModule->CheckTypeRefFixit(targetSrc); bool wantStatic = !target.mValue; if ((targetType == NULL) && (allowImplicitThis)) { targetType = mModule->mCurTypeInstance; if (mModule->mCurMethodInstance != NULL) wantStatic = mModule->mCurMethodInstance->mMethodDef->mIsStatic; - } + } if (targetType != NULL) { auto typeInst = targetType->ToTypeInstance(); - if ((targetType != NULL) && (!methodName.IsEmpty())) + if ((typeInst != NULL) && (!methodName.IsEmpty())) { BfTypeVector paramTypes; for (int argIdx = 0; argIdx < (int)argValues.mResolvedArgs.size(); argIdx++) @@ -9755,7 +10216,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp autoComplete->FixitAddMethod(typeInst, methodName, mExpectingType, paramTypes, wantStatic); } - } + } } if (methodName.IsEmpty()) @@ -9768,7 +10229,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { if ((origTarget.mType->IsPointer()) && (origTarget.mType->GetUnderlyingType()->IsObjectOrInterface())) { - mModule->Fail(StrFormat("Methods cannot be called on type '%s' because the type is a pointer to a reference type (ie: a double-reference).", + mModule->Fail(StrFormat("Methods cannot be called on type '%s' because the type is a pointer to a reference type (ie: a double-reference).", mModule->TypeToString(origTarget.mType).c_str()), targetSrc); } else @@ -9781,7 +10242,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp mModule->Fail(StrFormat("Method '%s' does not exist", methodName.c_str()), targetSrc); } return BfTypedValue(); - } + } if ((prevBindResult.mPrevVal != NULL) && (methodMatcher.mMethodCheckCount > 1)) prevBindResult.mPrevVal->mCheckedMultipleMethods = true; @@ -9789,7 +10250,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp BfType* overrideReturnType = NULL; BfModuleMethodInstance moduleMethodInstance = GetSelectedMethod(targetSrc, curTypeInst, methodDef, methodMatcher, &overrideReturnType); - if ((mModule->mAttributeState != NULL) && ((mModule->mAttributeState->mFlags & (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)) == + if ((mModule->mAttributeState != NULL) && ((mModule->mAttributeState->mFlags & (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError)) == (BfAttributeState::Flag_StopOnError | BfAttributeState::Flag_HadError))) { FinishDeferredEvals(argValues); @@ -9833,7 +10294,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp } bool isSkipCall = moduleMethodInstance.mMethodInstance->IsSkipCall(bypassVirtual); - + if ((moduleMethodInstance.mMethodInstance->IsOrInUnspecializedVariation()) && (!mModule->mBfIRBuilder->mIgnoreWrites)) { // Invalid methods such as types with a HasVar tuple generic arg will be marked as mIsUnspecializedVariation and shouldn't actually be called @@ -9845,8 +10306,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { // Ignore call return mModule->GetDefaultTypedValue(moduleMethodInstance.mMethodInstance->mReturnType, true, BfDefaultValueKind_Addr); - } - + } + if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsStatic) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface())) { bool isConstrained = false; @@ -9882,13 +10343,13 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp BfType* callTargetType = curTypeInst; if (methodDef->mMethodType == BfMethodType_Extension) { - callTargetType = moduleMethodInstance.mMethodInstance->GetParamType(0); + callTargetType = moduleMethodInstance.mMethodInstance->GetParamType(0); if ((callTargetType->IsRef()) && (target.IsAddr()) && (!target.IsReadOnly()) && (target.mType->IsValueType())) { target = BfTypedValue(target.mValue, mModule->CreateRefType(target.mType)); } } - + BfTypedValue callTarget; if (isSkipCall) { @@ -9899,9 +10360,9 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { if ((moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating) && ((target.IsReadOnly()) || (!target.IsAddr()))) - { + { String err = StrFormat("call mutating method '%s' on", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()); - CheckModifyResult(target, targetSrc, err.c_str()); + CheckModifyResult(target, targetSrc, err.c_str()); } } @@ -9919,7 +10380,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if ((callTarget) && (moduleMethodInstance.mMethodInstance->GetOwner()->IsInterface())) { - auto wantThis = moduleMethodInstance.mMethodInstance->GetParamType(-1); + auto wantThis = moduleMethodInstance.mMethodInstance->GetParamType(-1); if ((callTarget.mType != wantThis) && (wantThis->IsInterface())) callTarget = mModule->Cast(targetSrc, callTarget, wantThis, BfCastFlags_Explicit); } @@ -9983,23 +10444,30 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), moduleMethodInstance.mMethodInstance->mMethodDef->GetRefNode()); } } - + if ((mModule->mCompiler->mResolvePassData != NULL) && (methodDef != NULL)) { auto identifierNode = BfNodeDynCast(targetSrc); while (auto qualifiedNameNode = BfNodeDynCast(identifierNode)) identifierNode = qualifiedNameNode->mRight; - if ((identifierNode != NULL) && (methodDef->mIdx >= 0) && (!isIndirectMethodCall) && + if ((identifierNode != NULL) && (methodDef->mIdx >= 0) && (!isIndirectMethodCall) && ((targetTypeInst == NULL) || (!targetTypeInst->IsDelegateOrFunction()))) { - mModule->mCompiler->mResolvePassData->HandleMethodReference(identifierNode, moduleMethodInstance.mMethodInstance->GetOwner()->mTypeDef, methodDef); + auto refMethodInstance = moduleMethodInstance.mMethodInstance; + if (refMethodInstance->mVirtualTableIdx != -1) + { + auto& virtualEntry = refMethodInstance->GetOwner()->mVirtualMethodTable[refMethodInstance->mVirtualTableIdx]; + refMethodInstance = virtualEntry.mDeclaringMethod; + } + + mModule->mCompiler->mResolvePassData->HandleMethodReference(identifierNode, refMethodInstance->GetOwner()->mTypeDef, refMethodInstance->mMethodDef); auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(identifierNode))) - { + { autoComplete->SetDefinitionLocation(methodDef->GetRefNode(), true); int virtualIdx = moduleMethodInstance.mMethodInstance->mVirtualTableIdx; - if ((autoComplete->mResolveType == BfResolveType_GoToDefinition) && + if ((autoComplete->mResolveType == BfResolveType_GoToDefinition) && (virtualIdx != -1) && (targetTypeInst != NULL) && (!targetTypeInst->IsStruct()) && (!targetTypeInst->IsTypedPrimitive()) && (!targetTypeInst->IsInterface()) && // VirtualMethodTable can be empty if the non-autocomplete classifier hasn't completed yet. Allow failure, a PopulateType here can't force the method table to fill out (targetTypeInst->mVirtualMethodTable.size() != 0)) @@ -10016,12 +10484,12 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp autoComplete->SetDefinitionLocation(callingMethodDeclaration->mNameNode, true); } } - } - + } + if (autoComplete->mDefType == NULL) { - autoComplete->mDefMethod = methodDef; - autoComplete->mDefType = moduleMethodInstance.mMethodInstance->GetOwner()->mTypeDef; + autoComplete->mDefMethod = refMethodInstance->mMethodDef; + autoComplete->mDefType = refMethodInstance->GetOwner()->mTypeDef; } if (autoComplete->mResolveType == BfResolveType_GetResultString) @@ -10029,7 +10497,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp autoComplete->mResultString = ":"; autoComplete->mResultString += mModule->MethodToString(moduleMethodInstance.mMethodInstance); - auto methodDecl = moduleMethodInstance.mMethodInstance->mMethodDef->GetMethodDeclaration(); + auto methodDecl = moduleMethodInstance.mMethodInstance->mMethodDef->GetMethodDeclaration(); if ((methodDecl != NULL) && (methodDecl->mDocumentation != NULL)) { autoComplete->mResultString += "\x03"; @@ -10058,18 +10526,18 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { //BF_ASSERT(!callTarget.mValue.IsFake()); } - + prevBindResult.Restore(); // Check mut if ((callTarget.mType != NULL) && - (callTarget.mType->IsGenericParam()) && + (callTarget.mType->IsGenericParam()) && ((!callTarget.IsAddr()) || (callTarget.IsReadOnly())) && (callTarget.mKind != BfTypedValueKind_MutableValue) && (moduleMethodInstance.mMethodInstance->mMethodDef->mIsMutating)) { auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)callTarget.mType); - + bool needsMut = true; if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class | BfGenericParamFlag_Var)) != 0) needsMut = false; @@ -10098,49 +10566,20 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp (!mModule->mCurMethodInstance->mMethodDef->mIsMutating) && (methodDef->mIsMutating)) { - mModule->Fail(StrFormat("Cannot call mutating method '%s' within default interface method '%s'. Consider adding 'mut' specifier to this method.", + mModule->Fail(StrFormat("Cannot call mutating method '%s' within default interface method '%s'. Consider adding 'mut' specifier to this method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), targetSrc); } - BfTypedValue result; BfTypedValue argCascade; - - // - { - SetAndRestoreValue prevEvalExprFlag(mBfEvalExprFlags); - - if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef))) - { - mModule->mAttributeState->mUsed = true; - mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); - } - else if ((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) - { - mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); - } - else if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_Comptime) != 0) && (!mModule->mIsComptimeModule)) - { - if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) - mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime); - } - if (((moduleMethodInstance.mMethodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && - ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && - ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mComptimeFlags == BfComptimeFlag_None)) && - (!mModule->mIsComptimeModule)) - { - mModule->Fail(StrFormat("Method '%s' can only be invoked at comptime. Consider adding [Comptime] to the current method.", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc); - } + BfCreateCallFlags subCallFlags = BfCreateCallFlags_None; + if (bypassVirtual) + subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_BypassVirtual); + if (skipThis) + subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_SkipThis); + result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, subCallFlags, argValues.mResolvedArgs, &argCascade); - BfCreateCallFlags subCallFlags = BfCreateCallFlags_None; - if (bypassVirtual) - subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_BypassVirtual); - if (skipThis) - subCallFlags = (BfCreateCallFlags)(subCallFlags | BfCreateCallFlags_SkipThis); - result = CreateCall(targetSrc, callTarget, origTarget, methodDef, moduleMethodInstance, subCallFlags, argValues.mResolvedArgs, &argCascade); - } - if (overrideReturnType != NULL) { BF_ASSERT(moduleMethodInstance.mMethodInstance->mIsUnspecializedVariation); @@ -10157,7 +10596,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp if (result) { - bool discardedReturnValue = mUsedAsStatement; + bool discardedReturnValue = mUsedAsStatement; if (discardedReturnValue) { auto _ShowDiscardWaring = [&](const String& text, BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfAstNode* refNode) @@ -10172,7 +10611,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp { mModule->Warn(0, text + ": " + *str, targetSrc); return; - } + } } } @@ -10182,7 +10621,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp bool showedWarning = false; if (moduleMethodInstance.mMethodInstance->mMethodDef->mIsNoDiscard) { - _ShowDiscardWaring("Discarding return value of method with [NoDiscard] attribute", moduleMethodInstance.mMethodInstance->GetCustomAttributes(), + _ShowDiscardWaring("Discarding return value of method with [NoDiscard] attribute", moduleMethodInstance.mMethodInstance->GetCustomAttributes(), moduleMethodInstance.mMethodInstance->GetOwner()->mConstHolder, targetSrc); showedWarning = true; } @@ -10242,14 +10681,14 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp BF_ASSERT(mModule->IsInGeneric()); selfType = methodMatcher.mSelfType; } - else + else { // Will be an error selfType = methodMatcher.mBestMethodTypeInstance; } if ((selfType != NULL) && (!selfType->IsInterface())) - { + { auto resolvedType = mModule->ResolveSelfType(result.mType, selfType); if ((resolvedType != NULL) && (resolvedType != result.mType)) result = mModule->GetDefaultTypedValue(resolvedType); @@ -10268,7 +10707,7 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig StringT<64> fieldName; if (nameNode->mRight != NULL) nameNode->mRight->ToString(fieldName); - + bool wasBaseLookup = false; if (auto qualifiedLeftName = BfNodeDynCast(nameNode->mLeft)) { @@ -10278,28 +10717,28 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig auto type = mModule->ResolveTypeRef(qualifiedLeftName->mLeft, NULL); if (type == NULL) return; - + auto fieldName = nameNode->mRight->ToString(); auto target = mModule->GetThis(); target.mType = type; mResult = LookupField(nameNode->mRight, target, fieldName); if ((mPropDef != NULL) && (mPropDef->IsVirtual())) - mPropDefBypassVirtual = true; + mPropDefBypassVirtual = true; return; } } if (!wasBaseLookup) mResult = LookupIdentifier(nameNode->mLeft, ignoreInitialError, hadError); - GetResult(); + GetResult(); if (!mResult) { if (!ignoreInitialError) mModule->Fail("Identifier not found", nameNode->mLeft); - return; - } - + return; + } + if (mResult.mType->IsObject()) { mResult = mModule->LoadValue(mResult, 0, mIsVolatileReference); @@ -10316,12 +10755,12 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig } mIsVolatileReference = false; mIsHeapReference = false; - + if (!mResult) return; auto origResult = mResult; - auto lookupType = BindGenericType(nameNode, mResult.mType); + auto lookupType = BindGenericType(nameNode, mResult.mType); if (IsVar(mResult.mType)) { @@ -10337,22 +10776,22 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig mResult = BfTypedValue(); return; } - - BfTypedValue lookupVal = mResult; + + BfTypedValue lookupVal = mResult; mResult = LookupField(nameNode->mRight, lookupVal, fieldName); if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam())) { - auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType); + auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true); SizedArray searchConstraints; for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints) - { + { if (!searchConstraints.Contains(ifaceConstraint)) { searchConstraints.push_back(ifaceConstraint); for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces) { - auto innerIFace = innerIFaceEntry.mInterfaceType; + auto innerIFace = innerIFaceEntry.mInterfaceType; if (!searchConstraints.Contains(innerIFace)) { searchConstraints.push_back(innerIFace); @@ -10364,12 +10803,12 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig BfTypedValue prevTarget; BfPropertyDef* prevDef = NULL; for (auto ifaceConstraint : searchConstraints) - { + { BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint); - + mResult = LookupField(nameNode->mRight, lookupVal, fieldName); if (mPropDef != NULL) - { + { if (prevDef != NULL) { bool isBetter = mModule->TypeIsSubTypeOf(mPropTarget.mType->ToTypeInstance(), prevTarget.mType->ToTypeInstance()); @@ -10389,7 +10828,7 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig } } prevDef = mPropDef; - prevTarget = mPropTarget; + prevTarget = mPropTarget; } } /*if ((mResult) || (mPropDef != NULL)) @@ -10403,8 +10842,8 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig mPropDefBypassVirtual = true; } if ((mResult) || (mPropDef != NULL)) - return; - + return; + if (hadError != NULL) *hadError = true; @@ -10412,9 +10851,9 @@ void BfExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ig auto compiler = mModule->mCompiler; if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight))) { - FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), false); + FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), false); } - mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameNode->mRight); + mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameNode->mRight); } void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError) @@ -10438,7 +10877,7 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* target.mType = type; mResult = LookupField(nameRight, target, fieldName); if ((mPropDef != NULL) && (mPropDef->IsVirtual())) - mPropDefBypassVirtual = true; + mPropDefBypassVirtual = true; return; } } @@ -10481,26 +10920,25 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* if (mResult.mType->IsAllocType()) mResult.mType = mResult.mType->GetUnderlyingType(); - auto origResult = mResult; + auto origResult = mResult; if (IsVar(mResult.mType)) { auto varType = mModule->GetPrimitiveType(BfTypeCode_Var); mResult = BfTypedValue(mModule->GetDefaultValue(varType), varType, true); return; - } + } if ((!mResult.mType->IsTypeInstance()) && (!mResult.mType->IsGenericParam())) - { + { if (mResult.mType->IsSizedArray()) { - if (mResult.mType->IsValuelessType()) { mResult.mType = mModule->GetWrappedStructType(mResult.mType); mResult.mValue = mModule->mBfIRBuilder->GetFakeVal(); } else - { + { mResult = mModule->MakeAddressable(mResult); mResult.mType = mModule->GetWrappedStructType(mResult.mType); mResult.mValue = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(mResult.mType->ToTypeInstance())); @@ -10521,11 +10959,22 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* } BfTypedValue lookupVal = mResult; - auto lookupType = BindGenericType(nameNode, mResult.mType); + auto lookupType = BindGenericType(nameNode, mResult.mType); if ((lookupType->IsGenericParam()) && (!mResult.mType->IsGenericParam())) { + bool prevUseMixinGenerics = false; + if (mModule->mCurMethodState->mMixinState != NULL) + { + prevUseMixinGenerics = mModule->mCurMethodState->mMixinState->mUseMixinGenerics; + mModule->mCurMethodState->mMixinState->mUseMixinGenerics = true; + } + // Try to lookup from generic binding mResult = LookupField(nameRight, BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), lookupType), fieldName, BfLookupFieldFlag_BindOnly); + + if (mModule->mCurMethodState->mMixinState != NULL) + mModule->mCurMethodState->mMixinState->mUseMixinGenerics = prevUseMixinGenerics; + if (mPropDef != NULL) { mOrigPropTarget = lookupVal; @@ -10538,17 +10987,17 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* if ((!mResult) && (mPropDef == NULL) && (lookupType->IsGenericParam())) { - auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType); + auto genericParamInst = mModule->GetGenericParamInstance((BfGenericParamType*)lookupType, true); SizedArray searchConstraints; for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints) - { + { if (!searchConstraints.Contains(ifaceConstraint)) { searchConstraints.push_back(ifaceConstraint); for (auto& innerIFaceEntry : ifaceConstraint->mInterfaces) { - auto innerIFace = innerIFaceEntry.mInterfaceType; + auto innerIFace = innerIFaceEntry.mInterfaceType; if (!searchConstraints.Contains(innerIFace)) { searchConstraints.push_back(innerIFace); @@ -10560,7 +11009,7 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* BfTypedValue prevTarget; BfPropertyDef* prevDef = NULL; for (auto ifaceConstraint : searchConstraints) - { + { BfTypedValue lookupVal = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), ifaceConstraint); mResult = LookupField(nameRight, lookupVal, fieldName); @@ -10620,20 +11069,24 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* { FixitAddMember(typeInst, mExpectingType, nameRight->ToString(), false); } + + if (((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) && (typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, fieldName))) + return; + mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", fieldName.c_str(), mModule->TypeToString(lookupType).c_str()), nameRight); } void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError) { // Lookup left side as a type - { + { BfType* type = NULL; { type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); mModule->CheckTypeRefFixit(nameNode->mLeft); } if (type != NULL) - { + { BfTypedValue lookupType; if (type->IsWrappableType()) lookupType = BfTypedValue(mModule->GetWrappedStructType(type)); @@ -10655,7 +11108,7 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, auto compiler = mModule->mCompiler; if ((typeInst != NULL) && (compiler->IsAutocomplete()) && (compiler->mResolvePassData->mAutoComplete->CheckFixit(nameNode->mRight))) { - FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), true); + FixitAddMember(typeInst, mExpectingType, nameNode->mRight->ToString(), true); } } @@ -10667,11 +11120,11 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, String fieldName = nameNode->mRight->ToString(); - if (auto qualifiedLeftName = BfNodeDynCast(nameNode->mLeft)) + if (auto qualifiedLeftName = BfNodeDynCast(nameNode->mLeft)) LookupQualifiedStaticField(qualifiedLeftName, true); else if (auto leftName = BfNodeDynCast(nameNode->mLeft)) { - mResult = LookupIdentifier(leftName); + mResult = LookupIdentifier(leftName); } GetResult(); @@ -10698,7 +11151,7 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, if (!mResult.mType->IsTypeInstance()) { - mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft); + mModule->Fail(StrFormat("Type '%s' has no fields", mModule->TypeToString(mResult.mType).c_str()), nameNode->mLeft); return; } @@ -10713,8 +11166,11 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError) { // Lookup left side as a type - { + { BfType* type = mModule->ResolveTypeRef(nameLeft, NULL, BfPopulateType_Declaration, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_AllowGlobalContainer)); + if ((type != NULL) && (type->IsVar()) && (nameLeft->Equals("var"))) + type = NULL; + if (type != NULL) { BfTypedValue lookupType; @@ -10766,6 +11222,13 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifi } } + if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) + { + auto typeInst = lookupType.mType->ToTypeInstance(); + if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName))) + return; + } + if ((mBfEvalExprFlags & BfEvalExprFlags_NoLookupError) == 0) mModule->Fail("Field not found", nameRight); return; @@ -10839,17 +11302,17 @@ void BfExprEvaluator::Visit(BfQualifiedNameNode* nameNode) } bool hadError = false; - LookupQualifiedName(nameNode, nameNode->mLeft, nameNode->mRight, true, &hadError); + LookupQualifiedName(nameNode, nameNode->mLeft, nameNode->mRight, true, &hadError); if ((mResult) || (mPropDef != NULL)) return; if (hadError) return; - + LookupQualifiedStaticField(nameNode, nameNode->mLeft, nameNode->mRight, false); } void BfExprEvaluator::Visit(BfThisExpression* thisExpr) -{ +{ mResult = mModule->GetThis(); if (!mResult) { @@ -10858,11 +11321,11 @@ void BfExprEvaluator::Visit(BfThisExpression* thisExpr) } auto autoComplete = GetAutoComplete(); - if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(thisExpr))) - autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mTypeDef->GetRefNode()); + if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(thisExpr))) + autoComplete->SetDefinitionLocation(mModule->mCurTypeInstance->mTypeDef->GetRefNode()); mResultLocalVar = mModule->GetThisVariable(); - mResultFieldInstance = NULL; + mResultFieldInstance = NULL; } void BfExprEvaluator::Visit(BfBaseExpression* baseExpr) @@ -10879,7 +11342,7 @@ void BfExprEvaluator::Visit(BfBaseExpression* baseExpr) auto baseType = mModule->mCurTypeInstance->mBaseType; if (baseType == NULL) - baseType = mModule->mContext->mBfObjectType; + baseType = mModule->mContext->mBfObjectType; auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(baseExpr))) @@ -10911,7 +11374,7 @@ void BfExprEvaluator::Visit(BfMixinExpression* mixinExpr) mModule->Fail("Mixin references can only be used within mixins", mixinExpr); return; } - + int localIdx = GetMixinVariable(); if (localIdx != -1) { @@ -10942,7 +11405,7 @@ void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr) if (type == NULL) return; - if (type->IsArray()) + if (type->IsArray()) { // If we have a case like 'int[] (1, 2)' then we infer the sized array size from the initializer auto arrayType = (BfArrayType*)type; @@ -10977,9 +11440,9 @@ void BfExprEvaluator::Visit(BfSizedArrayCreateExpression* createExpr) } void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) -{ +{ uint64 unassignedFieldFlags = 0; - + if (auto typeRef = BfNodeDynCast(initExpr->mTarget)) { BfType* type = NULL; @@ -11013,7 +11476,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) } } else - VisitChild(initExpr->mTarget); + VisitChild(initExpr->mTarget); if (!mResult) mResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType); @@ -11025,8 +11488,8 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) mModule->mBfIRBuilder->SetInsertPoint(initBlock); } - BfTypedValue initValue = GetResult(true); - bool isFirstAdd = true; + BfTypedValue initValue = GetResult(true); + bool isFirstAdd = true; BfFunctionBindResult addFunctionBindResult; addFunctionBindResult.mWantsArgs = true; @@ -11076,7 +11539,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) autoComplete->SetDefinitionLocation(fieldDef->GetRefNode()); } } - + mResult = fieldResult; PerformAssignment(assignExpr, true, BfTypedValue()); mResult = BfTypedValue(); @@ -11086,7 +11549,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) mModule->Fail(StrFormat("'%s' does not contain a definition for '%s'", mModule->TypeToString(initValue.mType).c_str(), findName.c_str()), identifierNode); } - } + } } else { @@ -11104,10 +11567,10 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) } } } - + bool wasFirstAdd = isFirstAdd; if (isFirstAdd) - { + { BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mFunctionBindResult = &addFunctionBindResult; SizedArray argExprs; @@ -11162,12 +11625,12 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr) } void BfExprEvaluator::Visit(BfCollectionInitializerExpression* arrayInitExpr) -{ +{ mModule->Fail("Collection initializer not usable here", arrayInitExpr); } void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr) -{ +{ auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); auto autoComplete = GetAutoComplete(); @@ -11185,7 +11648,7 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr) { type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGlobalsSelf | BfResolveTypeRefFlag_AllowUnboundGeneric)); } - + if (type == NULL) { mResult = mModule->GetDefaultTypedValue(mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef)); @@ -11199,7 +11662,7 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr) bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName) { auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); - + BfType* type; // { @@ -11224,7 +11687,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); mModule->PopulateType(type); - auto typeInstance = type->ToTypeInstance(); + auto typeInstance = type->ToTypeInstance(); auto _BoolResult = [&](bool val) { @@ -11236,7 +11699,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie mResult = BfTypedValue(mModule->GetConstValue32(val), mModule->GetPrimitiveType(BfTypeCode_Int32)); }; - String memberName; + String memberName; propName->ToString(memberName); bool handled = true; @@ -11303,7 +11766,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie else if (memberName == "InstanceStride") _Int32Result((typeInstance != NULL) ? typeInstance->GetInstStride() : type->GetStride()); else if (memberName == "UnderlyingType") - { + { auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); if (type->IsGenericParam()) { @@ -11313,6 +11776,8 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie } else if (type->IsEnum()) { + if (type->IsDataIncomplete()) + mModule->PopulateType(type); auto underlyingType = type->GetUnderlyingType(); if (underlyingType != NULL) { @@ -11330,11 +11795,11 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie checkType = checkType->GetUnderlyingType(); if (checkType->IsGenericParam()) - { + { mResult = mModule->GetDefaultTypedValue(int32Type, false, Beefy::BfDefaultValueKind_Undef); - return true; + return true; } - + if ((typeInstance != NULL) && (typeInstance->IsEnum())) { if (typeInstance->mTypeInfoEx != NULL) @@ -11370,7 +11835,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie { bool isMin = memberName == "MinValue"; bool isBitSize = memberName == "BitSize"; - + BfType* checkType = type; if (checkType->IsTypedPrimitive()) checkType = checkType->GetUnderlyingType(); @@ -11382,7 +11847,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType); if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) || ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef)))) - foundMatch = true; + foundMatch = true; else { @@ -11431,7 +11896,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie else { switch (primType->mTypeDef->mTypeCode) - { + { case BfTypeCode_Int8: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, isMin ? -0x80 : 0x7F), primType); return true; @@ -11474,17 +11939,17 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie default: break; } } - } - + } + if (type->IsEnum()) { 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(type).c_str()), propName); } - } + } else return false; @@ -11493,7 +11958,7 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie if (mResult.mType != NULL) mResult = mModule->GetDefaultTypedValue(mResult.mType, false, Beefy::BfDefaultValueKind_Undef); } - + auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (typeOfExpr->mTypeRef != NULL)) { @@ -11504,9 +11969,9 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie } void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token) -{ +{ auto autoComplete = GetAutoComplete(); - + auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete); if (type == NULL) return; @@ -11530,7 +11995,7 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* comma } if (token == BfToken_OffsetOf) - { + { bool found = false; String findName; if (memberName != NULL) @@ -11550,7 +12015,7 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* comma { auto activeTypeDef = mModule->GetActiveTypeDef(); mModule->PopulateType(checkTypeInst); - + BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; for (auto fieldDef : checkTypeInst->mTypeDef->mFields) { @@ -11580,7 +12045,7 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* comma mModule->PopulateType(checkTypeInst); auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx]; - attrVal = fieldInst.mDataOffset; + attrVal = fieldInst.mDataOffset; found = true; break; } @@ -11610,7 +12075,7 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* comma if (isUndefVal) { // We do this so we know it's a constant but we can't assume anything about its value - // We make the value an Int32 which doesn't match the IntPtr type, but it allows us to + // We make the value an Int32 which doesn't match the IntPtr type, but it allows us to // assume it can be implicitly cased to int32 mResult = BfTypedValue(mModule->mBfIRBuilder->GetUndefConstValue(mModule->mBfIRBuilder->MapType(sizeType)), sizeType); } @@ -11634,12 +12099,142 @@ void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr) } void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr) -{ +{ DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf); } +void BfExprEvaluator::Visit(BfNameOfExpression* nameOfExpr) +{ + String name; + + if (mModule->IsInSpecializedGeneric()) + { + if (auto identifierNode = BfNodeDynCastExact(nameOfExpr->mTarget)) + { + // This is necessary so we don't resolve 'T' to the actual generic argument type + name = identifierNode->ToString(); + } + } + + if (name.IsEmpty()) + { + auto type = mModule->ResolveTypeRef(nameOfExpr->mTarget, {}, BfPopulateType_IdentityNoRemapAlias, + (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowUnboundGeneric | BfResolveTypeRefFlag_IgnoreLookupError | BfResolveTypeRefFlag_IgnoreProtection)); + if (type != NULL) + { + auto typeInst = type->ToTypeInstance(); + if (typeInst != NULL) + name = typeInst->mTypeDef->mName->ToString(); + else + name = mModule->TypeToString(type); + + mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference); + + // Just do this for autocomplete + SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + VisitChild(nameOfExpr->mTarget); + } + } + + if (name.IsEmpty()) + { + if (auto identifer = BfNodeDynCast(nameOfExpr->mTarget)) + { + String targetStr = nameOfExpr->mTarget->ToString(); + BfAtomComposite targetComposite; + bool isValid = mModule->mSystem->ParseAtomComposite(targetStr, targetComposite); + bool namespaceExists = false; + + BfProject* bfProject = NULL; + auto activeTypeDef = mModule->GetActiveTypeDef(); + if (activeTypeDef != NULL) + bfProject = activeTypeDef->mProject; + auto _CheckProject = [&](BfProject* project) + { + if ((isValid) && (project->mNamespaces.ContainsKey(targetComposite))) + namespaceExists = true; + }; + + if (bfProject != NULL) + { + for (int depIdx = -1; depIdx < (int)bfProject->mDependencies.size(); depIdx++) + { + BfProject* depProject = (depIdx == -1) ? bfProject : bfProject->mDependencies[depIdx]; + _CheckProject(depProject); + } + } + else + { + for (auto project : mModule->mSystem->mProjects) + _CheckProject(project); + } + + if (namespaceExists) + { + if (mModule->mCompiler->mResolvePassData != NULL) + { + if (auto sourceClassifier = mModule->mCompiler->mResolvePassData->GetSourceClassifier(nameOfExpr->mTarget)) + { + BfAstNode* checkIdentifier = identifer; + while (true) + { + auto qualifiedIdentifier = BfNodeDynCast(checkIdentifier); + if (qualifiedIdentifier == NULL) + break; + sourceClassifier->SetElementType(qualifiedIdentifier->mRight, BfSourceElementType_Namespace); + checkIdentifier = qualifiedIdentifier->mLeft; + } + + sourceClassifier->SetElementType(checkIdentifier, BfSourceElementType_Namespace); + } + } + + name = targetComposite.mParts[targetComposite.mSize - 1]->ToString(); + } + } + } + + if (name.IsEmpty()) + { + SetAndRestoreValue prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NameOf)); + SetAndRestoreValue prevIgnoreErrors(mModule->mBfIRBuilder->mIgnoreWrites, true); + VisitChild(nameOfExpr->mTarget); + + if ((mBfEvalExprFlags & BfEvalExprFlags_NameOfSuccess) != 0) + { + BfAstNode* nameNode = nameOfExpr->mTarget; + if (auto attributedIdentifierNode = BfNodeDynCast(nameNode)) + nameNode = attributedIdentifierNode->mIdentifier; + if (auto memberReferenceExpr = BfNodeDynCast(nameNode)) + nameNode = memberReferenceExpr->mMemberName; + if (auto qualifiedNameNode = BfNodeDynCast(nameNode)) + nameNode = qualifiedNameNode->mRight; + name = nameNode->ToString(); + } + else if (mResultFieldInstance != NULL) + { + auto fieldDef = mResultFieldInstance->GetFieldDef(); + if (fieldDef != NULL) + name = fieldDef->mName; + } + else if (mResultLocalVar != NULL) + { + name = mResultLocalVar->mName; + } + else if (mPropDef != NULL) + { + name = mPropDef->mName; + } + } + + if ((name.IsEmpty()) && (nameOfExpr->mTarget != NULL)) + mModule->Fail("Expression does not have a name", nameOfExpr->mTarget); + + mResult = BfTypedValue(mModule->GetStringObjectValue(name), mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)); +} + void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr) -{ +{ if (isConstExpr->mExpression == NULL) { mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), mModule->GetPrimitiveType(BfTypeCode_Boolean)); @@ -11656,7 +12251,7 @@ void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr) SetAndRestoreValue allowUninitReads(mModule->mCurMethodState->mAllowUinitReads, true); BfEvalExprFlags exprFlags = BfEvalExprFlags_None; - + auto result = mModule->CreateValueFromExpression(isConstExpr->mExpression, NULL, BfEvalExprFlags_DeclType); bool isConst = mModule->mBfIRBuilder->IsConstValue(result.mValue); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, isConst ? 1 : 0), mModule->GetPrimitiveType(BfTypeCode_Boolean)); @@ -11664,16 +12259,16 @@ void BfExprEvaluator::Visit(BfIsConstExpression* isConstExpr) void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr) { - auto autoComplete = GetAutoComplete(); - if (autoComplete != NULL) - autoComplete->CheckTypeRef(defaultExpr->mTypeRef, false, true); + auto autoComplete = GetAutoComplete(); + if (autoComplete != NULL) + autoComplete->CheckTypeRef(defaultExpr->mTypeRef, false, true); BfType* type = NULL; if (defaultExpr->mOpenParen == NULL) { if (mExpectingType) { - type = mExpectingType; + type = mExpectingType; } else { @@ -11684,7 +12279,7 @@ void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr) else type = mModule->ResolveTypeRef(defaultExpr->mTypeRef); if (type == NULL) - return; + return; BfDefaultValueKind defaultKind = BfDefaultValueKind_Const; if (type->IsRef()) @@ -11707,7 +12302,7 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) { auto targetValue = mModule->CreateValueFromExpression(checkTypeExpr->mTarget, NULL, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); if (!targetValue) - return; + return; if (checkTypeExpr->mTypeRef == NULL) { @@ -11715,9 +12310,9 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) return; } - auto autoComplete = GetAutoComplete(); - if (autoComplete != NULL) - autoComplete->CheckTypeRef(checkTypeExpr->mTypeRef, false, true); + auto autoComplete = GetAutoComplete(); + if (autoComplete != NULL) + autoComplete->CheckTypeRef(checkTypeExpr->mTypeRef, false, true); auto targetType = mModule->ResolveTypeRef(checkTypeExpr->mTypeRef, BfPopulateType_Declaration); if (!targetType) @@ -11734,7 +12329,7 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) mResult = mModule->GetDefaultTypedValue(boolType, false, BfDefaultValueKind_Undef); return; } - + if (targetValue.mType->IsValueTypeOrValueTypePtr()) { auto typeInstance = targetValue.mType->ToTypeInstance(); @@ -11759,21 +12354,21 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) } if (targetType->IsValueType()) - { + { if ((targetValue.mType != mModule->mContext->mBfObjectType) && (!targetValue.mType->IsInterface())) { mResult = BfTypedValue(mModule->GetConstValue(0, boolType), boolType); - return; + return; } } - + int wantTypeId = 0; if (!targetType->IsGenericParam()) wantTypeId = targetType->mTypeId; - + auto objectType = mModule->mContext->mBfObjectType; mModule->PopulateType(objectType, BfPopulateType_Full); - + targetValue = mModule->LoadValue(targetValue); BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance(); @@ -11796,7 +12391,7 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) mModule->Warn(BfWarning_BF4203_UnnecessaryDynamicCast, StrFormat("Unnecessary check, '%s' is a subtype of '%s'", mModule->TypeToString(srcTypeInstance).c_str(), mModule->TypeToString(targetType).c_str()), checkTypeExpr->mIsToken); } - + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType); return; } @@ -11815,9 +12410,9 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) auto irb = mModule->mBfIRBuilder; auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); - auto matchBB = mModule->mBfIRBuilder->CreateBlock("is.match"); + auto matchBB = mModule->mBfIRBuilder->CreateBlock("is.match"); auto endBB = mModule->mBfIRBuilder->CreateBlock("is.done"); - + BfIRValue boolResult = mModule->CreateAlloca(boolType); irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 0), boolResult, 1); @@ -11826,20 +12421,20 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr) mModule->AddBasicBlock(matchBB); irb->CreateAlignedStore(irb->CreateConst(BfTypeCode_Boolean, 1), boolResult, 1); irb->CreateBr(endBB); - - mModule->AddBasicBlock(endBB); + + mModule->AddBasicBlock(endBB); mResult = BfTypedValue(irb->CreateAlignedLoad(boolResult, 1), boolType); } void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) -{ - auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget); +{ + auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget); auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, false); - - auto autoComplete = GetAutoComplete(); - if (autoComplete != NULL) + + auto autoComplete = GetAutoComplete(); + if (autoComplete != NULL) { - autoComplete->CheckTypeRef(dynCastExpr->mTypeRef, false, true); + autoComplete->CheckTypeRef(dynCastExpr->mTypeRef, false, true); } auto origTargetType = targetType; @@ -11852,7 +12447,7 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) return; } - bool wasGenericParamType = false; + bool wasGenericParamType = false; if (targetType->IsGenericParam()) { //targetType = mModule->ResolveGenericType(targetType); @@ -11864,34 +12459,41 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) // We can never cast a MethodRef to any class type mResult = mModule->GetDefaultTypedValue(targetType); return; - } + } if (mModule->mContext->mResolvingVarField) { mResult = mModule->GetDefaultTypedValue(targetType); return; } - + mModule->AddDependency(targetType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); if (targetType->IsGenericParam()) { wasGenericParamType = true; - //wasGenericParamType = false; // "was", not "is" - auto genericParamType = (BfGenericParamType*) targetType; - auto genericParam = mModule->GetGenericParamInstance(genericParamType); - auto typeConstraint = genericParam->mTypeConstraint; - if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Interface))) - typeConstraint = mModule->mContext->mBfObjectType; - - if ((typeConstraint == NULL) || (!typeConstraint->IsObject())) + BfGenericParamInstance* origGenericParam = NULL; + int pass = 0; + while ((targetType != NULL) && (targetType->IsGenericParam())) { - mModule->Fail(StrFormat("The type parameter '%s' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' or 'interface' constraint", - genericParam->GetGenericParamDef()->mName.c_str()), dynCastExpr->mTypeRef); - return; + auto genericParamType = (BfGenericParamType*)targetType; + auto genericParam = mModule->GetGenericParamInstance(genericParamType); + if (pass == 0) + origGenericParam = genericParam; + auto typeConstraint = genericParam->mTypeConstraint; + if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Interface))) + typeConstraint = mModule->mContext->mBfObjectType; + targetType = typeConstraint; + if (++pass >= 100) // Sanity - but we should have caught circular error before + break; } - targetType = typeConstraint; + if ((targetType == NULL) || (!targetType->IsObjectOrInterface())) + { + mModule->Fail(StrFormat("The type parameter '%s' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' or 'interface' constraint", + origGenericParam->GetGenericParamDef()->mName.c_str()), dynCastExpr->mTypeRef); + return; + } } if (targetType->IsVar()) @@ -11921,7 +12523,7 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) mResult = mModule->GetDefaultTypedValue(targetType); return; } - + targetValue = mModule->GetDefaultTypedValue(typeConstraint); } @@ -11930,20 +12532,20 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) auto _CheckResult = [&]() { if ((mResult) && (origTargetType->IsGenericParam())) - mResult = mModule->GetDefaultTypedValue(origTargetType); + mResult = mModule->GetDefaultTypedValue(origTargetType, false, BfDefaultValueKind_Undef); }; if ((targetValue.mType->IsNullable()) && (targetType->IsInterface())) - { + { mResult = mModule->Cast(dynCastExpr, targetValue, targetType, BfCastFlags_SilentFail); if (!mResult) { - mModule->Warn(0, StrFormat("Conversion from '%s' to '%s' will always be null", + mModule->Warn(0, StrFormat("Conversion from '%s' to '%s' will always be null", mModule->TypeToString(targetValue.mType).c_str(), mModule->TypeToString(origTargetType).c_str()), dynCastExpr->mAsToken); mResult = BfTypedValue(mModule->GetDefaultValue(origTargetType), origTargetType); - } + } _CheckResult(); - return; + return; } if (targetValue.mType->IsVar()) @@ -11960,7 +12562,7 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) auto typeInstance = targetValue.mType->ToTypeInstance(); if (targetValue.mType->IsWrappableType()) typeInstance = mModule->GetWrappedStructType(targetValue.mType); - + bool matches = (targetValue.mType == targetType) || (mModule->mContext->mBfObjectType == targetType); if (targetType->IsNullable()) @@ -11969,7 +12571,7 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) if (elementType == targetValue.mType) { // We match nullable element - auto allocaInst = mModule->CreateAlloca(targetType); + auto allocaInst = mModule->CreateAlloca(targetType); auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 1); // has_value mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(1, boolType), hasValueAddr); hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, 0); // value @@ -11989,8 +12591,8 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) { auto allocaInst = mModule->CreateAlloca(targetType); auto allocaBits = mModule->mBfIRBuilder->CreateBitCast(allocaInst, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr)); - mModule->mBfIRBuilder->CreateMemSet(allocaBits, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)), - mModule->GetConstValue(targetType->mSize), targetType->mAlign); + mModule->mBfIRBuilder->CreateMemSet(allocaBits, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)), + mModule->GetConstValue(targetType->mSize), targetType->mAlign); mResult = BfTypedValue(allocaInst, targetType, true); } else @@ -12000,22 +12602,22 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) } if (targetType->IsNullable()) - { - if (autoComplete != NULL) + { + if (autoComplete != NULL) { mResult = mModule->GetDefaultTypedValue(targetType); return; } auto elementType = targetType->GetUnderlyingType(); - auto allocaInst = mModule->CreateAlloca(targetType); + auto allocaInst = mModule->CreateAlloca(targetType); auto hasValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, elementType->IsValuelessType() ? 1 : 2); // has_value mModule->mBfIRBuilder->CreateStore(mModule->GetConstValue(0, boolType), hasValueAddr); auto objectType = mModule->mContext->mBfObjectType; - auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); - auto matchBB = mModule->mBfIRBuilder->CreateBlock("as.match"); + auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); + auto matchBB = mModule->mBfIRBuilder->CreateBlock("as.match"); auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end"); mModule->EmitDynamicCastCheck(targetValue, elementType, matchBB, endBB); @@ -12037,23 +12639,23 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) auto boxedValueAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(srcBoxedType, 0, 1); // mValue auto boxedValue = mModule->mBfIRBuilder->CreateLoad(boxedValueAddr); mModule->mBfIRBuilder->CreateStore(boxedValue, nullableValueAddr); - } + } mModule->mBfIRBuilder->CreateBr(endBB); - + mModule->AddBasicBlock(endBB); mResult = BfTypedValue(allocaInst, targetType, true); _CheckResult(); return; } - targetValue = mModule->LoadValue(targetValue); + targetValue = mModule->LoadValue(targetValue); if (targetType->IsValueType()) - { + { mModule->Fail("Invalid dynamic cast type", dynCastExpr->mTypeRef); return; } - + BfTypeInstance* srcTypeInstance = targetValue.mType->ToTypeInstance(); BfTypeInstance* targetTypeInstance = targetType->ToTypeInstance(); @@ -12096,16 +12698,16 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) } auto irb = mModule->mBfIRBuilder; - auto objectType = mModule->mContext->mBfObjectType; + auto objectType = mModule->mContext->mBfObjectType; mModule->PopulateType(objectType, BfPopulateType_Full); - auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); + auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); auto endBB = mModule->mBfIRBuilder->CreateBlock("as.end"); auto matchBlock = irb->CreateBlock("as.match"); BfIRValue targetVal = mModule->CreateAlloca(targetType); irb->CreateAlignedStore(irb->CreateConstNull(irb->MapType(targetType)), targetVal, targetType->mAlign); - + mModule->EmitDynamicCastCheck(targetValue, targetType, matchBlock, endBB); mModule->AddBasicBlock(matchBlock); @@ -12113,7 +12715,7 @@ void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr) irb->CreateAlignedStore(castedCallResult, targetVal, targetValue.mType->mAlign); irb->CreateBr(endBB); - mModule->AddBasicBlock(endBB); + mModule->AddBasicBlock(endBB); mResult = BfTypedValue(irb->CreateAlignedLoad(targetVal, targetType->mAlign), targetType); _CheckResult(); } @@ -12128,7 +12730,7 @@ void BfExprEvaluator::Visit(BfCastExpression* castExpr) } BfType* resolvedType = NULL; - + if ((BfNodeDynCastExact(castExpr->mTypeRef) != NULL) && (mExpectingType != NULL)) { //mModule->SetElementType(castExpr->mTypeRef, BfSourceElementType_TypeRef); @@ -12151,9 +12753,9 @@ void BfExprEvaluator::Visit(BfCastExpression* castExpr) } bool BfExprEvaluator::IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams) -{ +{ if (methodA->mReturnType != methodB->mReturnType) - return false; + return false; int implicitParamCountA = methodA->GetImplicitParamCount(); if (methodA->HasExplicitThis()) implicitParamCountA++; @@ -12181,7 +12783,7 @@ void BfExprEvaluator::ConstResolve(BfExpression* expr) } BfTypeInstance* BfExprEvaluator::VerifyBaseDelegateType(BfTypeInstance* baseDelegateType) -{ +{ mModule->PopulateType(baseDelegateType, BfPopulateType_DataAndMethods); if (baseDelegateType->mFieldInstances.size() != 2) { @@ -12197,17 +12799,17 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr { return false; } - + bool isGenericMatch = mExpectingType == NULL; auto expectingType = mExpectingType; if (expectingType == NULL) expectingType = origMethodExpectingType; auto typeInstance = expectingType->ToTypeInstance(); - if ((typeInstance == NULL) || + if ((typeInstance == NULL) || ((!typeInstance->mTypeDef->mIsDelegate) && (!typeInstance->mTypeDef->mIsFunction))) return false; - + mModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods); auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInstance, 0, "Invoke"); @@ -12218,8 +12820,8 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr } if (delegateBindExpr->mTarget == NULL) - return false; - + return false; + BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr); SizedArray typedValueExprs; typedValueExprs.resize(methodInstance->GetParamCount()); @@ -12230,24 +12832,24 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr auto _FixType = [&](BfType* type) { if (!isGenericMatch) - return type; + return type; auto fixedType = mModule->ResolveGenericType(type, NULL, methodGenericArgumentsSubstitute, mModule->mCurTypeInstance); if (fixedType != NULL) return fixedType; - return (BfType*)mModule->GetPrimitiveType(BfTypeCode_Var); + return (BfType*)mModule->GetPrimitiveType(BfTypeCode_Var); }; auto _TypeMatches = [&](BfType* lhs, BfType* rhs) { if (lhs == rhs) return true; - return lhs->IsVar(); + return lhs->IsVar(); }; for (int i = 0; i < (int) methodInstance->GetParamCount(); i++) { auto typedValueExpr = &typedValueExprs[i]; - typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1); + typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1); typedValueExpr->mTypedValue.mType = _FixType(methodInstance->GetParamType(i)); typedValueExpr->mRefNode = NULL; args[i] = typedValueExpr; @@ -12256,7 +12858,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr BfMethodGenericArguments methodGenericArgs; if (delegateBindExpr->mGenericArgs != NULL) methodGenericArgs.mArguments = &delegateBindExpr->mGenericArgs->mGenericArgs; - + BfFunctionBindResult bindResult; bindResult.mSkipMutCheck = true; // Allow operating on copies bindResult.mBindType = expectingType; @@ -12265,7 +12867,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs); mFunctionBindResult = NULL; if (bindResult.mMethodInstance == NULL) - return false; + return false; if (boundMethod != NULL) *boundMethod = bindResult.mMethodInstance; @@ -12292,7 +12894,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx) { String findName = identifierNode->ToString(); - + if (mModule->mCurMethodState != NULL) { auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); @@ -12310,13 +12912,12 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentif BfClosureInstanceInfo* closureInstanceInfo = NULL; if ((checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mClosureType != NULL) && (!checkMethodState->mClosureState->mCapturing)) { - closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType; + closureTypeInst = mModule->mCurMethodState->mClosureState->mClosureType; } - + BfLocalVarEntry* entry; if (checkMethodState->mLocalVarSet.TryGetWith(findName, &entry)) { - auto varDecl = entry->mLocalVar; while (varDecl != NULL) @@ -12342,12 +12943,11 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfIdentif varDecl = varDecl->mShadowedLocal; } - } - + // Check for the captured locals. It's important we do it here so we get local-first precedence still if (closureTypeInst != NULL) - { + { closureTypeInst->mTypeDef->PopulateMemberSets(); BfMemberSetEntry* memberSetEntry = NULL; if (closureTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry)) @@ -12428,7 +13028,7 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodI BfMethodInstance* methodRefMethodInst = methodRefType->mMethodRef; BF_ASSERT(methodRefMethodInst == methodInstance); - + auto paramType = methodInstance->GetParamType(paramIdx); int dataIdx = methodRefType->GetDataIdxFromParamIdx(paramIdx); @@ -12466,11 +13066,11 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodI if ((isAddr) && (!lookupVal.mType->IsComposite())) lookupVal = mModule->LoadValue(lookupVal); return lookupVal; - } + } } if ((paramType->IsComposite()) && (methodRefTarget.IsAddr())) return BfTypedValue(mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefTarget.mValue, 0, dataIdx), paramType, true); - return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType); + return BfTypedValue(mModule->ExtractValue(methodRefTarget, dataIdx), paramType); } } @@ -12491,9 +13091,9 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodI else if (auto identifierNode = BfNodeDynCast(delegateBindExpr->mTarget)) { // Implicit - thisValue = mModule->GetThis(); + thisValue = mModule->GetThis(); } - + if (auto thisExpr = BfNodeDynCast(thisNode)) { thisValue = mModule->CreateValueFromExpression(thisExpr); @@ -12518,9 +13118,9 @@ BfTypedValue BfExprEvaluator::DoImplicitArgCapture(BfAstNode* refNode, BfMethodI lookupVal = DoImplicitArgCapture(refNode, identifierNode, 0); } else - { + { lookupVal = LookupIdentifier(NULL, captureName); - } + } if (lookupVal) { auto paramType = methodInstance->GetParamType(paramIdx); @@ -12576,11 +13176,11 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) BfAutoParentNodeEntry autoParentNodeEntry(mModule, delegateBindExpr); if (mExpectingType == NULL) - { + { mModule->Fail("Cannot infer delegate type", delegateBindExpr); return; } - + BfTokenNode* newToken = NULL; BfAllocTarget allocTarget; ResolveAllocTarget(allocTarget, delegateBindExpr->mNewToken, newToken); @@ -12590,7 +13190,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) BfTypeInstance* delegateTypeInstance = NULL; BfMethodInstance* methodInstance = NULL; - + const char* bindTypeName = NULL; bool isMethodRefMatch = false; if (mExpectingType->IsMethodRef()) @@ -12614,7 +13214,6 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) else delegateTypeInstance = mExpectingType->ToTypeInstance(); - if ((delegateTypeInstance == NULL) || ((!delegateTypeInstance->IsDelegate()) && (!delegateTypeInstance->IsFunction()))) { @@ -12643,11 +13242,11 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } } } - + int paramOffset = methodInstance->HasExplicitThis() ? 1 : 0; - typedValueExprs.resize(methodInstance->GetParamCount() - paramOffset); + typedValueExprs.resize(methodInstance->GetParamCount() - paramOffset); args.resize(methodInstance->GetParamCount() - paramOffset); - + for (int i = 0; i < (int)methodInstance->GetParamCount() - paramOffset; i++) { auto typedValueExpr = &typedValueExprs[i]; @@ -12676,10 +13275,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if ((!delegateBindExpr->mTarget->IsA()) && (!delegateBindExpr->mTarget->IsA())) - { - mModule->Fail(StrFormat("Invalid %s binding target, %s can only bind to method references. Consider wrapping expression in a lambda.", bindTypeName, bindTypeName), delegateBindExpr->mTarget); + { + mModule->Fail(StrFormat("Invalid %s binding target, %s can only bind to method references. Consider wrapping expression in a lambda.", bindTypeName, bindTypeName), delegateBindExpr->mTarget); mModule->CreateValueFromExpression(delegateBindExpr->mTarget); - return; + return; } BfFunctionBindResult bindResult; @@ -12691,8 +13290,8 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) mFunctionBindResult = &bindResult; DoInvocation(delegateBindExpr->mTarget, delegateBindExpr, args, methodGenericArgs); mFunctionBindResult = NULL; - } - + } + SetMethodElementType(delegateBindExpr->mTarget); if (bindResult.mMethodInstance == NULL) @@ -12727,7 +13326,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget); } else - { + { mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType | BfMethodNameFlag_IncludeMut)).c_str(), bindTypeName, mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget); } @@ -12742,18 +13341,18 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (bindMethodInstance->mIsIntrinsic) { - mModule->Fail(StrFormat("Method '%s' is an intrinsic and therefore cannot be used as a method binding target. Intrinsics have no addresses.", mModule->MethodToString(bindMethodInstance).c_str()), delegateBindExpr->mTarget); + mModule->Fail(StrFormat("Method '%s' is an intrinsic and therefore cannot be used as a method binding target. Intrinsics have no addresses.", mModule->MethodToString(bindMethodInstance).c_str()), delegateBindExpr->mTarget); mResult = BfTypedValue(); return; } bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mCallingConvention, bindMethodInstance->mCallingConvention); - + auto _GetInvokeMethodName = [&]() { StringT<512> methodName = "Invoke$"; methodName += mModule->mCurMethodInstance->mMethodDef->mName; - + int prevSepPos = (int)methodName.LastIndexOf('$'); if (prevSepPos > 6) { @@ -12763,7 +13362,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); HashContext hashCtx; - if (mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx != -1) + if (mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx != -1) hashCtx.Mixin(mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mPartialIdx); if (delegateBindExpr->mFatArrowToken != NULL) @@ -12808,7 +13407,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) return; } } - + if (mExpectingType->IsFunction()) { BfIRValue result; @@ -12822,7 +13421,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (result) { - String methodName = _GetInvokeMethodName(); + String methodName = _GetInvokeMethodName(); SizedArray irParamTypes; BfIRType irReturnType; @@ -12870,16 +13469,16 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) result = mModule->mBfIRBuilder->CreatePtrToInt(funcValue, BfTypeCode_IntPtr); } } - else - { + else + { if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsGenericParam()) && (bindResult.mMethodInstance->GetOwner()->IsInterface())) { bool matching = true; if (methodInstance->HasExplicitThis()) { auto thisType = methodInstance->GetParamType(0); - - if (thisType->IsPointer()) + + if (thisType->IsPointer()) thisType = thisType->GetUnderlyingType(); if (thisType->IsRef()) thisType = thisType->GetUnderlyingType(); @@ -12894,7 +13493,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } } result = mModule->CastToFunction(delegateBindExpr->mTarget, bindResult.mOrigTarget, bindResult.mMethodInstance, mExpectingType, BfCastFlags_None, bindResult.mFunc); - } + } if (result) mResult = BfTypedValue(result, mExpectingType); return; @@ -12922,7 +13521,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) { auto methodRefPtr = mModule->CreateAlloca(methodRefType, "bindResult"); auto elemPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(methodRefPtr, 0, 0); - + BfTypedValue target; if (bindResult.mTarget.IsSplat()) target = mModule->AggregateSplat(bindResult.mTarget, &bindResult.mIRArgs[0]); @@ -12930,21 +13529,21 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) target = bindResult.mTarget; mModule->mBfIRBuilder->CreateStore(target.mValue, elemPtr); - + mResult = BfTypedValue(methodRefPtr, methodRefType, true); } } return; } - + int implicitParamCount = bindMethodInstance->GetImplicitParamCount(); - + BfTypeInstance* useTypeInstance = delegateTypeInstance; BfClosureType* closureTypeInst = NULL; - + auto origTarget = bindResult.mOrigTarget; auto target = bindResult.mTarget; - + BfTypedValue methodRefTarget; if ((bindResult.mOrigTarget) && (bindResult.mOrigTarget.mType->IsMethodRef())) methodRefTarget = bindResult.mOrigTarget; @@ -12952,7 +13551,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) bool isStructTarget = (target) && (target.mType->IsStruct()); bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget; bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting(-1)); - bool captureThisByValue = isStructTarget; + bool captureThisByValue = isStructTarget; if (bindMethodInstance->mMethodDef->mIsLocalMethod) { // Local method captures always capture 'this' by reference @@ -12970,7 +13569,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (target.IsSplat()) target = mModule->AggregateSplat(target, &bindResult.mIRArgs[0]); - + bool hasCaptures = false; // Do we need a special delegate type for this? @@ -12989,14 +13588,14 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) // We mix in the project for reasons described in the lambda binding handler hashCtx.MixinStr(curProject->mName); - + String structTargetTypeName; String structTargetName; - - // Implicit param separator + + // Implicit param separator for (int implicitParamIdx = bindMethodInstance->HasThis() ? - 1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++) { - auto paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx); + auto paramType = bindResult.mMethodInstance->GetParamType(implicitParamIdx); if ((implicitParamIdx == -1) && (captureThisByValue)) { if (paramType->IsPointer()) @@ -13010,14 +13609,14 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) Val128 hash128 = hashCtx.Finish128(); BfClosureType* checkClosureType = new BfClosureType(delegateTypeInstance, hash128); - checkClosureType->mContext = mModule->mContext; + checkClosureType->mContext = mModule->mContext; checkClosureType->mBaseType = delegateTypeInstance; BfType* resolvedClosureType = mModule->ResolveType(checkClosureType, BfPopulateType_TypeDef); closureTypeInst = (BfClosureType*)resolvedClosureType; if (checkClosureType == resolvedClosureType) - { + { // This is a new closure type - closureTypeInst->Init(curProject); + closureTypeInst->Init(curProject); for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++) { String fieldName = bindResult.mMethodInstance->GetParamName(implicitParamIdx); @@ -13044,7 +13643,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) useTypeInstance = closureTypeInst; } mModule->PopulateType(useTypeInstance); - + if (delegateBindExpr->mTarget == NULL) { mModule->AssertErrorState(); @@ -13052,10 +13651,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance); - + // Do we need specialized calling code for this? BfIRValue funcValue; - if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) && + if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) && (mModule->HasExecutedOutput())) { int fieldIdx = 0; @@ -13071,7 +13670,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (fieldType->IsPointer()) fieldType = fieldType->GetUnderlyingType(); } - + bool failed = false; BfTypedValue lookupVal; if (implicitParamIdx == -1) @@ -13083,7 +13682,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if ((fieldType->IsPointer()) && (lookupVal.mType != fieldType)) { BF_ASSERT(fieldType->GetUnderlyingType() == lookupVal.mType); - BF_ASSERT(lookupVal.IsAddr()); + BF_ASSERT(lookupVal.IsAddr()); } else if (!fieldType->IsRef()) lookupVal = mModule->LoadOrAggregateValue(lookupVal); @@ -13102,7 +13701,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (hasCaptures) { hasThis = true; - methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes); + methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes); int thisIdx = 0; if (GetStructRetIdx(methodInstance) == 0) thisIdx = 1; @@ -13114,7 +13713,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes); hasThis = bindMethodInstance->HasThis(); } - + auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction(); auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock(); mModule->mBfIRBuilder->SaveDebugLocation(); @@ -13123,7 +13722,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName); if (GetStructRetIdx(methodInstance) != -1) - { + { mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_NoAlias); mModule->mBfIRBuilder->Func_AddAttribute(funcValue, GetStructRetIdx(methodInstance) + 1, BfIRAttribute_StructRet); } @@ -13134,7 +13733,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) else if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall) srcCallingConv = BfIRCallingConv_FastCall; mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv); - + mModule->mBfIRBuilder->SetActiveFunction(funcValue); auto entryBlock = mModule->mBfIRBuilder->CreateBlock("entry", true); mModule->mBfIRBuilder->SetInsertPoint(entryBlock); @@ -13148,7 +13747,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance))); argIdx++; } - + for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++) { auto fieldInst = &useTypeInstance->mFieldInstances[fieldIdx]; @@ -13163,7 +13762,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) disableSplat = true; } } - + int thisIdx = 0; if (GetStructRetIdx(methodInstance) == 0) thisIdx = 1; @@ -13175,7 +13774,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) if (hasThis) argIdx++; - + if (GetStructRetIdx(bindMethodInstance) == 1) { irArgs.push_back(mModule->mBfIRBuilder->GetArgument(GetStructRetIdx(methodInstance))); @@ -13220,17 +13819,17 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) else if ((closureTypeInst != NULL) && (captureThisByValue)) { // When we need to aggregrate a splat for a target, we just point out delegate's mTarget to inside ourselves where we aggregated the value - auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, 1); + auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, 1); target = mModule->LoadValue(target); mModule->mBfIRBuilder->CreateStore(target.mValue, fieldPtr); target = BfTypedValue(fieldPtr, target.mType, true); } - + BfResolvedArgs resolvedArgs; MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, false); - auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType); - auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full)); + auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType); + auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full)); // >> delegate.mTarget = bindResult.mTarget BfIRValue valPtr; @@ -13245,7 +13844,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, 2); mModule->mBfIRBuilder->CreateStore(valPtr, fieldPtr); } - + if (!funcValue) { funcValue = bindResult.mFunc; @@ -13271,34 +13870,34 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) } void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor) -{ +{ if (auto blockBody = BfNodeDynCast(body)) mModule->VisitChild(blockBody); else if (auto bodyExpr = BfNodeDynCast(body)) - { + { auto result = mModule->CreateValueFromExpression(bodyExpr); if ((result) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mReturnTypeInferState == BfReturnTypeInferState_Inferring)) - mModule->mCurMethodState->mClosureState->mReturnType = result.mType; + mModule->mCurMethodState->mClosureState->mReturnType = result.mType; } - + while (fieldDtor != NULL) { mModule->mCurMethodState->mLeftBlockUncond = false; mModule->VisitChild(fieldDtor->mBody); - fieldDtor = fieldDtor->mNextFieldDtor; + fieldDtor = fieldDtor->mNextFieldDtor; } } BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget) -{ +{ if (mModule->mCurMethodState == NULL) return NULL; - auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); + auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); BfAstNodeList cacheNodeList; cacheNodeList.mList.Add(lambdaBindExpr); - + /// { auto checkMethodState = mModule->mCurMethodState; @@ -13314,13 +13913,13 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam BfLambdaInstance* lambdaInstance = NULL; if ((!isInferReturnType) && (rootMethodState->mLambdaCache.TryGetValue(cacheNodeList, &lambdaInstance))) - return lambdaInstance; - + return lambdaInstance; + static int sBindCount = 0; - sBindCount++; + sBindCount++; bool isFunctionBind = false; - + BfTypeInstance* delegateTypeInstance = NULL; BfMethodInstance* invokeMethodInstance = NULL; if (mExpectingType == NULL) @@ -13387,12 +13986,12 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam autoComplete->CheckInvocation(lambdaBindExpr, lambdaBindExpr->mOpenParen, lambdaBindExpr->mCloseParen, lambdaBindExpr->mCommas); if (autoComplete->mIsCapturingMethodMatchInfo) - { + { autoComplete->mMethodMatchInfo->mInstanceList.Clear(); auto methodMatchInfo = autoComplete->mMethodMatchInfo; - BfAutoComplete::MethodMatchEntry methodMatchEntry; + BfAutoComplete::MethodMatchEntry methodMatchEntry; methodMatchEntry.mTypeInstance = invokeMethodInstance->GetOwner(); methodMatchEntry.mCurMethodInstance = mModule->mCurMethodInstance; methodMatchEntry.mMethodDef = invokeMethodInstance->mMethodDef; @@ -13403,7 +14002,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam int cursorIdx = lambdaBindExpr->GetParser()->mCursorIdx; if ((lambdaBindExpr->mCloseParen == NULL) || (cursorIdx <= lambdaBindExpr->mCloseParen->GetSrcStart())) - { + { int paramIdx = 0; for (int commaIdx = 0; commaIdx < (int)lambdaBindExpr->mCommas.size(); commaIdx++) { @@ -13411,16 +14010,16 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam if ((commaNode != NULL) && (cursorIdx >= commaNode->GetSrcStart())) paramIdx = commaIdx + 1; } - + bool isEmpty = true; - + if (paramIdx < (int)lambdaBindExpr->mParams.size()) { auto paramNode = lambdaBindExpr->mParams[paramIdx]; if (paramNode != NULL) isEmpty = false; } - + if (isEmpty) { if (paramIdx < (int)invokeMethodInstance->GetParamCount()) @@ -13433,13 +14032,13 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam autoComplete->mInsertStartIdx = cursorIdx; autoComplete->mInsertEndIdx = cursorIdx; - if ((paramIdx == 0) && (lambdaBindExpr->mParams.IsEmpty())) + if ((paramIdx == 0) && (lambdaBindExpr->mParams.IsEmpty())) { String totalNames; for (int checkIdx = 0; checkIdx < (int)invokeMethodInstance->GetParamCount(); checkIdx++) { if (!totalNames.IsEmpty()) - totalNames += ", "; + totalNames += ", "; String paramName = invokeMethodInstance->GetParamName(checkIdx); if (paramName.IsEmpty()) paramName += StrFormat("val%d", checkIdx + 1); @@ -13459,7 +14058,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam if (autoComplete != NULL) autoComplete->mIsCapturingMethodMatchInfo = (wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo) && (autoComplete->mMethodMatchInfo != NULL); } - ); + ); if (lambdaBindExpr->mBody == NULL) { @@ -13476,7 +14075,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam if ((mModule->mCurMethodState != NULL) && (mModule->mCurMethodState->mClosureState != NULL) && (mModule->mCurMethodState->mClosureState->mCapturing)) { SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); - VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor); + VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor); } if ((lambdaBindExpr->mNewToken != NULL) && (isFunctionBind)) @@ -13518,7 +14117,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } auto methodRefType = mModule->CreateMethodRefType(moduleMethodInstance.mMethodInstance); - mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls); + mModule->AddDependency(methodRefType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls); mModule->AddCallDependency(moduleMethodInstance.mMethodInstance); mResult = BfTypedValue(BfIRValue(BfIRValueFlags_Value, BfIRValue::ID_IMPLICIT), methodRefType); @@ -13562,7 +14161,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam methodState.mCurScope->mDIScope = prevMethodState.mPrevVal->mCurScope->mDIScope;//invokeMethodInstance->mDIFunction; methodState.mCurLocalVarId = -1; - + methodState.mIRFunction = prevMethodState.mPrevVal->mIRFunction; methodState.mDeferredLocalAssignData = &deferredLocalAssignData; @@ -13600,7 +14199,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam BfSource* bfSource = delegateTypeInstance->mTypeDef->mSource; BfMethodDef* methodDef = new BfMethodDef(); methodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType; - Val128 closureMethodHash; + Val128 closureMethodHash; OwnedVector tempParamDecls; if ((autoComplete != NULL) && (autoComplete->mMethodMatchInfo != NULL) && (autoComplete->IsAutocompleteNode(lambdaBindExpr->mBody))) @@ -13661,7 +14260,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam /// auto varMethodState = methodState.mPrevMethodState; - bool hasExplicitCaptureNames = false; + bool hasExplicitCaptureNames = false; for (auto& captureEntry : allocTarget.mCaptureInfo->mCaptures) { @@ -13670,8 +14269,8 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam hasExplicitCaptureNames = false; break; } - - hasExplicitCaptureNames = true; + + hasExplicitCaptureNames = true; } auto _SetNotCapturedFlag = [&](bool notCaptured) @@ -13725,11 +14324,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam localVar->mNotCaptured = false; localVar = localVar->mShadowedLocal; - } + } } } } - + varMethodState = varMethodState->mPrevMethodState; if (varMethodState == NULL) break; @@ -13742,14 +14341,14 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } } } - + BfClosureInstanceInfo* closureInstanceInfo = new BfClosureInstanceInfo(); auto checkInsertBlock = mModule->mBfIRBuilder->GetInsertBlock(); closureState.mCaptureStartAccessId = methodState.mPrevMethodState->GetRootMethodState()->mCurAccessId; closureState.mCaptureVisitingBody = true; closureState.mClosureInstanceInfo = closureInstanceInfo; - + if ((mBfEvalExprFlags & BfEvalExprFlags_InferReturnType) != 0) { closureState.mReturnType = NULL; @@ -13757,8 +14356,8 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } VisitLambdaBodies(lambdaBindExpr->mBody, lambdaBindExpr->mDtor); - - if (hasExplicitCaptureNames) + + if (hasExplicitCaptureNames) _SetNotCapturedFlag(false); // If we ended up being called by a method with a lower captureStartAccessId, propagate that to whoever is calling us, too... @@ -13781,7 +14380,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam { mResult = BfTypedValue(closureState.mReturnType); } - + earlyExit = true; } else if (mModule->mCurMethodInstance->mIsUnspecialized) @@ -13794,19 +14393,19 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam { prevIgnoreWrites.Restore(); mModule->mBfIRBuilder->RestoreDebugLocation(); - + mModule->mBfIRBuilder->SetActiveFunction(prevActiveFunction); if (!prevInsertBlock.IsFake()) mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); delete methodDef; delete closureInstanceInfo; return NULL; - } + } closureState.mCaptureVisitingBody = false; - + prevIgnoreWrites.Restore(); - mModule->mBfIRBuilder->RestoreDebugLocation(); + mModule->mBfIRBuilder->RestoreDebugLocation(); auto _GetCaptureType = [&](const StringImpl& str) { @@ -13885,10 +14484,10 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } if (captureByRef) - { + { capturedType = mModule->CreateRefType(capturedType); } - + if (captureType == BfCaptureType_Reference) capturedEntry.mExplicitlyByReference = true; capturedEntry.mType = capturedType; @@ -13898,7 +14497,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam else { capturedEntry.mName = outerLocal->mName; - + BfLocalVarEntry* entry = NULL; if (varMethodState->mLocalVarSet.TryGetWith(capturedEntry.mName, &entry)) { @@ -13909,7 +14508,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam while (checkVar != NULL) { if (checkVar == outerLocal) - { + { // We only use mShadowIdx when we have duplicate name nodes (ie: in the case of for looks with iterator vs value) auto shadowCheckVar = startCheckVar; while (shadowCheckVar != checkVar) @@ -13930,7 +14529,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam checkVar = checkVar->mShadowedLocal; } } - } + } capturedEntries.Add(capturedEntry); } } @@ -13962,7 +14561,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam auto captureType = _GetCaptureType(fieldDef->mName); BfClosureCapturedEntry capturedEntry; - capturedEntry.mName = fieldDef->mName; + capturedEntry.mName = fieldDef->mName; capturedEntry.mType = copyField->mResolvedType; if ((captureType == BfCaptureType_Reference) && (capturedEntry.mType->IsRef())) { @@ -13976,7 +14575,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam else if ((captureType == BfCaptureType_Reference) && (!capturedEntry.mType->IsRef()) && (!fieldDef->mIsReadOnly)) { capturedEntry.mType = mModule->CreateRefType(capturedEntry.mType); - } + } } std::sort(capturedEntries.begin(), capturedEntries.end()); @@ -14003,8 +14602,8 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject; BF_ASSERT(curProject != NULL); - // We need to make these per-project even though you'd think we might not because we - // insert generic type specializations in the generic definition's project, + // We need to make these per-project even though you'd think we might not because we + // insert generic type specializations in the generic definition's project, // BECAUSE: we would need to scan the captured fields the same way we scan the // generic arguments to determine if each project can see it or not in the vdata @@ -14027,7 +14626,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam hashCtx.MixinStr(capturedEntry.mName); hashCtx.Mixin(capturedEntry.mExplicitlyByReference); } - + if (lambdaBindExpr->mDtor != NULL) { // Has DTOR thunk @@ -14094,12 +14693,11 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam mModule->mBfIRBuilder->PopulateType(useTypeInstance); mModule->PopulateType(useTypeInstance); - methodDef->mIsStatic = closureTypeInst == NULL; - + SizedArray origParamTypes; BfIRType origReturnType; - + bool forceStatic = false; if (invokeMethodInstance != NULL) { @@ -14112,7 +14710,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam origReturnType = mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_None)); } - SizedArray newTypes; + SizedArray newTypes; if ((invokeMethodInstance != NULL) && (GetStructRetIdx(invokeMethodInstance, forceStatic) == 0)) newTypes.push_back(origParamTypes[0]); @@ -14137,7 +14735,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); // Just a check - mModule->mBfIRBuilder->GetInsertBlock(); + mModule->mBfIRBuilder->GetInsertBlock(); //auto rootMethodState = mModule->mCurMethodState; @@ -14179,7 +14777,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam } } checkMethodState = checkMethodState->mPrevMethodState; - } + } uint64 closureHash = closureHashCtx.Finish64(); methodDef->mName += "$"; @@ -14206,7 +14804,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(methodInstance->mHotMethod); methodState.Reset(); - + lambdaInstance = new BfLambdaInstance(); rootMethodState->mLambdaCache[cacheNodeList] = lambdaInstance; lambdaInstance->mDelegateTypeInstance = delegateTypeInstance; @@ -14216,10 +14814,10 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam lambdaInstance->mCopyOuterCaptures = copyOuterCaptures; lambdaInstance->mDeclaringMethodIsMutating = mModule->mCurMethodInstance->mMethodDef->mIsMutating; lambdaInstance->mIsStatic = methodDef->mIsStatic; - lambdaInstance->mClosureFunc = closureFunc; + lambdaInstance->mClosureFunc = closureFunc; lambdaInstance->mMethodInstance = methodInstance; lambdaInstance->mConstLocals = closureState.mConstLocals; - lambdaInstance->mParamDecls = tempParamDecls; + lambdaInstance->mParamDecls = tempParamDecls; lambdaInstance->mDeclMixinState = mModule->mCurMethodState->mMixinState; if (lambdaInstance->mDeclMixinState != NULL) lambdaInstance->mDeclMixinState->mHasDeferredUsage = true; @@ -14241,7 +14839,6 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam mModule->mBfIRBuilder->SaveDebugLocation(); // { - BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None; if (mModule->mCompiler->mResolvePassData != NULL) { @@ -14275,12 +14872,12 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam dtorMethodDef->mDeclaringType = mModule->mCurMethodInstance->mMethodDef->mDeclaringType; dtorMethodDef->mName = "~this$"; dtorMethodDef->mName += methodDef->mName; - + dtorMethodDef->mMethodType = BfMethodType_Normal; dtorMethodDef->mBody = lambdaBindExpr->mDtor; dtorMethodDef->mIdx = mModule->mCurMethodInstance->mMethodDef->mIdx; - BfMethodInstance* dtorMethodInstance = new BfMethodInstance(); + BfMethodInstance* dtorMethodInstance = new BfMethodInstance(); dtorMethodInstance->mMethodDef = dtorMethodDef; dtorMethodInstance->mReturnType = mModule->GetPrimitiveType(BfTypeCode_None); dtorMethodInstance->mMethodInstanceGroup = &methodInstanceGroup; @@ -14303,20 +14900,20 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam mModule->mBfIRBuilder->RestoreDebugLocation(); if (mModule->IsSkippingExtraResolveChecks()) dtorFunc = BfIRFunction(); - + if (dtorMethodInstance->mIsReified) mModule->CheckHotMethod(dtorMethodInstance, dtorMangledName); if ((dtorMethodInstance->mHotMethod != NULL) && (mModule->mCurMethodState->mHotDataReferenceBuilder)) mModule->mCurMethodState->mHotDataReferenceBuilder->mInnerMethods.Add(dtorMethodInstance->mHotMethod); lambdaInstance->mDtorMethodInstance = dtorMethodInstance; lambdaInstance->mDtorFunc = dtorFunc; - + dtorMethodInstance->mMethodInstanceGroup = NULL; } prevClosureState.Restore(); if ((prevInsertBlock) && (!prevInsertBlock.IsFake())) - mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); + mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock); for (auto& capturedEntry : capturedEntries) { @@ -14333,7 +14930,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam if (processMethods) rootMethodState->mDeferredLambdaInstances.Add(lambdaInstance); - methodInstance->mMethodInstanceGroup = NULL; + methodInstance->mMethodInstanceGroup = NULL; return lambdaInstance; } @@ -14368,7 +14965,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) BfTypeInstance* closureTypeInst = lambdaInstance->mClosureTypeInstance; mResult = BfTypedValue(mModule->AllocFromType(useTypeInstance, allocTarget, BfIRValue(), BfIRValue(), 0, BfAllocFlags_None), useTypeInstance); - + if (!delegateTypeInstance->IsDelegate()) { mModule->AssertErrorState(); @@ -14391,7 +14988,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr); BfIRValue valPtr; if (!lambdaInstance->mIsStatic) - valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType)); + valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(nullPtrType)); else valPtr = mModule->GetDefaultValue(nullPtrType); auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, targetField.mDataIdx); @@ -14400,19 +14997,19 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) // >> delegate.mFuncPtr = bindResult.mFunc if (lambdaInstance->mClosureFunc) { - auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr); + auto nullPtrType = mModule->GetPrimitiveType(BfTypeCode_NullPtr); auto valPtr = mModule->mBfIRBuilder->CreateBitCast(lambdaInstance->mClosureFunc, mModule->mBfIRBuilder->MapType(nullPtrType)); auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(baseDelegate, 0, funcPtrField.mDataIdx); mModule->mBfIRBuilder->CreateAlignedStore(valPtr, fieldPtr, funcPtrField.mResolvedType->mAlign); } - + mModule->AddDependency(useTypeInstance, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls); - + // Copy captures into the delegate if (lambdaInstance->mClosureTypeInstance != NULL) { int fieldIdx = 0; - + if (lambdaInstance->mCopyOuterCaptures) { for (auto& fieldInstance : lambdaInstance->mOuterClosure->mFieldInstances) @@ -14426,13 +15023,13 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) capturedValue = mModule->mBfIRBuilder->CreateAlignedLoad(capturedValue, fieldInstance.mResolvedType->mAlign); auto fieldPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(mResult.mValue, 0, fieldInstance.mDataIdx); mModule->mBfIRBuilder->CreateStore(capturedValue, fieldPtr); - + fieldIdx++; } } } - int captureIdx = 0; + int captureIdx = 0; for (int captureIdx = 0; captureIdx < (int)lambdaInstance->mCaptures.size(); captureIdx++) { auto& capturedEntry = lambdaInstance->mCaptures[captureIdx]; @@ -14454,7 +15051,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) break; } capturedValue = capturedTypedVal.mValue; - + if (capturedValue) { if (!IsVar(capturedTypedVal.mType)) @@ -14482,7 +15079,7 @@ void BfExprEvaluator::Visit(BfLambdaBindExpression* lambdaBindExpr) mModule->mBfIRBuilder->CreateAlignedStore(dtorThunk, fieldPtr, mModule->mSystem->mPtrSize); fieldIdx++; } - } + } } void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray& valueExprs, const BfSizedArray& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl& dimLengths, int dim, bool& hasFailed) @@ -14525,7 +15122,7 @@ void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSi } for (int i = 0; i < (int)valueExprs.size(); i++) - { + { BfExpression* expr = valueExprs[i]; if (auto uninitExpr = BfNodeDynCast(expr)) @@ -14537,16 +15134,16 @@ void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSi if (dim < dimensions - 1) { if (innerInitExpr == NULL) - { + { if (auto innerTupleExpr = BfNodeDynCast(expr)) { ProcessArrayInitializer(innerTupleExpr->mOpenParen, innerTupleExpr->mValues, innerTupleExpr->mCommas, innerTupleExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed); } else if (auto parenExpr = BfNodeDynCast(expr)) - { + { SizedArray values; values.Add(parenExpr->mExpression); - SizedArray commas; + SizedArray commas; ProcessArrayInitializer(parenExpr->mOpenParen, values, commas, parenExpr->mCloseParen, dimensions, dimLengths, dim + 1, hasFailed); } else @@ -14555,7 +15152,7 @@ void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSi mModule->Fail("A nested array initializer is expected", expr); continue; } - } + } else ProcessArrayInitializer(innerInitExpr->mOpenBrace, innerInitExpr->mValues, innerInitExpr->mCommas, innerInitExpr->mCloseBrace, dimensions, dimLengths, dim + 1, hasFailed); } @@ -14574,7 +15171,7 @@ void BfExprEvaluator::ProcessArrayInitializer(BfTokenNode* openToken, const BfSi void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode) { - auto autoComplete = GetAutoComplete(); + auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (afterNode != NULL) && (autoComplete->mIsAutoComplete) && (afterNode->IsFromParser(mModule->mCompiler->mResolvePassData->mParsers[0])) && (afterNode->GetParser()->mCursorIdx == afterNode->GetSrcEnd() + 1)) @@ -14586,9 +15183,9 @@ void BfExprEvaluator::CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* { expectingTypeInst = mExpectingType->ToTypeInstance(); } - + if ((mExpectingType != NULL) && (((expectingTypeInst == NULL) || (!expectingTypeInst->mTypeDef->mIsDelegate)))) - { + { // Why were we doing this? It floods the autocomplete with every possible type //autoComplete->AddTopLevelTypes(NULL); autoComplete->mInsertStartIdx = afterNode->GetSourceData()->ToParser()->mCursorIdx; @@ -14618,7 +15215,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr) void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* wantAllocType) { - auto autoComplete = GetAutoComplete(); + auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mTypeRef != NULL)) { autoComplete->CheckTypeRef(objCreateExpr->mTypeRef, false, true); @@ -14626,26 +15223,26 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL) && (objCreateExpr->mCloseToken != NULL) && (objCreateExpr->mOpenToken->mToken == BfToken_LBrace) && (autoComplete->CheckFixit(objCreateExpr->mOpenToken))) - { + { auto refNode = objCreateExpr->mOpenToken; BfParserData* parser = refNode->GetSourceData()->ToParserData(); if (parser != NULL) - { - autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Change initializer braces to parentheses\treformat|%s|%d-1|(\x01|%s|%d-1|)", + { + autoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("Change initializer braces to parentheses\treformat|%s|%d-1|(\x01|%s|%d-1|)", parser->mFileName.c_str(), refNode->mSrcStart, parser->mFileName.c_str(), objCreateExpr->mCloseToken->mSrcStart).c_str())); } } - CheckObjectCreateTypeRef(mExpectingType, allocNode); + CheckObjectCreateTypeRef(mExpectingType, allocNode); - BfAttributeState attributeState; + BfAttributeState attributeState; attributeState.mTarget = BfAttributeTargets_Alloc; - SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); + SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); BfTokenNode* newToken = NULL; BfAllocTarget allocTarget; ResolveAllocTarget(allocTarget, allocNode, newToken, &attributeState.mCustomAttributes); - + bool isScopeAlloc = newToken->GetToken() == BfToken_Scope; bool isAppendAlloc = newToken->GetToken() == BfToken_Append; bool isStackAlloc = (newToken->GetToken() == BfToken_Stack) || (isScopeAlloc); @@ -14658,7 +15255,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { mModule->Warn(0, "This allocation will only be in scope during the constructor. Consider using a longer-term allocation such as 'new'", allocNode); } - + if (allocNode == newToken) // Scope, no target specified { if (mModule->mParentNodeEntry != NULL) @@ -14677,10 +15274,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } BfAutoParentNodeEntry autoParentNodeEntry(mModule, objCreateExpr); - + SizedArray dimLengthRefs; SizedArray dimLengthVals; - + BfArrayType* arrayType = NULL; BfType* unresolvedTypeRef = NULL; @@ -14705,7 +15302,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs resolvedTypeRef = unresolvedTypeRef; } } - else + else { if ((objCreateExpr->mTypeRef->IsExact()) && (mExpectingType != NULL)) { @@ -14737,9 +15334,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs isArrayAlloc = true; if (auto dotTypeRef = BfNodeDynCast(arrayTypeRef->mElementType)) { - if ((mExpectingType != NULL) && + if ((mExpectingType != NULL) && ((mExpectingType->IsArray()) || (mExpectingType->IsPointer()) || (mExpectingType->IsSizedArray()))) - unresolvedTypeRef = mExpectingType->GetUnderlyingType(); + unresolvedTypeRef = mExpectingType->GetUnderlyingType(); } if (unresolvedTypeRef == NULL) unresolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType); @@ -14747,7 +15344,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs unresolvedTypeRef = mModule->mContext->mBfObjectType; int dimensions = 1; - + bool commaExpected = false; if (arrayTypeRef->mParams.size() != 0) { @@ -14793,9 +15390,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } if (arg != NULL) - { + { dimLength = mModule->CreateValueFromExpression(expr, intType, BfEvalExprFlags_NoCast); - + BfCastFlags castFlags = BfCastFlags_None; if ((dimLength) && (dimLength.mType->IsInteger())) { @@ -14820,7 +15417,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs dimLengthVals.push_back(dimLength.mValue); commaExpected = true; } - } + } if ((arrayTypeRef->mParams.size() == 0) && (objCreateExpr->mOpenToken == NULL)) mModule->Fail("Array size or array initializer expected", arrayTypeRef->mOpenBracket); @@ -14833,12 +15430,12 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } if (unresolvedTypeRef == NULL) - { - unresolvedTypeRef = ResolveTypeRef(objCreateExpr->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam); + { + unresolvedTypeRef = ResolveTypeRef(objCreateExpr->mTypeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_NoResolveGenericParam); } } - resolvedTypeRef = unresolvedTypeRef; + resolvedTypeRef = unresolvedTypeRef; if ((resolvedTypeRef != NULL) && (IsVar(resolvedTypeRef))) resolvedTypeRef = unresolvedTypeRef; } @@ -14849,32 +15446,32 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs resolvedTypeRef = unresolvedTypeRef; } auto resultType = resolvedTypeRef; - + if ((resolvedTypeRef->IsInterface()) && (!isArrayAlloc)) { mModule->Fail("Cannot create an instance of an interface", objCreateExpr->mTypeRef); resolvedTypeRef = mModule->mContext->mBfObjectType; } - - BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance(); + + BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance(); int elementSize = resolvedTypeRef->mSize; int elementAlign = resolvedTypeRef->mAlign; BfIRType allocType = mModule->mBfIRBuilder->MapType(resolvedTypeRef); if (typeInstance != NULL) { - if (!mModule->mCurTypeInstance->mResolvingVarField) + if (!mModule->mCurTypeInstance->mResolvingVarField) mModule->PopulateType(typeInstance); if ((typeInstance->mTypeDef->mIsDelegate) && (!isArrayAlloc)) mModule->Fail("Delegates must be constructed through delegate binding", objCreateExpr->mTypeRef); elementSize = BF_MAX(0, typeInstance->mInstSize); - elementAlign = typeInstance->mInstAlign; + elementAlign = typeInstance->mInstAlign; allocType = mModule->mBfIRBuilder->MapTypeInst(typeInstance); } if (isAppendAlloc) - { + { if (!mModule->mCurTypeInstance->IsObject()) { mModule->Fail("Append allocations are only allowed in classes", allocNode); @@ -14907,21 +15504,21 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { mModule->Fail("Append allocations are only allowed in non-static constructors", allocNode); isAppendAlloc = false; - } + } } } - + if (isArrayAlloc) { - const int MAX_DIMENSIONS = 2; - + const int MAX_DIMENSIONS = 2; + int dimensions = 1; if (arrayType != NULL) { dimensions = arrayType->mDimensions; mModule->AddDependency(arrayType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls); } - + bool zeroMemory = true; if (objCreateExpr->mOpenToken != NULL) { @@ -14953,7 +15550,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { int64 dimLength = constant->mInt64; if (dimLength < 0) - { + { mModule->Fail(StrFormat("Invalid array dimension '%lld'", dimLength), dimLengthRefs[dim]); dimLength = -1; } @@ -14974,7 +15571,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs // Ending in an ", )" means we need to zero-fill ending zeroMemory = objCreateExpr->mCommas.size() >= objCreateExpr->mArguments.size(); - bool hasFailed = false; + bool hasFailed = false; ProcessArrayInitializer(objCreateExpr->mOpenToken, objCreateExpr->mArguments, objCreateExpr->mCommas, objCreateExpr->mCloseToken, dimensions, dimLengths, 0, hasFailed); dimLengthVals.resize(dimLengths.size()); @@ -14983,18 +15580,18 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { if (!dimLengthVals[i]) { - auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); + auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); dimLengthVals[i] = mModule->GetConstValue(dimLengths[i], intType); } } } } - + while ((int)dimLengthVals.size() < dimensions) dimLengthVals.push_back(mModule->GetConstValue(0)); - + BfTypedValue arrayValue; - + BfIRValue arraySize; for (BfIRValue dimSize : dimLengthVals) { @@ -15007,23 +15604,22 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs BfAllocFlags allocFlags = BfAllocFlags_None; if (isRawArrayAlloc) allocFlags = (BfAllocFlags)(allocFlags | BfAllocFlags_RawArray); - + int writeIdx = 0; struct BfInitContext { public: BfModule* mModule; - BfType* resultType; + BfType* resultType; int dimensions; SizedArray& dimLengthVals; BfIRValue arraySize; - int& writeIdx; + int& writeIdx; BfInitContext(BfModule* module, BfType* resultType, int dimensions, SizedArray& dimLengthVals, BfIRValue arraySize, int& writeIdx) : mModule(module), resultType(resultType), dimensions(dimensions), dimLengthVals(dimLengthVals), arraySize(arraySize), writeIdx(writeIdx) { - } void Handle(BfIRValue addr, int curDim, const BfSizedArray& valueExprs) @@ -15103,7 +15699,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (!storeValue) continue; if (!resultType->IsValuelessType()) - { + { storeValue = mModule->LoadOrAggregateValue(storeValue); mModule->mBfIRBuilder->CreateStore(storeValue.mValue, elemAddr); } @@ -15134,7 +15730,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } // Actually leave it alone? - if ((isUninit) && + if ((isUninit) && ((mModule->IsOptimized()) || (mModule->mIsComptimeModule) || (mModule->mBfIRBuilder->mIgnoreWrites))) return; @@ -15146,7 +15742,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } if (doClear) { - // We multiply by GetStride. This relies on the fact that we over-allocate on the array allocation -- the last + // We multiply by GetStride. This relies on the fact that we over-allocate on the array allocation -- the last // element doesn't need to be padded out to the element alignment, but we do anyway. Otherwise this would be // a more complicated computation auto clearBytes = mModule->mBfIRBuilder->CreateMul(numElemsLeft, mModule->GetConstValue(resultType->GetStride())); @@ -15196,7 +15792,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs }; BfInitContext initContext(mModule, resultType, dimensions, dimLengthVals, arraySize, writeIdx); - + if (IsVar(resultType)) { SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); @@ -15207,7 +15803,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (isRawArrayAlloc) { - // If we have a constant-sized alloc then make the type a pointer to the sized array, otherwise just a pointer to the raw type + // If we have a constant-sized alloc then make the type a pointer to the sized array, otherwise just a pointer to the raw type BfType* ptrType = mModule->CreatePointerType(resultType); if (isAppendAlloc) arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, false), ptrType); @@ -15217,7 +15813,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } initContext.Handle(arrayValue.mValue, 0, objCreateExpr->mArguments); - + mResult = arrayValue; return; } @@ -15265,11 +15861,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false); } else - { - MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false); - } + { + MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, false); + } - //TODO: Assert 'length' var is at slot 1 + //TODO: Assert 'length' var is at slot 1 mModule->PopulateType(arrayType->mBaseType, BfPopulateType_DataAndMethods); mModule->mBfIRBuilder->PopulateType(arrayType); auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(arrayValue.mValue, mModule->mBfIRBuilder->MapTypeInstPtr(arrayType->mBaseType)); @@ -15278,13 +15874,13 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", objCreateExpr); return; - } + } mResult = arrayValue; auto lengthFieldInstance = mModule->GetFieldByName(arrayType->mBaseType->ToTypeInstance(), "mLength"); - if (lengthFieldInstance == NULL) - return; + if (lengthFieldInstance == NULL) + return; auto firstElementFieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mFirstElement"); if (firstElementFieldInstance == NULL) return; @@ -15315,9 +15911,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs addr = mModule->mBfIRBuilder->GetFakeVal(); else addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx); - + initContext.Handle(addr, 0, objCreateExpr->mArguments); - + return; } else @@ -15325,27 +15921,27 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (resolvedTypeRef->IsVar()) { // Leave as a var - } + } else if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam())) { resultType = mModule->CreatePointerType(resolvedTypeRef); } } - + if ((isStackAlloc) && (mModule->mCurMethodState == NULL)) { mModule->Fail("Cannot use 'stack' here", allocNode); isStackAlloc = false; isScopeAlloc = false; } - + bool isGenericParam = unresolvedTypeRef->IsGenericParam(); if (resolvedTypeRef->IsGenericParam()) { BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None; BfType* typeConstraint = NULL; auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)resolvedTypeRef, genericParamFlags, typeConstraint); - + if (typeConstraint == NULL) { if ((genericParamFlags & BfGenericParamFlag_Var) != 0) @@ -15364,7 +15960,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } } } - + if (((typeConstraint != NULL) && (typeConstraint->IsValueType())) || ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0)) { @@ -15378,7 +15974,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } else resultType = mModule->CreateModifiedTypeType(resolvedTypeRef, BfToken_AllocType); - + mResult.mType = resultType; if (typeInstance == NULL) @@ -15404,11 +16000,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs // Turn from an addr of a sized array to pointer of sized array mResult = BfTypedValue(mResult.mValue, resultType); return; - } + } } - SetAndRestoreValue prevNoBind(mNoBind, mNoBind || isGenericParam); - + SetAndRestoreValue prevNoBind(mNoBind, mNoBind || isGenericParam); + if ((typeInstance != NULL) && (typeInstance->mTypeDef->mIsAbstract)) { mModule->Fail("Cannot create an instance of an abstract class", objCreateExpr->mTypeRef); @@ -15418,20 +16014,20 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs BfFunctionBindResult bindResult; bindResult.mSkipThis = true; bindResult.mWantsArgs = true; - SetAndRestoreValue prevBindResult(mFunctionBindResult, &bindResult); + SetAndRestoreValue prevBindResult(mFunctionBindResult, &bindResult); - BfIRValue appendSizeValue; + BfIRValue appendSizeValue; BfTypedValue emtpyThis(mModule->mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct()); - + BfResolvedArgs argValues; if (objCreateExpr != NULL) { argValues.Init(objCreateExpr->mOpenToken, &objCreateExpr->mArguments, &objCreateExpr->mCommas, objCreateExpr->mCloseToken); ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval); //// } - + if (typeInstance == NULL) - { + { // No CTOR needed if (objCreateExpr->mArguments.size() != 0) { @@ -15441,7 +16037,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs else if ((autoComplete != NULL) && (objCreateExpr != NULL) && (objCreateExpr->mOpenToken != NULL)) { auto wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo; - autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas); + autoComplete->CheckInvocation(objCreateExpr, objCreateExpr->mOpenToken, objCreateExpr->mCloseToken, objCreateExpr->mCommas); MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInstance, argValues, false, true); if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo)) { @@ -15456,8 +16052,8 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs auto refNode = allocNode; if (objCreateExpr != NULL) refNode = objCreateExpr->mTypeRef; - MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, true); - } + MatchConstructor(refNode, objCreateExpr, emtpyThis, typeInstance, argValues, false, true); + } if (objCreateExpr != NULL) mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef); @@ -15469,16 +16065,16 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs int appendAllocAlign = 0; if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend)) - { + { if (!bindResult.mFunc) { BF_ASSERT((!mModule->HasExecutedOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites)); appendSizeValue = mModule->GetConstValue(0); } else - { + { auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND); - + SizedArray irArgs; if (bindResult.mIRArgs.size() > 1) irArgs.Insert(0, &bindResult.mIRArgs[1], bindResult.mIRArgs.size() - 1); @@ -15486,7 +16082,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (!appendSizeTypedValue) { BF_ASSERT(calcAppendMethodModule.mFunc); - + appendSizeTypedValue = CreateCall(objCreateExpr, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs); BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr)); } @@ -15497,13 +16093,13 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (appendAllocAlign != 0) { - int endingAlign = typeInstance->GetEndingInstanceAlignment(); + int endingAlign = typeInstance->GetEndingInstanceAlignment(); if (endingAlign % appendAllocAlign != 0) { int extraSize = appendAllocAlign - (endingAlign % appendAllocAlign); appendSizeValue = mModule->mBfIRBuilder->CreateAdd(appendSizeValue, mModule->GetConstValue(extraSize)); - } - } + } + } } // WTF? I'm not even sure this is correct - add more tests @@ -15519,7 +16115,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs { if (isAppendAlloc) { - allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign); + allocValue = mModule->AppendAllocFromType(resolvedTypeRef, appendSizeValue, appendAllocAlign); } else { @@ -15541,8 +16137,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs /*if (typeInstance != NULL) { - - mModule->InitTypeInst(mResult, scopeData, true); + mModule->InitTypeInst(mResult, scopeData, true); } if (isStackAlloc) { @@ -15558,9 +16153,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs //mModule->mBfIRBuilder->CreateMemSet(mResult.mValue, mModule->GetConstValue8(0), mModule->GetConstValue(resolvedTypeRef->mSize), resolvedTypeRef->mAlign); } else if (bindResult.mFunc) - { + { if (typeInstance->IsObject()) - { + { bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime()); bool wantsCtorClear = true; @@ -15570,7 +16165,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if ((!isStackAlloc) && (!isAppendAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL)) wantsCtorClear = false; } - + if (wantsCtorClear) { auto ctorClear = mModule->GetMethodByName(typeInstance, "__BfCtorClear"); @@ -15607,6 +16202,18 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs BF_ASSERT(vtableEntry.mImplementingMethod.mKind == BfMethodRefKind_AmbiguousRef); } + if (!needsCall) + { + for (auto& fieldInst : typeInstance->mFieldInstances) + { + if (fieldInst.IsAppendedObject()) + { + needsCall = true; + break; + } + } + } + if (needsCall) { SizedArray irArgs; @@ -15635,17 +16242,17 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs } } } - + if ((bindResult.mMethodInstance->mMethodDef->mHasAppend) && (mResult.mType->IsObject())) { BF_ASSERT(bindResult.mIRArgs[0].IsFake()); auto typeInst = mResult.mType->ToTypeInstance(); - auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); + auto intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); auto thisVal = mResult; BfIRValue intPtrVal = mModule->CreateAlloca(intPtrType); auto intPtrThisVal = mModule->mBfIRBuilder->CreatePtrToInt(thisVal.mValue, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64); auto curValPtr = mModule->mBfIRBuilder->CreateAdd(intPtrThisVal, mModule->GetConstValue(typeInst->mInstSize, intPtrType)); - mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal); + mModule->mBfIRBuilder->CreateStore(curValPtr, intPtrVal); bindResult.mIRArgs[0] = intPtrVal; } if (!typeInstance->IsValuelessType()) @@ -15701,7 +16308,7 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr) auto genericParamTarget = (BfGenericParamType*)exprValue.mType; auto genericParamInstance = mModule->GetGenericParamInstance(genericParamTarget); - + if ((genericParamInstance->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) == BfGenericParamFlag_Class) doWarn = true; @@ -15728,7 +16335,7 @@ void BfExprEvaluator::Visit(BfBoxExpression* boxExpr) mModule->Fail(StrFormat("Box target '%s' must be a value type or pointer to a value type", mModule->TypeToString(exprValue.mType).c_str()), boxExpr->mExpression); return; } - + if (boxedType == NULL) boxedType = mModule->CreateBoxedType(exprValue.mType); if (boxedType == NULL) @@ -15746,7 +16353,7 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* { auto autoComplete = GetAutoComplete(); BfAttributeDirective* attributeDirective = NULL; - + allocTarget.mRefNode = allocNode; newToken = BfNodeDynCast(allocNode); if (newToken == NULL) @@ -15816,7 +16423,7 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* } } else if (attrib.mType->IsInstanceOf(mModule->mCompiler->mFriendAttributeTypeDef)) - allocTarget.mIsFriend = true; + allocTarget.mIsFriend = true; } if (outCustomAttributes != NULL) @@ -15824,7 +16431,7 @@ void BfExprEvaluator::ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* else delete customAttrs; } - } + } } BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target) @@ -15860,7 +16467,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa auto primStructType = mModule->GetWrappedStructType(target.mType); if (primStructType != NULL) { - mModule->PopulateType(primStructType); + mModule->PopulateType(primStructType); if (primStructType->IsTypedPrimitive()) { @@ -15875,7 +16482,7 @@ BfTypedValue BfExprEvaluator::MakeCallableTarget(BfAstNode* targetSrc, BfTypedVa else if ((primStructType->IsSplattable()) && (target.IsSplat()) && (!IsComptime())) { target.mType = primStructType; - target.mKind = BfTypedValueKind_SplatHead; + target.mKind = BfTypedValueKind_SplatHead; } else { @@ -15919,7 +16526,7 @@ int BfExprEvaluator::GetMixinVariable() BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType) { bool failed = false; - + BfTypeVector resolvedGenericArguments; BfMethodState* rootMethodState = NULL; if (mModule->mCurMethodState != NULL) @@ -15928,7 +16535,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, int localInferrableGenericArgCount = -1; if ((methodMatcher.mBestMethodGenericArguments.size() == 0) && (!methodMatcher.mExplicitMethodGenericArguments.IsEmpty())) - { + { int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(methodDef); int64 genericArgCountDiff = (int)methodMatcher.mExplicitMethodGenericArguments.size() + uniqueGenericStartIdx - (int)methodDef->mGenericParams.size(); @@ -15952,7 +16559,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, mModule->Fail(StrFormat("Too many generic arguments, expected %d fewer", genericArgCountDiff), errorNode); } else if ((genericArgCountDiff < 0) && (!methodMatcher.mHadOpenGenericArguments)) - { + { BfAstNode* errorNode = targetSrc; if ((invocationExpr != NULL) && (invocationExpr->mGenericArgs != NULL) && (invocationExpr->mGenericArgs->mCloseChevron != NULL)) errorNode = invocationExpr->mGenericArgs->mCloseChevron; @@ -15970,8 +16577,8 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, bool hasVarGenerics = false; - for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++) - { + for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++) + { BfMethodInstance* outerMethodInstance = NULL; auto& genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx]; @@ -15979,7 +16586,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, if (genericArg == NULL) { if ((methodDef->mIsLocalMethod) && (checkGenericIdx < mModule->mCurMethodInstance->GetNumGenericArguments())) - { + { // If the root method is generic and we need that param then use that... auto rootMethodInstance = rootMethodState->mMethodInstance; if ((rootMethodInstance->mMethodInfoEx != NULL) && (checkGenericIdx < rootMethodInstance->mMethodInfoEx->mMethodGenericArguments.size())) @@ -15995,7 +16602,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, if (checkGenericIdx < localInferrableGenericArgCount) genericArg = mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments[checkGenericIdx]; } - } + } } if (genericArg == NULL) @@ -16027,13 +16634,13 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, { BfTypedValue constExprVal; constExprVal.mType = genericParam->mTypeConstraint; - auto constant = curTypeInst->mConstHolder->GetConstant(defaultVal.mValue); + auto constant = curTypeInst->mConstHolder->GetConstant(defaultVal.mValue); constExprVal.mValue = mModule->ConstantToCurrent(constant, curTypeInst->mConstHolder, genericParam->mTypeConstraint); genericArg = mModule->CreateConstExprValueType(constExprVal); } } } - } + } } if (genericArg == NULL) @@ -16041,7 +16648,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, BfGenericInferContext genericInferContext; genericInferContext.mModule = mModule; genericInferContext.mCheckMethodGenericArguments = &methodMatcher.mBestMethodGenericArguments; - genericInferContext.InferGenericArguments(unspecializedMethod); + genericInferContext.InferGenericArguments(unspecializedMethod); } if (genericArg == NULL) @@ -16054,9 +16661,9 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, genericArg = mModule->mContext->mBfObjectType; if (error != NULL) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), unspecializedMethod->mMethodDef->GetRefNode()); - } + } } - + if (genericArg->IsVar()) { //BF_ASSERT(methodMatcher.mHasVarArguments); @@ -16067,7 +16674,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, genericArg = mModule->FixIntUnknown(genericArg); auto resolvedGenericArg = genericArg; - resolvedGenericArguments.push_back(genericArg); + resolvedGenericArguments.push_back(genericArg); } BfTypeInstance* foreignType = NULL; @@ -16095,10 +16702,10 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type. foreignType = curTypeInst; curTypeInst = mModule->mCurTypeInstance; - flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef); + flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef); } } - } + } if (hasVarGenerics) return BfModuleMethodInstance(); @@ -16109,7 +16716,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, moduleMethodInstance = methodMatcher.mBestMethodInstance; } else - { + { moduleMethodInstance = mModule->GetMethodInstance(curTypeInst, methodDef, resolvedGenericArguments, flags, foreignType); } if (mModule->IsSkippingExtraResolveChecks()) @@ -16117,7 +16724,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, //BF_ASSERT(methodInstance.mFunc == NULL); } if (moduleMethodInstance.mMethodInstance == NULL) - return NULL; + return NULL; if (methodDef->IsEmptyPartial()) return moduleMethodInstance; @@ -16129,7 +16736,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, auto genericParams = moduleMethodInstance.mMethodInstance->mMethodInfoEx->mGenericParams[checkGenericIdx]; BfTypeVector* checkMethodGenericArgs = NULL; BfType* genericArg = NULL; - + if (checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size()) { genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx]; @@ -16138,14 +16745,14 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, { checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments; genericArg = genericParams->mExternType; - + auto owner = moduleMethodInstance.mMethodInstance->GetOwner(); BfTypeVector* typeGenericArguments = NULL; if (owner->mGenericTypeInfo != NULL) typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments; //genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs); } - + if (genericArg->IsVar()) continue; @@ -16190,9 +16797,9 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, { typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(typeUnspecMethodInstance, true); typeGenericArgs = &curTypeInst->mGenericTypeInfo->mTypeGenericArguments; - } - - BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments, + } + + BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments, mModule->mCurTypeInstance); if (specializedReturnType != NULL) *overrideReturnType = specializedReturnType; @@ -16202,7 +16809,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc, } BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfMethodMatcher& methodMatcher) -{ +{ if (!methodMatcher.mBestMethodInstance) methodMatcher.mBestMethodInstance = GetSelectedMethod(methodMatcher.mTargetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher); return methodMatcher.mBestMethodInstance; @@ -16215,7 +16822,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty auto parser = targetSrc->GetSourceData()->ToParserData(); return ((int64)parser->mDataId << 32) + targetSrc->GetSrcStart(); }; - + BfMethodState* ctxMethodState = NULL; BfClosureInstanceInfo* ctxClosureInstanceInfo = NULL; @@ -16246,7 +16853,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty } } else - { + { BfLocalMethod* matchedLocalMethod = NULL; BfLocalMethod* localMethod = NULL; if (checkMethodState->mLocalMethodMap.TryGetValue(methodName, &localMethod)) @@ -16279,7 +16886,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState != NULL)) { - // The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its + // The called method is calling us from its mLocalMethodRefs set. Stretch our mCaptureStartAccessId back to incorporate its // captures as well if (methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId < mModule->mCurMethodState->mClosureState->mCaptureStartAccessId) mModule->mCurMethodState->mClosureState->mCaptureStartAccessId = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState->mCaptureStartAccessId; @@ -16306,7 +16913,7 @@ void BfExprEvaluator::CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* ty } checkMethodState = checkMethodState->mPrevMethodState; - } + } } void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray& arguments, const BfMethodGenericArguments& methodGenericArgs) @@ -16370,7 +16977,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo argExprEvaluators.push_back(new BfExprEvaluator(mModule)); BfExprEvaluator* exprEvaluator = argExprEvaluators.back(); - exprEvaluator->mResolveGenericParam = false; + exprEvaluator->mResolveGenericParam = false; exprEvaluator->mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator->mBfEvalExprFlags | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr); bool deferExpr = false; @@ -16382,7 +16989,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (deferExpr) { - // + // } else if (argExpr != NULL) exprEvaluator->Evaluate(argExpr, false, false, true); @@ -16425,7 +17032,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { CheckLocalMethods(targetSrc, curTypeInst, name, methodMatcher, BfMethodType_Mixin); } - + if (methodMatcher.mBestMethodDef == NULL) methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef; @@ -16450,10 +17057,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo continue; methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false); if (methodMatcher.mBestMethodDef != NULL) - break; + break; } } - + if (methodMatcher.mBestMethodDef == NULL) { BfStaticSearch* staticSearch = mModule->GetStaticSearch(); @@ -16475,8 +17082,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mModule->Fail("Cannot find mixin", targetSrc); return; } - - auto resolvePassData = mModule->mCompiler->mResolvePassData; + + auto resolvePassData = mModule->mCompiler->mResolvePassData; if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(targetNameNode)) && (autoComplete->mDefType == NULL)) { autoComplete->mInsertStartIdx = targetNameNode->GetSrcStart(); @@ -16487,14 +17094,14 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } if ((mModule->mCompiler->mResolvePassData != NULL) && (mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method)) - { + { targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() - 1); mModule->mCompiler->mResolvePassData->HandleMethodReference(targetNameNode, methodMatcher.mBestMethodTypeInstance->mTypeDef, methodMatcher.mBestMethodDef); targetNameNode->SetSrcEnd(targetNameNode->GetSrcEnd() + 1); } - + auto curMethodState = mModule->mCurMethodState; - + auto moduleMethodInstance = GetSelectedMethod(targetSrc, methodMatcher.mBestMethodTypeInstance, methodMatcher.mBestMethodDef, methodMatcher); if (!moduleMethodInstance) { @@ -16508,8 +17115,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo return; } - if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc)) - return; + if (!mModule->CheckUseMethodInstance(moduleMethodInstance.mMethodInstance, targetSrc)) + return; auto methodInstance = moduleMethodInstance.mMethodInstance; PerformCallChecks(methodInstance, targetSrc); @@ -16522,15 +17129,15 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo continue; BfAstNode* paramSrc; - if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0) - paramSrc = targetSrc; + if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0) + paramSrc = targetSrc; else paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression; // Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized BfError* error = NULL; if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL, &error)) - { + { if (methodInstance->mMethodDef->mMethodDeclaration != NULL) { if (error != NULL) @@ -16549,12 +17156,12 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo // based on method selection within the mixin dependent on args { bool hasCircularRef = false; - + BfMixinState* checkMixinState = NULL; auto checkMethodState = curMethodState; while (checkMethodState != NULL) - { + { auto curMixinState = checkMethodState->mMixinState; while (curMixinState != NULL) { @@ -16595,8 +17202,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } checkMethodState = checkMethodState->mPrevMethodState; - } - + } + if (hasCircularRef) { for (auto argType : checkMixinState->mArgTypes) @@ -16616,8 +17223,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } } - AddCallDependencies(methodInstance); - + AddCallDependencies(methodInstance); + if (!methodMatcher.mBestMethodDef->mIsStatic) { if ((!target) && (allowImplicitThis)) @@ -16635,7 +17242,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { if (target) { - BfError* error = mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead", + BfError* error = mModule->Fail(StrFormat("Mixin '%s' cannot be accessed with an instance reference; qualify it with a type name instead", mModule->MethodToString(methodInstance).c_str()), targetSrc); if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL)) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode()); @@ -16648,16 +17255,16 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo int explicitParamCount = methodParamCount - implicitParamCount; while ((int)args.size() < explicitParamCount) - { + { int argIdx = (int)args.size(); BfExpression* expr = methodInstance->GetParamInitializer(argIdx); if (expr == NULL) - break; + break; _AddArg(expr); } if ((int)args.size() < explicitParamCount) - { + { BfError* error = mModule->Fail(StrFormat("Not enough arguments specified, expected %d more.", explicitParamCount - (int)arguments.size()), targetSrc); if ((error != NULL) && (methodInstance->mMethodDef->GetRefNode() != NULL)) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode()); @@ -16670,18 +17277,18 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode()); return; } - + int paramIdx = implicitParamCount; - auto argExprEvaluatorItr = argExprEvaluators.begin(); + auto argExprEvaluatorItr = argExprEvaluators.begin(); for (int argIdx = 0; argIdx < (int)args.size(); argIdx++) { auto exprEvaluator = *argExprEvaluatorItr; //auto paramType = methodInstance->GetParamKind(paramIdx); - + BfType* wantType = methodInstance->mParams[paramIdx].mResolvedType; auto& arg = args[argIdx]; - + if ((arg.mArgFlags & BfArgFlag_VariableDeclaration) != 0) { arg.mTypedValue = ResolveArgValue(arg, wantType); @@ -16689,7 +17296,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (wantType->IsGenericParam()) { - // + // } else if (!wantType->IsVar()) { @@ -16703,11 +17310,11 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { exprEvaluator->FinishExpressionResult(); arg.mTypedValue = mModule->LoadValue(arg.mTypedValue); - arg.mTypedValue = mModule->Cast(arg.mExpression, arg.mTypedValue, wantType); + arg.mTypedValue = mModule->Cast(arg.mExpression, arg.mTypedValue, wantType); /*// Do this to generate default implicit cast error - mModule->Fail(StrFormat("Mixin argument type '%s' must match parameter type '%s'.", - mModule->TypeToString(arg.mTypedValue.mType).c_str(), + mModule->Fail(StrFormat("Mixin argument type '%s' must match parameter type '%s'.", + mModule->TypeToString(arg.mTypedValue.mType).c_str(), mModule->TypeToString(wantType).c_str()), arg.mExpression); return;*/ } @@ -16718,7 +17325,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } mModule->AddDependency(methodInstance->GetOwner(), mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_InlinedCall); - + auto startBlock = mModule->mBfIRBuilder->CreateBlock("mixinStart"); mModule->mBfIRBuilder->CreateBr(startBlock); mModule->mBfIRBuilder->AddBlock(startBlock); @@ -16727,7 +17334,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo //auto prevDebugLoc = mModule->mBfIRBuilder->getCurrentDebugLocation(); // This is so when we debug we can hit a steppoint on the inlined "call line" mModule->EmitEnsureInstructionAt(); - + auto rootMethodState = mModule->mCurMethodState->GetRootMethodState(); BfMixinState* mixinState = rootMethodState->mMixinStates.Alloc(); @@ -16740,7 +17347,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mixinState->mTargetScope = mixinState->mCallerScope; mixinState->mResultExpr = NULL; mixinState->mHasDeferredUsage = false; - mixinState->mUsedInvocationScope = false; + mixinState->mUsedInvocationScope = false; mixinState->mTarget = target; auto checkNode = origTargetSrc; @@ -16757,12 +17364,12 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } } } - + mModule->mBfIRBuilder->SaveDebugLocation(); SetAndRestoreValue prevMixinState(curMethodState->mMixinState, mixinState); BfGetSymbolReferenceKind prevSymbolRefKind = BfGetSymbolReferenceKind_None; - if (mModule->mCompiler->mResolvePassData != NULL) + if (mModule->mCompiler->mResolvePassData != NULL) { prevSymbolRefKind = mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind; mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None; @@ -16774,35 +17381,35 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (mModule->mCompiler->mResolvePassData != NULL) mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind; } - ); + ); auto methodDef = methodInstance->mMethodDef; auto methodDeclaration = methodDef->GetMethodDeclaration(); - BfScopeData scopeData; + BfScopeData scopeData; scopeData.mCloseNode = methodDeclaration->mBody; if (auto block = BfNodeDynCast(methodDeclaration->mBody)) { if (block->mCloseBrace != NULL) scopeData.mCloseNode = block->mCloseBrace; } - curMethodState->AddScope(&scopeData); - curMethodState->mCurScope->mMixinDepth++; + curMethodState->AddScope(&scopeData); + curMethodState->mCurScope->mMixinDepth++; // We can't flush scope state because we extend params in as arbitrary values mModule->NewScopeState(true, false); - bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo); + bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo); DISubprogram* diFunction = NULL; - + int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size(); int endLocalIdx = startLocalIdx; if ((wantsDIData) || (mModule->mIsComptimeModule)) - { + { BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance); //int defLine = mModule->mCurFilePosition.mCurLine; - - int flags = 0; + + int flags = 0; curMethodState->mCurScope->mDIInlinedAt = mModule->mBfIRBuilder->DbgGetCurrentLocation(); // We used to have the "def" line be the inlining position, but the linker we de-duplicate instances of these functions without regard to their unique line @@ -16813,7 +17420,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (!mModule->mBfIRBuilder->mIgnoreWrites) { String methodName = methodDef->mName; - methodName += "!"; + methodName += "!"; BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance); String linkageName; if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mCurBuilder != NULL)) @@ -16823,10 +17430,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile; } } - + if (methodDef->mBody != NULL) mModule->UpdateSrcPos(methodDef->mBody); - + mModule->SetIllegalSrcPos(); auto _AddLocalVariable = [&](BfLocalVariable* newLocalVar, BfExprEvaluator* exprEvaluator) @@ -16838,7 +17445,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (hasConstValue) { auto constant = mModule->mBfIRBuilder->GetConstant(newLocalVar->mConstValue); - hasConstValue = constant->mConstType < BfConstType_GlobalVar; + hasConstValue = constant->mConstType < BfConstType_GlobalVar; } if ((exprEvaluator != NULL) && (exprEvaluator->mResultLocalVar != NULL) && (exprEvaluator->mResultLocalVarField == 0)) @@ -16929,7 +17536,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo // auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope, // name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType); // mModule->mBfIRBuilder->DbgInsertValueIntrinsic(fakeValue, diVariable); - + auto diType = mModule->mBfIRBuilder->DbgGetType(mModule->GetPrimitiveType(BfTypeCode_NullPtr)); auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope, name, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType); @@ -16943,7 +17550,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo checkMethodState = checkMethodState->mPrevMethodState; } } - + if (handled) { // @@ -16952,11 +17559,11 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { mModule->UpdateSrcPos(methodDeclaration->mNameNode); mModule->SetIllegalSrcPos(); - + // With the Beef backend we can assign two variables to the same value, but LLVM does not allow this // so we have to create a ref to that variable auto diType = mModule->mBfIRBuilder->DbgGetType(newLocalVar->mResolvedType); - + auto diVariable = mModule->mBfIRBuilder->DbgCreateAutoVariable(mModule->mCurMethodState->mCurScope->mDIScope, newLocalVar->mName, mModule->mCurFilePosition.mFileInstance->mDIFile, mModule->mCurFilePosition.mCurLine, diType); @@ -16978,7 +17585,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value); if (mModule->WantsLifetimes()) - scopeData.mDeferredLifetimeEnds.Add(aliasValue); + scopeData.mDeferredLifetimeEnds.Add(aliasValue); if (newLocalVar->mAddr) mModule->mBfIRBuilder->DbgInsertDeclare(aliasValue, diVariable); @@ -17023,7 +17630,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo localVal = mModule->AggregateSplat(localVal); BfType* allocType = localVal.mType; - + auto allocaVal = mModule->CreateAlloca(allocType); mModule->mBfIRBuilder->CreateStore(localVal.mValue, allocaVal); @@ -17031,7 +17638,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (!mModule->mBfIRBuilder->mIgnoreWrites) { if (newLocalVar->mIsSplat) - { + { //TODO: Implement } else @@ -17050,17 +17657,17 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (mModule->mBfIRBuilder->IsConstValue(newLocalVar->mConstValue)) mixinState->mArgConsts.Add(newLocalVar->mConstValue); }; - + argExprEvaluatorItr = argExprEvaluators.begin(); for (int argIdx = methodDef->mIsStatic ? 0 : -1; argIdx < (int)explicitParamCount; argIdx++) { int paramIdx = argIdx; - auto exprEvaluator = *argExprEvaluatorItr; + auto exprEvaluator = *argExprEvaluatorItr; BfTypedValue argValue; - BfLocalVariable* localVar = new BfLocalVariable(); + BfLocalVariable* localVar = new BfLocalVariable(); if (argIdx == -1) { @@ -17088,8 +17695,8 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (!argValue) continue; - - localVar->mResolvedType = argValue.mType; + + localVar->mResolvedType = argValue.mType; if (argValue.mType->IsRef()) { auto refType = (BfRefType*)localVar->mResolvedType; @@ -17103,7 +17710,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { if (!argValue.mValue) { - // Untyped value + // Untyped value } else if (argValue.mValue.IsConst()) { @@ -17126,7 +17733,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } if (argValue.IsReadOnly()) localVar->mIsReadOnly = true; - + if (argIdx == -1) { _AddLocalVariable(localVar, NULL); @@ -17138,7 +17745,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo endLocalIdx++; ++argExprEvaluatorItr; } - } + } if (auto blockBody = BfNodeDynCast(methodDef->mBody)) { @@ -17151,6 +17758,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (!exprNode->IsA()) { // Mixin expression result + SetAndRestoreValue prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr)); mModule->UpdateSrcPos(exprNode); VisitChild(exprNode); FinishExpressionResult(); @@ -17165,16 +17773,24 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo { mModule->UpdateSrcPos(expr); mResult = mModule->CreateValueFromExpression(expr); - } + } if (!mResult) { // If we didn't have an expression body then just make the result "void" mResult = BfTypedValue(BfIRValue(), mModule->GetPrimitiveType(BfTypeCode_None)); } - + + mResult = mModule->RemoveRef(mResult); + + if (mResult.IsAddr()) + { + if (mModule->mCurMethodState->mCurScope->ExtendLifetime(mResult.mValue)) + mModule->mBfIRBuilder->CreateLifetimeSoftEnd(mResult.mValue); + } + int localIdx = startLocalIdx; - + argExprEvaluatorItr = argExprEvaluators.begin(); for (; localIdx < endLocalIdx; localIdx++) { @@ -17191,7 +17807,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo } ++argExprEvaluatorItr; - } + } if (auto blockBody = BfNodeDynCast(methodDef->mBody)) { @@ -17203,9 +17819,9 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo if (methodDeclaration->mFatArrowToken != NULL) mModule->UpdateSrcPos(methodDeclaration->mFatArrowToken); } - - mModule->RestoreScopeState(); - + + mModule->RestoreScopeState(); + prevMixinState.Restore(); if ((scopedInvocationTarget != NULL) && (scopedInvocationTarget->mScopeName != NULL) && (!mixinState->mUsedInvocationScope)) @@ -17226,7 +17842,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo BF_ASSERT(rootMethodState->mMixinStates.back() == mixinState); rootMethodState->mMixinStates.pop_back(); delete mixinState; - } + } mModule->mBfIRBuilder->RestoreDebugLocation(); mModule->mBfIRBuilder->DupDebugLocation(); @@ -17241,7 +17857,7 @@ void BfExprEvaluator::SetMethodElementType(BfAstNode* target) } if (auto lambdaBindExpr = BfNodeDynCast(target)) - { + { return; } @@ -17250,7 +17866,7 @@ void BfExprEvaluator::SetMethodElementType(BfAstNode* target) if (attributedIdentifierNode->mIdentifier != NULL) mModule->SetElementType(attributedIdentifierNode->mIdentifier, BfSourceElementType_Method); } - else if (auto memberReferenceExpr = BfNodeDynCast(target)) + else if (auto memberReferenceExpr = BfNodeDynCast(target)) { if (memberReferenceExpr->mMemberName != NULL) SetMethodElementType(memberReferenceExpr->mMemberName); @@ -17287,7 +17903,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m bool allowImplicitThis = false; BfAstNode* methodNodeSrc = target; - + BfAttributeState attributeState; attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_Invocation | BfAttributeTargets_MemberAccess); @@ -17317,7 +17933,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m autoComplete->CheckMemberReference(memberRefExpression->mTarget, memberRefExpression->mDotToken, memberRefExpression->mMemberName, false, mExpectingType); else if (mExpectingType != NULL) { - String filter; + String filter; if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(memberRefExpression->mDotToken, memberRefExpression->mMemberName, filter))) { auto typeInst = mExpectingType->ToTypeInstance(); @@ -17327,11 +17943,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if ((memberRefExpression->mMemberName != NULL) && (autoComplete->IsAutocompleteNode(memberRefExpression->mMemberName))) filter = autoComplete->GetFilter(memberRefExpression->mMemberName); - bool allowPrivate = typeInst == mModule->mCurTypeInstance; + bool allowPrivate = typeInst == mModule->mCurTypeInstance; autoComplete->AddEnumTypeMembers(typeInst, filter, false, allowPrivate); autoComplete->AddSelfResultTypeMembers(typeInst, typeInst, filter, allowPrivate); } - } + } } } @@ -17345,7 +17961,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m } if (expectingType != NULL) - { + { if (expectingType->IsSizedArray()) { if (mModule->mParentNodeEntry != NULL) @@ -17357,10 +17973,10 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m } } } - else if (expectingType->IsStruct()) + else if ((expectingType->IsStruct()) || (expectingType->IsTypedPrimitive())) { if ((wasCapturingMethodInfo) && (autoComplete->mMethodMatchInfo != NULL)) - { + { autoComplete->mIsCapturingMethodMatchInfo = true; BF_ASSERT(autoComplete->mMethodMatchInfo != NULL); } @@ -17381,10 +17997,10 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m } else mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr); - - auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, false); + + auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, false); if ((ctorResult) && (!ctorResult.mType->IsVoid())) - mResult = ctorResult; + mResult = ctorResult; mModule->ValidateAllocation(expectingType, invocationExpr->mTarget); return; @@ -17417,13 +18033,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { // Allow } - else + else if ((mBfEvalExprFlags & BfEvalExprFlags_AppendFieldInitializer) == 0) { gaveUnqualifiedDotError = true; if (mModule->PreFail()) mModule->Fail(StrFormat("Cannot use inferred constructor on type '%s'", mModule->TypeToString(expectingType).c_str()), memberRefExpression->mDotToken); } - } + } } if (memberRefExpression->IsA()) @@ -17436,7 +18052,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if (attrIdentifier->mIdentifier != NULL) methodNodeSrc = attrIdentifier->mIdentifier; attributeState.mSrc = attrIdentifier->mAttributes; - attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); + attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); if (attrIdentifier->mIdentifier != NULL) targetFunctionName = attrIdentifier->mIdentifier->ToString(); } @@ -17449,11 +18065,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { if (mExpectingType->IsVar()) { - } mResult = BfTypedValue(mExpectingType); - } else if (!gaveUnqualifiedDotError) mModule->Fail("Unqualified dot syntax can only be used when the result type can be inferred", memberRefExpression->mDotToken); @@ -17464,7 +18078,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m mResult = BfTypedValue(ResolveTypeRef(typeRef)); } if (auto leftIdentifier = BfNodeDynCast(memberRefExpression->mTarget)) - { + { bool hadError = false; thisValue = LookupIdentifier(leftIdentifier, true, &hadError); @@ -17495,7 +18109,6 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m thisValue = mResult; mResult = BfTypedValue(); } - } if (mPropDef != NULL) thisValue = GetResult(true); @@ -17517,7 +18130,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m bool handled = false; if (auto subMemberRefExpr = BfNodeDynCast(expr)) - { + { String findName; if (subMemberRefExpr->mMemberName != NULL) findName = subMemberRefExpr->mMemberName->ToString(); @@ -17564,7 +18177,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m bypassVirtual = true; } } - } + } } } @@ -17577,10 +18190,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if (auto paranExpr = BfNodeDynCast(expr)) { // Allow 'ref' on binding, to indicate we want to capture 'this' by reference - flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowRefExpr); + flags = (BfEvalExprFlags)(flags | BfEvalExprFlags_AllowRefExpr); expr = paranExpr->mExpression; } - } if (expr != NULL) mResult = mModule->CreateValueFromExpression(expr, expectingTargetType, flags); @@ -17593,7 +18205,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m bool isNullCondLookup = (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->GetToken() == BfToken_QuestionDot); if (isNullCondLookup) mResult = SetupNullConditional(mResult, memberRefExpression->mDotToken); - + if ((mResult.mType == NULL) && (memberRefExpression->mTarget != NULL)) { mModule->AssertErrorState(); @@ -17601,14 +18213,17 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m } thisValue = mResult; mResult = BfTypedValue(); + + if ((thisValue) && (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->mToken == BfToken_Arrow)) + thisValue = TryArrowLookup(thisValue, memberRefExpression->mDotToken); } else if (auto qualifiedName = BfNodeDynCast(target)) { if (GetAutoComplete() != NULL) GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight); - + if (qualifiedName->mLeft->GetSrcLength() == 4) - { + { if (CheckIsBase(qualifiedName->mLeft)) bypassVirtual = true; } @@ -17621,38 +18236,38 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if (attrIdentifier->mIdentifier != NULL) methodNodeSrc = attrIdentifier->mIdentifier; attributeState.mSrc = attrIdentifier->mAttributes; - attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); + attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); targetFunctionName = attrIdentifier->mIdentifier->ToString(); } else - targetFunctionName = qualifiedName->mRight->ToString(); + targetFunctionName = qualifiedName->mRight->ToString(); - bool hadError = false; - thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError); + bool hadError = false; + thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError); CheckResultForReading(thisValue); - if (mPropDef != NULL) - thisValue = GetResult(true); + if (mPropDef != NULL) + thisValue = GetResult(true); if (hadError) { mModule->AssertErrorState(); thisValue = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType); } - + if ((!thisValue) && (mPropDef == NULL)) { // Identifier not found. Static method? Just check speculatively don't throw error BfType* type; { - //SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); + //SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); type = mModule->ResolveTypeRef(qualifiedName->mLeft, NULL, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError)); } if (type == NULL) { //SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); - + type = mModule->ResolveTypeRef(qualifiedName, methodGenericArguments, BfPopulateType_DataAndMethods, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowGlobalContainer | BfResolveTypeRefFlag_IgnoreLookupError)); if (type != NULL) { @@ -17676,7 +18291,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { if ((thisValue.mType == type) || (!mModule->TypeIsSubTypeOf(thisValue.mType->ToTypeInstance(), type->ToTypeInstance()))) { - mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'", + mModule->Fail(StrFormat("Type '%s' is not a base type of '%s'", mModule->TypeToString(type).c_str(), mModule->TypeToString(thisValue.mType).c_str()), qualifiedLeft->mLeft); } @@ -17690,7 +18305,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { auto castedThis = mModule->Cast(qualifiedLeft->mRight, thisValue, type, BfCastFlags_Explicit); if (castedThis) - thisValue = castedThis; + thisValue = castedThis; //mModule->Fail("Explicit base types can only be used for specifying default interface members", qualifiedLeft->mLeft); } } @@ -17706,10 +18321,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m mResult = BfTypedValue(); } } - } - if (mPropDef != NULL) - thisValue = GetResult(true); + if (mPropDef != NULL) + thisValue = GetResult(true); if (!thisValue.mType) { mModule->Fail("Identifier not found", qualifiedName->mLeft); @@ -17722,13 +18336,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m mResult = BfTypedValue(); } else if (auto identiferExpr = BfNodeDynCast(target)) - { + { if (auto attrIdentifier = BfNodeDynCast(target)) { if (attrIdentifier->mIdentifier != NULL) methodNodeSrc = attrIdentifier->mIdentifier; attributeState.mSrc = attrIdentifier->mAttributes; - attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); + attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifier->mAttributes, attributeState.mTarget); } allowImplicitThis = true; @@ -17802,7 +18416,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m auto primType = (BfPrimitiveType*)typedVal.mType; int64 val = ceDebugger->ValueToInt(typedVal); - int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1)); + int64 bitCount = ceDebugger->ValueToInt(_ResolveArg(1)); int64 andBits = (0x8000000000000000LL) >> ((typedVal.mType->mSize - 8) * 8 + bitCount - 1); int64 resultVal = val & ~andBits; mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, (uint64)resultVal), typedVal.mType); @@ -17840,13 +18454,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef)->ToTypeInstance(); auto fieldDef = typeType->mTypeDef->GetFieldByName("mTypeId"); if (fieldDef != NULL) - { + { int typeId = ceDebugger->ReadMemory((intptr)intVal + typeType->mFieldInstances[fieldDef->mIdx].mDataOffset); type = mModule->mContext->FindTypeById(typeId); } } else - typeName += StrFormat("%lld", intVal); + typeName += StrFormat("%lld", intVal); } } @@ -17894,7 +18508,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { auto addrVal = _ResolveArg(0); auto ceAddrVal = ceDebugger->GetAddr(addrVal); - + CeFunction* ceFunction = NULL; int functionId = 0; if (mModule->mSystem->mPtrSize == 4) @@ -17906,11 +18520,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m CeFunction* checkCeFunction = (CeFunction*)ceAddrVal.mAddr; functionId = checkCeFunction->SafeGetId(); } - + if (mModule->mCompiler->mCeMachine->mFunctionIdMap.TryGetValue(functionId, &ceFunction)) { BfMethodInstance* methodInstance = ceFunction->mMethodInstance; - if (methodInstance != NULL) + if (methodInstance != NULL) { if (targetFunctionName == "__funcTarget") { @@ -17937,18 +18551,18 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m return; } } - + if (targetFunctionName == "__funcTarget") mResult = _ResolveArg(1); else - mResult = addrVal; + mResult = addrVal; return; } } } } else if (auto expr = BfNodeDynCast(target)) - { + { auto innerInvocationResult = mModule->CreateValueFromExpression(expr); if (!innerInvocationResult) { @@ -17956,9 +18570,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m innerInvocationResult = mModule->GetDefaultTypedValue(mModule->mContext->mBfObjectType); } - if (innerInvocationResult.mType->IsVar()) + if (innerInvocationResult.mType->IsVar()) { - mResult = innerInvocationResult; + mResult = innerInvocationResult; return; } @@ -17968,7 +18582,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m auto invocationTypeInst = innerInvocationResult.mType->ToTypeInstance(); if ((invocationTypeInst->mTypeDef->mIsDelegate) || (invocationTypeInst->mTypeDef->mIsFunction)) { - thisValue = innerInvocationResult; + thisValue = innerInvocationResult; } } @@ -17995,15 +18609,15 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m prevAttributeState.Init(mModule->mAttributeState, &attributeState); if ((targetFunctionName != "") && (targetFunctionName[targetFunctionName.length() - 1] == '!')) - { + { targetFunctionName = targetFunctionName.Substring(0, targetFunctionName.length() - 1); InjectMixin(methodNodeSrc, thisValue, allowImplicitThis, targetFunctionName, args, methodGenericArgs); return; - } + } //TODO: We removed this... Messed up with PrimStruct 'this' non-mut errors - + // We moved this until later in MatchMethod, we want the raw target for the GetType optimization, plus we shouldn't do this until we know we won't do a SkipCall /*if (thisValue) { @@ -18039,13 +18653,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m checkTypeInst = checkTypeInst->mBaseType; } } - + SizedArray copiedArgs; for (BfExpression* arg : args) copiedArgs.push_back(arg); BfSizedArray sizedCopiedArgs(copiedArgs); - BfResolvedArgs argValues(&sizedCopiedArgs); - + BfResolvedArgs argValues(&sizedCopiedArgs); + if (mModule->mParentNodeEntry != NULL) { if (auto invocationExpr = BfNodeDynCast(mModule->mParentNodeEntry->mNode)) @@ -18054,9 +18668,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m argValues.mCommas = &invocationExpr->mCommas; argValues.mCloseToken = invocationExpr->mCloseParen; } - } + } - BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes); + BfResolveArgsFlags resolveArgsFlags = (BfResolveArgsFlags)(BfResolveArgsFlag_DeferFixits | BfResolveArgsFlag_AllowUnresolvedTypes); resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamEval); if ((mayBeSkipCall) || (mayBeComptimeCall)) resolveArgsFlags = (BfResolveArgsFlags)(resolveArgsFlags | BfResolveArgsFlag_DeferParamValues); @@ -18068,7 +18682,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m { NOP; } - + BfCheckedKind checkedKind = BfCheckedKind_NotSet; if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL)) { @@ -18092,7 +18706,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if (isCascade) mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_InCascade); ResolveArgValues(argValues, resolveArgsFlags); - + // { // We also apply this right before the actual call, but we need to set the comptime flag earlier @@ -18105,14 +18719,14 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m } mResult = MatchMethod(methodNodeSrc, methodBoundExpr, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, argValues, methodGenericArgs, checkedKind); } - + argValues.HandleFixits(mModule); if (mModule->mAttributeState == &attributeState) - mModule->FinishAttributeState(&attributeState); + mModule->FinishAttributeState(&attributeState); if (isCascade) - { + { if ((outCascadeValue != NULL) && (thisValue.mValue)) { *outCascadeValue = thisValue; @@ -18120,12 +18734,12 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m else { mModule->Fail("Invalid use of cascade operator", cascadeOperatorToken); - } + } } } void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) -{ +{ BfAutoParentNodeEntry autoParentNodeEntry(mModule, invocationExpr); // We need to check for sized array constructor like "uint8[2](1, 2)" @@ -18136,7 +18750,7 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) { checkTarget = indexerExpr->mTarget; } - + SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); auto resolvedType = mModule->ResolveTypeRef(checkTarget, NULL, BfPopulateType_Identity); prevIgnoreError.Restore(); @@ -18144,7 +18758,7 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) if (resolvedType != NULL) { BfType* curType = resolvedType; - + auto checkTarget = invocationExpr->mTarget; while (auto indexerExpr = BfNodeDynCastExact(checkTarget)) { @@ -18188,13 +18802,13 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) InitializedSizedArray((BfSizedArrayType*)curType, invocationExpr->mOpenParen, invocationExpr->mArguments, invocationExpr->mCommas, invocationExpr->mCloseParen, NULL); return; - } + } } auto autoComplete = GetAutoComplete(); auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo); if (autoComplete != NULL) - autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas); + autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas); mModule->UpdateExprSrcPos(invocationExpr); BfMethodGenericArguments methodGenericArgs; @@ -18212,7 +18826,7 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) } SizedArray copiedArgs; for (BfExpression* arg : invocationExpr->mArguments) - copiedArgs.push_back(arg); + copiedArgs.push_back(arg); BfTypedValue cascadeValue; DoInvocation(invocationExpr->mTarget, invocationExpr, copiedArgs, methodGenericArgs, &cascadeValue); @@ -18230,7 +18844,7 @@ void BfExprEvaluator::Visit(BfInvocationExpression* invocationExpr) else autoComplete->mIsCapturingMethodMatchInfo = false; } - + /// Previous check for discard if (cascadeValue) @@ -18241,7 +18855,7 @@ BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMet { bool allowMut = true; if ((propTarget) && (propTarget.mType->IsValueType())) - { + { if (propTarget.IsReadOnly()) { allowMut = false; @@ -18251,7 +18865,7 @@ BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMet mModule->PopulateType(propTarget.mType); if (!propTarget.IsValuelessType()) allowMut = false; - } + } } int bestPri = -1000; @@ -18262,7 +18876,7 @@ BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMet if (methodDef->mMethodType != methodType) continue; - int curPri = 0; + int curPri = 0; if (methodDef->mCheckedKind == checkedKind) { @@ -18296,7 +18910,6 @@ BfMethodDef* BfExprEvaluator::GetPropertyMethodDef(BfPropertyDef* propDef, BfMet { if (methodDef->mMethodType != methodType) continue; - if (methodDef->mCheckedKind == checkedKind) { @@ -18321,13 +18934,13 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m { auto curTypeInst = mPropTarget.mType->ToTypeInstance(); if (mModule->TypeIsSubTypeOf(mModule->mCurTypeInstance, curTypeInst)) - { + { if (methodDef->mBody != NULL) { - // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type. + // This is an explicit call to a default static interface method. We pull the methodDef into our own concrete type. mPropTarget = mModule->GetThis(); return mModule->GetMethodInstance(mModule->mCurTypeInstance, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_ForeignMethodDef, curTypeInst); - } + } } else { @@ -18336,16 +18949,16 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m } } else - { + { auto propTypeInst = mPropTarget.mType->ToTypeInstance(); mModule->PopulateType(propTypeInst, BfPopulateType_DataAndMethods); auto rawMethodInstance = mModule->GetRawMethodInstance(propTypeInst, methodDef); - + if (rawMethodInstance->mVirtualTableIdx == -1) { if (!mModule->mCompiler->mIsResolveOnly) { - // ResolveOnly does not force methods to slot + // ResolveOnly does not force methods to slot BF_ASSERT(rawMethodInstance->mVirtualTableIdx != -1); mModule->Fail(StrFormat("Failed to devirtualize %s", mModule->MethodToString(rawMethodInstance).c_str())); } @@ -18358,11 +18971,14 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m } } } - + if ((mOrigPropTarget) && (mOrigPropTarget.mType != mPropTarget.mType) && ((!mOrigPropTarget.mType->IsGenericParam()) && (mPropTarget.mType->IsInterface()))) { auto checkType = mOrigPropTarget.mType; + + if ((checkType->IsNullable()) && (!mPropTarget.mType->IsNullable())) + checkType = checkType->GetUnderlyingType(); if (checkType->IsPointer()) checkType = ((BfPointerType*)checkType)->mElementType; if (checkType->IsWrappableType()) @@ -18371,7 +18987,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m { auto activeTypeDef = mModule->GetActiveTypeDef(); BfTypeInterfaceEntry* bestIFaceEntry = NULL; - + bool checkedUnderlying = false; auto checkTypeInst = checkType->ToTypeInstance(); while (checkTypeInst != NULL) @@ -18400,7 +19016,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m bool isBetter; bool isWorse; - mModule->CompareDeclTypes(iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse); + mModule->CompareDeclTypes(NULL, iface.mDeclaringType, bestIFaceEntry->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { // Failed @@ -18431,10 +19047,10 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m } } } - + if (bestIFaceEntry != NULL) - { - auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx]; + { + auto ifaceMethodEntry = checkTypeInst->mInterfaceMethodTable[bestIFaceEntry->mStartInterfaceTableIdx + methodDef->mIdx]; BfMethodInstance* bestMethodInstance = ifaceMethodEntry.mMethodRef; if (bestMethodInstance != NULL) { @@ -18443,14 +19059,14 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m //mPropTarget = mModule->Cast( mOrigPropTarget, checkTypeInst); return mModule->GetMethodInstanceAtIdx(ifaceMethodEntry.mMethodRef.mTypeInstance, ifaceMethodEntry.mMethodRef.mMethodNum); } - } + } } mModule->AssertErrorState(); return BfModuleMethodInstance(); } - auto propTypeInst = mPropTarget.mType->ToTypeInstance(); + auto propTypeInst = mPropTarget.mType->ToTypeInstance(); if (propTypeInst == NULL) { @@ -18462,7 +19078,7 @@ BfModuleMethodInstance BfExprEvaluator::GetPropertyMethodInstance(BfMethodDef* m mModule->Fail("INTERNAL ERROR: Invalid property target", mPropSrc); return BfModuleMethodInstance(); } - + return mModule->GetMethodInstance(propTypeInst, methodDef, BfTypeVector(), mPropGetMethodFlags); } @@ -18470,7 +19086,7 @@ void BfExprEvaluator::CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance { auto propTypeInst = mPropTarget.mType->ToTypeInstance(); // If mExplicitInterface is null then we are implicitly calling through an interface - if ((checkProt) && (propTypeInst != NULL) && (methodInstance->GetExplicitInterface() == NULL) && + if ((checkProt) && (propTypeInst != NULL) && (methodInstance->GetExplicitInterface() == NULL) && (!mModule->CheckAccessMemberProtection(propMethodDef->mProtection, propTypeInst))) mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(methodInstance).c_str()), mPropSrc); else if (mPropCheckedKind != methodInstance->mMethodDef->mCheckedKind) @@ -18506,21 +19122,21 @@ bool BfExprEvaluator::HasResult() BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericType) { if ((!mResult) && (mPropDef != NULL)) - { + { bool handled = false; if (mPropTarget.mType->IsGenericTypeInstance()) { auto genericTypeInst = (BfTypeInstance*)mPropTarget.mType; if (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSizedArrayTypeDef)) - { + { if (mPropDef->mName == "Count") { auto sizedType = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[1]; if (sizedType->IsConstExprValue()) { - auto constExprType = (BfConstExprValueType*)sizedType; + auto constExprType = (BfConstExprValueType*)sizedType; mResult = BfTypedValue(mModule->GetConstValue(constExprType->mValue.mInt64), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); - handled = true; + handled = true; } else { @@ -18534,8 +19150,8 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp if (!handled) { - SetAndRestoreValue prevFunctionBindResult(mFunctionBindResult, NULL); - SetAndRestoreValue prevDeferCallRef(mDeferCallRef, NULL); + SetAndRestoreValue prevFunctionBindResult(mFunctionBindResult, NULL); + SetAndRestoreValue prevDeferCallRef(mDeferCallRef, NULL); BfMethodDef* matchedMethod = GetPropertyMethodDef(mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget); if (matchedMethod == NULL) @@ -18555,10 +19171,10 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp if (mPropSrc != NULL) mModule->UpdateExprSrcPos(mPropSrc); - + auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString)) - { + { autoComplete->mResultString = ":"; autoComplete->mResultString += mModule->TypeToString(methodInstance.mMethodInstance->mReturnType); autoComplete->mResultString += " "; @@ -18575,10 +19191,10 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp mResult = mModule->GetDefaultTypedValue(methodInstance.mMethodInstance->mReturnType); } else - { + { SizedArray args; if (!matchedMethod->mIsStatic) - { + { auto owner = methodInstance.mMethodInstance->GetOwner(); bool isTypeMatch = mPropTarget.mType == owner; @@ -18587,7 +19203,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp if ((!isTypeMatch) || ((mPropTarget.mValue.IsFake()) && (!mOrigPropTarget.mValue.IsFake()))) - { + { auto prevPropTarget = mPropTarget; mPropTarget = mModule->Cast(mPropSrc, mOrigPropTarget, owner); @@ -18600,9 +19216,9 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp } if ((mPropGetMethodFlags & BfGetMethodInstanceFlag_DisableObjectAccessChecks) == 0) - mModule->EmitObjectAccessCheck(mPropTarget); - } - + mModule->EmitObjectAccessCheck(mPropTarget); + } + auto callFlags = mPropDefBypassVirtual ? BfCreateCallFlags_BypassVirtual : BfCreateCallFlags_None; mResult = CreateCall(mPropSrc, mPropTarget, mOrigPropTarget, matchedMethod, methodInstance, callFlags, mIndexerValues, NULL); } @@ -18613,12 +19229,12 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp mIndexerValues.clear(); mResultLocalVar = NULL; mResultFieldInstance = NULL; - } + } if (resolveGenericType) ResolveGenericType(); BfTypedValue result = mResult; if (clearResult) - mResult = BfTypedValue(); + mResult = BfTypedValue(); return result; } @@ -18643,9 +19259,9 @@ void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue) // These errors can only be detected during capture time, so we don't ignore them on this pass mModule->mIgnoreErrors = false; } - + int fieldIdx = mResultLocalVarField - 1; - + auto localVar = mResultLocalVar; if (localVar->mCompositeCount > 0) { @@ -18683,6 +19299,8 @@ void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue) undefinedFieldFlags = 0; } } + if (deferredLocalAssignData->mLeftBlockUncond) + isAssigned = true; } if (fieldIdx == -1) @@ -18710,7 +19328,7 @@ void BfExprEvaluator::CheckResultForReading(BfTypedValue& typedValue) } else { - mModule->Fail(StrFormat("Use of unassigned local variable '%s'", localVar->mName.c_str()), mResultLocalVarRefNode); + mModule->Fail(StrFormat("Use of unassigned local variable '%s'", localVar->mName.c_str()), mResultLocalVarRefNode); } } } @@ -18734,7 +19352,7 @@ bool BfExprEvaluator::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* void BfExprEvaluator::MarkResultUsed() { if (mResultLocalVar != NULL) - { + { mResultLocalVar->mReadFromId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } } @@ -18756,7 +19374,7 @@ void BfExprEvaluator::MarkResultAssigned() mModule->mCurMethodState->GetMethodStateForLocal(localVar)->LocalDefined(localVar, fieldIdx + i); //if (localIdx != 0x7FFF) - { + { if (localVar->mCompositeCount > 0) { mModule->Fail(StrFormat("Cannot write to composite '%s', it can only be used in an argument list", localVar->mName.c_str()), mResultLocalVarRefNode); @@ -18767,7 +19385,7 @@ void BfExprEvaluator::MarkResultAssigned() void BfExprEvaluator::MakeResultAsValue() { - // Expressions like parens will turn a variable reference into a simple value + // Expressions like parens will turn a variable reference into a simple value mResultLocalVar = NULL; mResultFieldInstance = NULL; } @@ -18795,7 +19413,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo BfLocalVariable* localVar = NULL; bool isCapturedLocal = false; if (mResultLocalVar != NULL) - { + { localVar = mResultLocalVar; localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } @@ -18804,7 +19422,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo localVar = mModule->GetThisVariable(); } else if (typedVal.IsSplat()) - { + { for (auto checkLocal : mModule->mCurMethodState->mLocals) { if (checkLocal->mAddr == typedVal.mValue) @@ -18812,7 +19430,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo localVar = checkLocal; break; } - } + } } else if (typedVal.mValue.IsArg()) { @@ -18841,7 +19459,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo if (localVar != NULL) { if (!canModify) - { + { BfError* error = NULL; if (localVar->mIsThis) { @@ -18881,14 +19499,14 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode); } else - { + { error = _Fail(StrFormat("Cannot %s 'this' because '%s' is a reference type.", modifyType, mModule->TypeToString(localVar->mResolvedType).c_str()), refNode); } return false; } else if (mResultFieldInstance != NULL) - { + { if (isCapturedLocal) { error = _Fail(StrFormat("Cannot %s read-only captured local variable '%s'. Consider adding by-reference capture specifier [&] to lambda and ensuring that captured value is not read-only.", modifyType, @@ -18923,8 +19541,8 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo error = _Fail(StrFormat("Cannot %s field '%s.%s' within struct method '%s'. Consider adding 'mut' specifier to this method.", modifyType, mModule->TypeToString(mResultFieldInstance->mOwner).c_str(), mResultFieldInstance->GetFieldDef()->mName.c_str(), mModule->MethodToString(mModule->mCurMethodInstance).c_str()), refNode); - } - return false; + } + return false; } } else if (localVar->IsParam()) @@ -18975,22 +19593,20 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo break; } } - - - } + } } - + if (error == NULL) { error = _Fail(StrFormat("Cannot %s read-only local variable '%s'.", modifyType, localVar->mName.c_str()), refNode); } return false; - } + } } else { - // When we are capturing, we need to note that we require capturing by reference here + // When we are capturing, we need to note that we require capturing by reference here localVar->mWrittenToId = mModule->mCurMethodState->GetRootMethodState()->mCurAccessId++; } } @@ -19003,7 +19619,7 @@ bool BfExprEvaluator::CheckModifyResult(BfTypedValue& typedVal, BfAstNode* refNo return false; } - + if ((!skipCopyOnMutate) && (typedVal.IsCopyOnMutate())) typedVal = mModule->CopyValue(typedVal); @@ -19018,20 +19634,20 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) auto condResult = mModule->CreateValueFromExpression(condExpr->mConditionExpression, mModule->GetPrimitiveType(BfTypeCode_Boolean), (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); if (!condResult) return; - + if (condExpr->mTrueExpression == NULL) { mModule->AssertErrorState(); return; - } - + } + if (condExpr->mFalseExpression == NULL) { mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, BfEvalExprFlags_NoCast); mModule->AssertErrorState(); return; } - + bool isConstBranch = false; bool constResult = false; bool constResultUndef = false; @@ -19058,7 +19674,7 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) BfTypedValue actualValue = mModule->CreateValueFromExpression(actualExpr, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast)); BfTypedValue ignoredValue; // - { + { auto curBlock = mModule->mBfIRBuilder->GetInsertBlock(); SetAndRestoreValue ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true); @@ -19093,24 +19709,24 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) auto falseBB = mModule->mBfIRBuilder->CreateBlock("cond.else"); auto endBB = mModule->mBfIRBuilder->CreateBlock("cond.end"); auto contBB = mModule->mBfIRBuilder->CreateBlock("cond.cont"); - + mModule->mBfIRBuilder->CreateCondBr(condResult.mValue, trueBB, falseBB); SetAndRestoreValue prevInCondBlock(mModule->mCurMethodState->mCurScope->mInnerIsConditional, true); bool wantExpectingCast = (mExpectingType != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_NoCast) == 0); - mModule->AddBasicBlock(trueBB); + mModule->AddBasicBlock(trueBB); auto trueValue = mModule->CreateValueFromExpression(condExpr->mTrueExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_CreateConditionalScope)); if ((wantExpectingCast) && (trueValue) && (trueValue.mType != mExpectingType)) { // In some cases like typed primitives - we CAN individually cast each value which it's a constant still, but not after the merging // IE: Color c = isOver ? 0xFF000000 : 0xFFFFFFFF; - // Otherwise the resulting value would just be 'int' which cannot implicitly convert to Color, but each of those ints can be - // a uint32 if converted separately + // Otherwise the resulting value would just be 'int' which cannot implicitly convert to Color, but each of those ints can be + // a uint32 if converted separately auto checkTrueValue = mModule->Cast(condExpr->mTrueExpression, trueValue, mExpectingType, BfCastFlags_SilentFail); if (checkTrueValue) - trueValue = checkTrueValue; + trueValue = checkTrueValue; mModule->FixIntUnknown(trueValue); } auto trueBlockPos = mModule->mBfIRBuilder->GetInsertBlock(); @@ -19122,12 +19738,10 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) { auto checkFalseValue = mModule->Cast(condExpr->mFalseExpression, falseValue, mExpectingType, BfCastFlags_SilentFail); if (checkFalseValue) - falseValue = checkFalseValue; + falseValue = checkFalseValue; mModule->FixIntUnknown(falseValue); } - prevInCondBlock.Restore(); - bool isValid = trueValue && falseValue; if (isValid) @@ -19147,7 +19761,7 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) { BfTypedValue trueToFalse; { - SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos); trueToFalse = mModule->Cast(condExpr->mTrueExpression, trueValue, falseValue.mType); } @@ -19163,12 +19777,14 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) trueValue = trueToFalse; } } - + + prevInCondBlock.Restore(); + mModule->mBfIRBuilder->SetInsertPoint(trueBlockPos); if (isValid) trueValue = mModule->LoadValue(trueValue); mModule->mBfIRBuilder->CreateBr(endBB); - + mModule->mBfIRBuilder->SetInsertPoint(falseBlockPos); if (isValid) falseValue = mModule->LoadValue(falseValue); @@ -19178,7 +19794,7 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) if (!isValid) return; - mModule->mBfIRBuilder->SetInsertPoint(endBB); + mModule->mBfIRBuilder->SetInsertPoint(endBB); BfIRValue phi; if (!trueValue.mType->IsValuelessType()) { @@ -19197,11 +19813,11 @@ void BfExprEvaluator::Visit(BfConditionalExpression* condExpr) mModule->mBfIRBuilder->CreateBr(contBB); mModule->AddBasicBlock(contBB); - mResult = BfTypedValue(phi, trueValue.mType); + mResult = BfTypedValue(phi, trueValue.mType); } void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExpr, DeferredTupleAssignData& deferredTupleAssignData) -{ +{ BfTypeVector fieldTypes; Array fieldNames; @@ -19212,6 +19828,8 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE DeferredTupleAssignData::Entry entry; entry.mExprEvaluator = NULL; entry.mInnerTuple = NULL; + entry.mVarType = NULL; + entry.mVarNameNode = NULL; BfExpression* valueExpr = tupleExpr->mValues[valueIdx]; entry.mExpr = valueExpr; @@ -19226,8 +19844,8 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE else { BfExprEvaluator* exprEvaluator = new BfExprEvaluator(mModule); - entry.mExprEvaluator = exprEvaluator; - + entry.mExprEvaluator = exprEvaluator; + if (valueExpr->IsA()) { resultType = mModule->GetPrimitiveType(BfTypeCode_None); @@ -19241,10 +19859,27 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE } else { - resultType = ResolveTypeRef(varDecl->mTypeRef); + resultType = ResolveTypeRef(varDecl->mTypeRef); if (resultType == NULL) resultType = mModule->GetPrimitiveType(BfTypeCode_Var); } + entry.mVarType = resultType; + } + + if (auto binOpExpr = BfNodeDynCast(valueExpr)) + { + if (binOpExpr->mOp == BfBinaryOp_Multiply) + { + SetAndRestoreValue prevIgnoreError(mModule->mIgnoreErrors, true); + auto resolvedType = mModule->ResolveTypeRef(binOpExpr->mLeft, NULL); + prevIgnoreError.Restore(); + if (resolvedType != NULL) + { + resultType = mModule->CreatePointerType(resolvedType); + entry.mVarType = resultType; + entry.mVarNameNode = binOpExpr->mRight; + } + } } if (resultType == NULL) @@ -19264,14 +19899,14 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE BfPointerType* pointerType = (BfPointerType*)exprEvaluator->mPropTarget.mType; propTypeInst = pointerType->mElementType->ToTypeInstance(); } - + auto setMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertySetter, mPropCheckedKind, mPropTarget); if (setMethod != NULL) { auto methodInstance = mModule->GetMethodInstance(propTypeInst, setMethod, BfTypeVector()); resultType = methodInstance.mMethodInstance->GetParamType(0); } - else + else { auto getMethod = GetPropertyMethodDef(exprEvaluator->mPropDef, BfMethodType_PropertyGetter, mPropCheckedKind, mPropTarget); if (getMethod != NULL) @@ -19299,20 +19934,20 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE } BfTypeInstance* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames, true); - deferredTupleAssignData.mTupleType = tupleType; + deferredTupleAssignData.mTupleType = tupleType; } void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue) -{ +{ BF_ASSERT(rightValue.mType->IsTuple()); auto tupleType = (BfTypeInstance*)rightValue.mType; for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++) - { + { auto& child = deferredTupleAssignData.mChildren[valueIdx]; - BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx]; + BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[valueIdx]; BfTypedValue elementValue; if (fieldInstance->mDataIdx >= 0) - { + { rightValue = mModule->LoadOrAggregateValue(rightValue); mModule->mBfIRBuilder->PopulateType(rightValue.mType); auto extractedValue = mModule->mBfIRBuilder->CreateExtractValue(rightValue.mValue, fieldInstance->mDataIdx); @@ -19333,11 +19968,19 @@ void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* ass } } - if (auto varDecl = BfNodeDynCast(child.mExpr)) + if (child.mVarType != NULL) { - if (!elementValue) - elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType()); - mModule->HandleVariableDeclaration(varDecl, elementValue); + if (auto varDecl = BfNodeDynCast(child.mExpr)) + { + if (!elementValue) + elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType()); + mModule->HandleVariableDeclaration(varDecl, elementValue); + } + else + { + // This handles the 'a*b' disambiguated variable decl case + mModule->HandleVariableDeclaration(child.mVarType, child.mVarNameNode, elementValue); + } } } } @@ -19349,11 +19992,11 @@ void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr) DeferredTupleAssignData deferredTupleAssignData; PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData); BfTypeInstance* tupleType = deferredTupleAssignData.mTupleType; - + BfTypedValue rightValue; if (assignExpr->mRight != NULL) { - rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, tupleType); + rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, tupleType); } if (!rightValue) { @@ -19361,14 +20004,14 @@ void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr) rightValue = mModule->GetDefaultTypedValue(tupleType); } rightValue = mModule->LoadValue(rightValue); - - AssignDeferrredTupleAssignData(assignExpr, deferredTupleAssignData, rightValue); - + + AssignDeferrredTupleAssignData(assignExpr, deferredTupleAssignData, rightValue); + mResult = rightValue; } BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* assignExpr, bool deferBinop, BfTypedValue& leftValue, BfTypedValue& rightValue, bool& evaluatedRight) -{ +{ BfResolvedArgs argValues; auto checkTypeInst = leftValue.mType->ToTypeInstance(); while (checkTypeInst != NULL) @@ -19403,6 +20046,9 @@ BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* { if (!mModule->CanCast(rightValue, paramType)) continue; + + rightValue = mModule->Cast(assignExpr->mLeft, rightValue, paramType); + BF_ASSERT(rightValue); } mModule->SetElementType(assignExpr->mOpToken, BfSourceElementType_Method); @@ -19420,10 +20066,9 @@ BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args); exprEvaluator.PushArg(rightValue, args); exprEvaluator.CreateCall(assignExpr, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args); - return leftValue; + return leftValue; } - checkTypeInst = mModule->GetBaseType(checkTypeInst); } @@ -19432,10 +20077,10 @@ BfTypedValue BfExprEvaluator::PerformAssignment_CheckOp(BfAssignmentExpression* void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue) { - auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp); + auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp); BfExpression* targetNode = assignExpr->mLeft; - + if ((BfNodeIsA(targetNode)) && (!mModule->mCurMethodInstance->mIsUnspecialized)) { // If we have a "mixin = " but there's no mixin target then ignore the assignment @@ -19446,16 +20091,19 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool return; } } - + BfAutoComplete* autoComplete = GetAutoComplete(); bool deferredFixits = false; - if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetFixits)) + + //TODO: Why was this needed? This breaks fixits on target nodes (ie: 'using' field fixit for 'fully quality') + /*if ((autoComplete != NULL) && (autoComplete->mResolveType == BfResolveType_GetFixits)) { SetAndRestoreValue ignoreFixits(autoComplete->mIgnoreFixits, true); VisitChild(targetNode); deferredFixits = true; } - else if (!evaluatedLeft) + else*/ + if (!evaluatedLeft) { if (auto memberReferenceExpr = BfNodeDynCast(targetNode)) { @@ -19464,8 +20112,8 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool else VisitChild(targetNode); } - - if ((!mResult) && (mPropDef == NULL)) + + if ((!mResult) && (mPropDef == NULL)) { if (assignExpr->mRight != NULL) { @@ -19482,9 +20130,9 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } ResolveGenericType(); - auto ptr = mResult; + auto ptr = mModule->RemoveRef(mResult); mResult = BfTypedValue(); - + if (mPropDef != NULL) { bool hasLeftVal = false; @@ -19497,10 +20145,10 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool { // Allow for a ref return on the getter to be used if a setter is not available GetResult(); - + if ((mResult) && (mResult.mKind == BfTypedValueKind_Addr)) { - ptr = mResult; + ptr = mResult; mResult = BfTypedValue(); hasLeftVal = true; } @@ -19514,12 +20162,12 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } if (!hasLeftVal) - { + { auto methodInstance = GetPropertyMethodInstance(setMethod); if (methodInstance.mMethodInstance == NULL) return; //BF_ASSERT(methodInstance.mMethodInstance->mMethodDef == setMethod); - CheckPropFail(setMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0); + CheckPropFail(setMethod, methodInstance.mMethodInstance, (mPropGetMethodFlags & BfGetMethodInstanceFlag_Friend) == 0); auto autoComplete = GetAutoComplete(); if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(mPropSrc)) && (autoComplete->mResolveType == BfResolveType_GetResultString)) @@ -19565,7 +20213,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool if (!convVal) return; } - } + } else { auto wantType = methodInstance.mMethodInstance->GetParamType(0); @@ -19590,7 +20238,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool mPropDef = NULL; return; } - } + } if (!handled) { @@ -19637,14 +20285,14 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } if (toType->IsIntUnknown()) toType = mModule->FixIntUnknown(toType); - + if ((autoComplete != NULL) && (assignExpr->mOpToken != NULL) && (toType != NULL)) autoComplete->CheckEmptyStart(assignExpr->mOpToken, toType); BfExpression* rightExpr = assignExpr->mRight; if (rightExpr == NULL) { - mModule->AssertErrorState(); + mModule->AssertErrorState(); return; } @@ -19654,13 +20302,13 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool { CheckResultForReading(ptr); BfTypedValue leftValue = ptr; - + bool deferBinop = false; BfDeferEvalChecker deferEvalChecker; deferEvalChecker.mDeferLiterals = false; assignExpr->mRight->Accept(&deferEvalChecker); if (deferEvalChecker.mNeedsDeferEval) - deferBinop = true; + deferBinop = true; if (binaryOp == BfBinaryOp_NullCoalesce) { @@ -19678,7 +20326,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast)); } } - + BfResolvedArgs argValues; if ((rightValue) || (deferBinop)) @@ -19693,20 +20341,27 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool else { auto flags = BfBinOpFlag_ForceLeftType; - if (deferBinop) - flags = (BfBinOpFlags)(flags | BfBinOpFlag_DeferRight); - + if (deferBinop) + flags = (BfBinOpFlags)(flags | BfBinOpFlag_DeferRight); + leftValue = mModule->LoadValue(leftValue); - if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(assignExpr->mOpToken, assignExpr->mLeft, assignExpr->mRight, leftValue, leftValue.mType, &ptr))) + if (binaryOp == BfBinaryOp_NullCoalesce) { - return; + if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true)) + { + mModule->CreateValueFromExpression(assignExpr->mRight, ptr.mType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast)); + mResult = leftValue; + return; + } + if (PerformBinaryOperation_NullCoalesce(assignExpr->mOpToken, assignExpr->mLeft, assignExpr->mRight, leftValue, leftValue.mType, &ptr)) + return; } - PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, flags, leftValue, rightValue); + PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, flags, leftValue, rightValue); } } - + convVal = mResult; mResult = BfTypedValue(); @@ -19714,7 +20369,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool return; } else - { + { convVal = rightValue; if (!convVal) @@ -19725,7 +20380,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool { MarkResultAssigned(); return; - } + } } // In the cases like "structVal = GetVal()", the allowDirectStructRetWrite optimization allows us to pass the @@ -19736,16 +20391,16 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool // have the backend ensure that this local value never gets its address taken. bool allowDirectStructWrite = false; - BfExprEvaluator exprEvaluator(mModule); + BfExprEvaluator exprEvaluator(mModule); exprEvaluator.mExpectingType = toType; if (allowDirectStructWrite) - exprEvaluator.mReceivingValue = &ptr; + exprEvaluator.mReceivingValue = &ptr; exprEvaluator.Evaluate(rightExpr, false, false, true); exprEvaluator.CheckResultForReading(exprEvaluator.mResult); - convVal = exprEvaluator.GetResult(); + convVal = exprEvaluator.GetResult(); mModule->FixIntUnknown(convVal); alreadyWritten = (allowDirectStructWrite) && (exprEvaluator.mReceivingValue == NULL); - + if (!convVal) convVal = mModule->GetDefaultTypedValue(toType); @@ -19755,9 +20410,9 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool mResult = convVal; return; } - } - } - + } + } + if (!CheckModifyResult(ptr, assignExpr->mOpToken, "assign to", false, false, true)) { mResult = convVal; @@ -19768,7 +20423,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool ptr.mKind = BfTypedValueKind_Addr; else if (ptr.IsCopyOnMutate()) ptr = mModule->CopyValue(ptr); - + BF_ASSERT(convVal); if ((convVal) && (convVal.mType->IsNull()) && (ptr.mType->IsNullable())) { @@ -19796,7 +20451,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool { auto constant = mModule->mBfIRBuilder->GetConstant(convVal.mValue); if ((constant->mTypeCode == BfTypeCode_NullPtr) || (constant->mConstType == BfConstType_AggZero)) - { + { auto type = ptr.mType; mModule->mBfIRBuilder->CreateMemSet(ptr.mValue, mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_Int8)), mModule->GetConstValue(type->mSize), type->mAlign); @@ -19807,7 +20462,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } // if (ptr.mType->IsMethodRef()) -// { +// { // auto methodRefType = (BfMethodRefType*)ptr.mType; // auto methodInstance = methodRefType->mMethodInstance; // int implicitParamCount = methodInstance->GetImplicitParamCount(); @@ -19824,7 +20479,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool // } // } // else - { + { mModule->mBfIRBuilder->PopulateType(ptr.mType); if (convVal.IsSplat()) @@ -19832,7 +20487,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool //convVal = mModule->AggregateSplat(convVal); mModule->AggregateSplatIntoAddr(convVal, ptr.mValue); } - else + else { if (ptr.mType->IsValuelessType()) { @@ -19857,7 +20512,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool return; } - auto ceContext = mModule->mCompiler->mCeMachine->mCurContext; + auto ceContext = mModule->mCompiler->mCeMachine->mCurContext; if (ceContext->CheckMemory((addr_ce)ceTypedVal.mAddr, convVal.mType->mSize)) { if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) != 0) @@ -19873,7 +20528,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool } } } - + if (!success) { mModule->Fail("Assignment failed", assignExpr); @@ -19910,7 +20565,7 @@ void BfExprEvaluator::Visit(BfAssignmentExpression* assignExpr) } BfAutoParentNodeEntry autoParentNodeEntry(mModule, assignExpr); - + BfTypedValue cascadeValue; PerformAssignment(assignExpr, false, BfTypedValue(), &cascadeValue); if (cascadeValue) @@ -19918,7 +20573,7 @@ void BfExprEvaluator::Visit(BfAssignmentExpression* assignExpr) } void BfExprEvaluator::Visit(BfParenthesizedExpression* parenExpr) -{ +{ VisitChild(parenExpr->mExpression); MakeResultAsValue(); } @@ -19940,12 +20595,12 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken } }; - SizedArray values; - + SizedArray values; + { //bool hasFailed = false; HashSet failedAt; - bool isAllConst = true; + bool isAllConst = true; //bool endUninitialzied = false; @@ -20008,7 +20663,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken if (checkArrayType->mElementType->IsSizedArray()) { if (auto arrayInitExpr = BfNodeDynCast(expr)) - { + { depth++; _GetValues((BfSizedArrayType*)checkArrayType->mElementType, arrayInitExpr->mOpenParen, arrayInitExpr->mValues, arrayInitExpr->mCommas, arrayInitExpr->mCloseParen, ignore); depth--; @@ -20034,11 +20689,11 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken } if (expr != NULL) - { + { auto evalFlags = (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags); - bool tryDefer = false; - if ((checkArrayType->IsComposite()) && + bool tryDefer = false; + if ((checkArrayType->IsComposite()) && ((expr->IsA()) || (expr->IsExact()))) { // We evaluate with a new scope because this expression may create variables that we don't want to be visible to other @@ -20053,7 +20708,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken } if (!elementValue) - elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType); + elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType); if ((!elementValue) || (!CheckAllowValue(elementValue, expr))) elementValue = mModule->GetDefaultTypedValue(checkArrayType->mElementType); @@ -20068,8 +20723,8 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken initValue.mValue = elementValue; initValue.mIsDeferred = deferredValue; values.push_back(initValue); - } - } + } + } } }; @@ -20085,12 +20740,12 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken bool hasUninit = false; for (int idx = 0; idx < checkArrayType->mElementCount; idx++) - { + { BfExpression* expr = NULL; BfTypedValue elementValue; if (idx >= (int)valueExprs.size()) break; - + expr = valueExprs[idx]; if ((BfNodeDynCastExact(expr) != NULL) && (idx == (int)commas.size())) @@ -20158,9 +20813,9 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken elementValue = mModule->LoadValue(elementValue); mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign); - } + } } - + int fillCount = (int)(checkArrayType->mElementCount - valIdx); if (fillCount > 0) { @@ -20236,25 +20891,25 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken elementValue = initValue.mValue; members.push_back(elementValue.mValue); } - + int fillCount = (int)(checkArrayType->mElementCount - valIdx); - if (fillCount > 0) + if (fillCount > 0) { // We just need to insert one default value, it will be duplicated as needed into the backend auto defaultVal = mModule->GetDefaultTypedValue(checkArrayType->GetUnderlyingType()); BF_ASSERT(defaultVal.mValue.IsConst()); - members.push_back(defaultVal.mValue); + members.push_back(defaultVal.mValue); } - + auto allocArrayType = checkArrayType; if (checkArrayType->IsUndefSizedArray()) allocArrayType = mModule->CreateSizedArrayType(checkArrayType->GetUnderlyingType(), (int)members.size()); - + return mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(checkArrayType), members); }; _GetValues(arrayType, openToken, valueExprs, commas, closeToken, false); - + if (!failedAt.IsEmpty()) { mResult = mModule->GetDefaultTypedValue(arrayType, false, BfDefaultValueKind_Addr); @@ -20277,13 +20932,13 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken { if ((mReceivingValue != NULL) && (mReceivingValue->mType == arrayType) && (mReceivingValue->IsAddr())) { - mResult = *mReceivingValue; + mResult = *mReceivingValue; mReceivingValue = NULL; } else { auto arrayValue = mModule->CreateAlloca(arrayType); - mResult = BfTypedValue(arrayValue, arrayType, BfTypedValueKind_TempAddr); + mResult = BfTypedValue(arrayValue, arrayType, BfTypedValueKind_TempAddr); } if (!arrayType->IsValuelessType()) _CreateMemArray(mResult, openToken, valueExprs, commas, closeToken); @@ -20292,15 +20947,15 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken } void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) -{ +{ BfTypeInstance* tupleType = NULL; bool hadFullMatch = false; if ((mExpectingType != NULL) && (mExpectingType->IsTuple())) { tupleType = (BfTypeInstance*)mExpectingType; hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size(); - } - + } + struct InitValue { BfTypedValue mValue; @@ -20346,11 +21001,11 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) hadFullMatch = false; fieldType = NULL; } - } + } } bool tryDefer = false; - if (((fieldType == NULL) || (fieldType->IsComposite())) && + if (((fieldType == NULL) || (fieldType->IsComposite())) && ((valueExpr->IsA()) || (valueExpr->IsExact()))) { tryDefer = true; @@ -20372,8 +21027,8 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) auto checkName = tupleExpr->mNames[valueIdx]; if (checkName != NULL) { - if (checkName->ToString() != fieldInstance->GetFieldDef()->mName) - hadFullMatch = false; + if (checkName->ToString() != fieldInstance->GetFieldDef()->mName) + hadFullMatch = false; } } @@ -20420,11 +21075,11 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) mResult = *mReceivingValue; mReceivingValue = NULL; curTupleValue = mResult.mValue; - } + } else { int valueIdx = -1; - bool isExactConst = true; + bool isExactConst = true; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { @@ -20446,7 +21101,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) } if (isExactConst) - { + { mModule->PopulateType(tupleType); Array irValues; @@ -20466,21 +21121,21 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) if (!val) val = mModule->mBfIRBuilder->CreateConstArrayZero(0); } - + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConstAgg(mModule->mBfIRBuilder->MapType(tupleType), irValues), tupleType); return; } - + curTupleValue = mModule->CreateAlloca(tupleType); mResultIsTempComposite = true; - mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr); + mResult = BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr); } int valueIdx = -1; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { - BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; - ++valueIdx; + BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; + ++valueIdx; if (fieldInstance->mResolvedType->IsValuelessType()) continue; auto typedVal = typedValues[valueIdx]; @@ -20497,7 +21152,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) { // Value was deferred. Allow us to try to init in place BfExpression* valueExpr = tupleExpr->mValues[valueIdx]; - + BfTypedValue memberPtrTypedVal = BfTypedValue(memberVal, fieldInstance->mResolvedType, BfTypedValueKind_Addr); BfExprEvaluator exprEvaluator(mModule); @@ -20512,7 +21167,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) continue; } - typedVal = exprEvaluator.mResult; + typedVal = exprEvaluator.mResult; typedVal = mModule->Cast(valueExpr, typedVal, fieldInstance->mResolvedType); if (!typedVal) { @@ -20521,7 +21176,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) } typedVal = mModule->LoadValue(typedVal); } - + if (typedVal.mType->IsVar()) { // Do nothing @@ -20531,7 +21186,7 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) else mModule->mBfIRBuilder->CreateAlignedStore(typedVal.mValue, memberVal, typedVal.mType->mAlign); } - } + } } BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTokenNode* dotToken) @@ -20544,11 +21199,11 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok mModule->Fail("Null conditional reference not valid for static field references", dotToken); return thisValue; } - + auto opResult = PerformUnaryOperation_TryOperator(thisValue, NULL, BfUnaryOp_NullConditional, dotToken, BfUnaryOpFlag_None); if (opResult) thisValue = opResult; - + if (thisValue.mType->IsGenericParam()) { bool isValid = false; @@ -20559,7 +21214,7 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok if ((genericParams->mTypeConstraint->IsNullable()) || (genericParams->mTypeConstraint->IsPointer()) || (genericParams->mTypeConstraint->IsObjectOrInterface())) - isValid = true; + isValid = true; } if ((genericParams->mGenericParamFlags & (BfGenericParamFlag_Var | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Class)) != 0) @@ -20576,12 +21231,17 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok else if ((thisValue.mType->IsPointer()) || (thisValue.mType->IsObjectOrInterface())) { // Also good - } + } else - { - mModule->Warn(0, StrFormat("Null conditional reference is unnecessary since value type '%s' can never be null", mModule->TypeToString(thisValue.mType).c_str()), dotToken); + { + bool canBeNull = false; + if (thisValue.mType->IsGenericParam()) + canBeNull = true; + + if (!canBeNull) + mModule->Warn(0, StrFormat("Null conditional reference is unnecessary since value type '%s' can never be null", mModule->TypeToString(thisValue.mType).c_str()), dotToken); return thisValue; - } + } thisValue = mModule->LoadValue(thisValue); if (thisValue.mType->IsVar()) @@ -20593,30 +21253,30 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok pendingNullCond = new BfPendingNullConditional(); mModule->mCurMethodState->mPendingNullConditional = pendingNullCond; } - if (!pendingNullCond->mPrevBB) - pendingNullCond->mPrevBB = mModule->mBfIRBuilder->GetInsertBlock(); - + if (!pendingNullCond->mPrevBB) + pendingNullCond->mPrevBB = mModule->mBfIRBuilder->GetInsertBlock(); + if (!pendingNullCond->mDoneBB) pendingNullCond->mDoneBB = mModule->mBfIRBuilder->CreateBlock("nullCond.done"); // We will in the br to checkBB later if (!pendingNullCond->mCheckBB) { - pendingNullCond->mCheckBB = mModule->mBfIRBuilder->CreateBlock("nullCond.check"); + pendingNullCond->mCheckBB = mModule->mBfIRBuilder->CreateBlock("nullCond.check"); mModule->AddBasicBlock(pendingNullCond->mCheckBB); } BfIRValue isNotNull; if (thisValue.mType->IsNullable()) - { + { BfTypeInstance* nullableType = (BfTypeInstance*)thisValue.mType->ToTypeInstance(); auto elementType = nullableType->GetUnderlyingType(); if (elementType->IsValuelessType()) { thisValue = mModule->MakeAddressable(thisValue); BfIRValue hasValuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mHasValue - isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1); + isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1); thisValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), elementType, true); } else @@ -20626,7 +21286,7 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok isNotNull = mModule->mBfIRBuilder->CreateAlignedLoad(hasValuePtr, 1); BfIRValue valuePtr = mModule->mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 1); // mValue thisValue = BfTypedValue(valuePtr, elementType, true); - } + } } else isNotNull = mModule->mBfIRBuilder->CreateIsNotNull(thisValue.mValue); @@ -20634,7 +21294,7 @@ BfTypedValue BfExprEvaluator::SetupNullConditional(BfTypedValue thisValue, BfTok pendingNullCond->mNotNullBBs.Add(notNullBB); mModule->mBfIRBuilder->CreateCondBr(isNotNull, notNullBB, pendingNullCond->mDoneBB); - mModule->AddBasicBlock(notNullBB); + mModule->AddBasicBlock(notNullBB); return thisValue; } @@ -20650,13 +21310,13 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx BfAttributeState attributeState; attributeState.mTarget = (BfAttributeTargets)(BfAttributeTargets_MemberAccess); - + String findName; BfAstNode* nameRefNode = memberRefExpr->mMemberName; if (auto attrIdentifierExpr = BfNodeDynCast(memberRefExpr->mMemberName)) { nameRefNode = attrIdentifierExpr->mIdentifier; - // Don't validate + // Don't validate attributeState.mCustomAttributes = mModule->GetCustomAttributes(attrIdentifierExpr->mAttributes, BfAttributeTargets_SkipValidate); if (nameRefNode != NULL) findName = attrIdentifierExpr->mIdentifier->ToString(); @@ -20667,20 +21327,20 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx mModule->FailAfter("Member name expected", memberRefExpr->mDotToken); defer - ( + ( if (attributeState.mCustomAttributes != NULL) { if (mPropDef != NULL) attributeState.mTarget = (BfAttributeTargets)(attributeState.mTarget | BfAttributeTargets_Invocation); mModule->ValidateCustomAttributes(attributeState.mCustomAttributes, attributeState.mTarget); - } + } ); SetAndRestoreValue prevAttributeState(mModule->mAttributeState, &attributeState); BfTypeInstance* expectingTypeInst = NULL; if (mExpectingType != NULL) - { + { expectingTypeInst = mExpectingType->ToTypeInstance(); if (mExpectingType->IsPointer()) expectingTypeInst = mExpectingType->GetUnderlyingType()->ToTypeInstance(); @@ -20698,7 +21358,7 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx BfAutoComplete* autoComplete = GetAutoComplete(); if (autoComplete != NULL) - { + { SetAndRestoreValue prevFriendSet(autoComplete->mHasFriendSet, (attributeState.mCustomAttributes != NULL) && (attributeState.mCustomAttributes->Contains(mModule->mCompiler->mFriendAttributeTypeDef))); if (memberRefExpr->mTarget == NULL) @@ -20709,7 +21369,7 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx { if (expectingTypeInst != NULL) { - bool allowPrivate = expectingTypeInst == mModule->mCurTypeInstance; + bool allowPrivate = expectingTypeInst == mModule->mCurTypeInstance; if (expectingTypeInst->IsEnum()) autoComplete->AddEnumTypeMembers(expectingTypeInst, filter, false, allowPrivate); autoComplete->AddSelfResultTypeMembers(expectingTypeInst, expectingTypeInst, filter, allowPrivate); @@ -20746,13 +21406,13 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx return; } - if (expectingTypeInst == NULL) + if (expectingTypeInst == NULL) { if (mModule->PreFail()) mModule->Fail(StrFormat("Unqualified dot syntax cannot be used with type '%s'", mModule->TypeToString(mExpectingType).c_str()), nameRefNode); return; } - + BfTypedValue expectingVal(expectingTypeInst); mResult = LookupField(memberRefExpr->mMemberName, expectingVal, findName); if ((mResult) || (mPropDef != NULL)) @@ -20761,10 +21421,11 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot); bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot)); - + bool isArrowLookup = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_Arrow)); + BfIdentifierNode* nameLeft = BfNodeDynCast(memberRefExpr->mTarget); BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName); - if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade)) + if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade) && (!isArrowLookup)) { bool hadError = false; LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError); @@ -20777,20 +21438,20 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx return; } - + BfTypedValue thisValue; if (auto exprTarget = BfNodeDynCast(memberRefExpr->mTarget)) { if (auto typeOfExpr = BfNodeDynCast(memberRefExpr->mTarget)) { if (auto nameIdentifer = BfNodeDynCast(memberRefExpr->mMemberName)) - { + { if (LookupTypeProp(typeOfExpr, nameIdentifer)) return; } } - - //Hm, not using VisitChild broke our ability to write to a field for a not-initialized local struct + + //Hm, not using VisitChild broke our ability to write to a field for a not-initialized local struct VisitChild(memberRefExpr->mTarget); GetResult(); thisValue = mResult; @@ -20822,6 +21483,9 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx if (isNullCondLookup) thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken); + if ((isArrowLookup) && (thisValue)) + thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken); + mResult = LookupField(nameRefNode, thisValue, findName); if ((!mResult) && (mPropDef == NULL)) @@ -20840,6 +21504,13 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx { if (auto targetIdentifier = BfNodeDynCast(memberRefExpr->mMemberName)) { + if ((mBfEvalExprFlags & BfEvalExprFlags_NameOf) != 0) + { + auto typeInst = thisValue.mType->ToTypeInstance(); + if ((typeInst != NULL) && (CheckForMethodName(nameRight, typeInst, findName))) + return; + } + mResult.mType = mModule->ResolveInnerType(thisValue.mType, targetIdentifier, BfPopulateType_Declaration); } } @@ -20857,7 +21528,7 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx if (mModule->PreFail()) { if ((thisValue) && (thisValue.mType->IsPointer()) && (thisValue.mType->GetUnderlyingType()->IsObjectOrInterface())) - mModule->Fail(StrFormat("Members cannot be referenced on type '%s' because the type is a pointer to a reference type (ie: a double-reference).", + mModule->Fail(StrFormat("Members cannot be referenced on type '%s' because the type is a pointer to a reference type (ie: a double-reference).", mModule->TypeToString(thisValue.mType).c_str()), nameRefNode); else if (thisValue) mModule->Fail(StrFormat("Unable to find member '%s' in '%s'", findName.c_str(), mModule->TypeToString(thisValue.mType).c_str()), nameRefNode); @@ -20900,7 +21571,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) target = GetResult(true); if (target) break; - + if (pass == 0) { SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0)); @@ -20916,7 +21587,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) if (!target.HasType()) return; - + if (target.mType->IsGenericParam()) { auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)target.mType); @@ -20948,14 +21619,14 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) // Avoid attempting to apply the current attributes to the indexer arguments SetAndRestoreValue prevAttributeState(mModule->mAttributeState, NULL); - + bool isNullCondLookup = (indexerExpr->mOpenBracket != NULL) && (indexerExpr->mOpenBracket->GetToken() == BfToken_QuestionLBracket); if (isNullCondLookup) target = SetupNullConditional(target, indexerExpr->mOpenBracket); - + if (target.mType->IsVar()) { - mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true); + mResult = BfTypedValue(mModule->GetDefaultValue(target.mType), target.mType, true); return; } @@ -20963,7 +21634,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) { mIndexerValues.clear(); - SizedArray argExprs; + SizedArray argExprs; BfSizedArray sizedArgExprs(indexerExpr->mArguments); BfResolvedArgs argValues(&sizedArgExprs); ResolveArgValues(argValues, (BfResolveArgsFlags)(BfResolveArgsFlag_DeferParamEval | BfResolveArgsFlag_FromIndexer)); @@ -20972,9 +21643,9 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) BfMethodMatcher methodMatcher(indexerExpr->mTarget, mModule, "[]", mIndexerValues, BfMethodGenericArguments()); methodMatcher.mCheckedKind = checkedKind; - + BfMethodDef* methodDef = NULL; - + auto startCheckTypeInst = target.mType->ToTypeInstance(); for (int pass = 0; pass < 2; pass++) @@ -21002,7 +21673,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) auto prop = nextProp; nextProp = nextProp->mNextWithSameName; - //TODO: Match against setMethod (minus last param) if we have no 'get' method + //TODO: Match against setMethod (minus last param) if we have no 'get' method for (auto checkMethod : prop->mMethods) { if (checkMethod->mMethodType != BfMethodType_PropertyGetter) @@ -21025,7 +21696,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) wasCapturingMethodMatchInfo = autoComplete->mIsCapturingMethodMatchInfo; autoComplete->mIsCapturingMethodMatchInfo = false; } - + defer ( if (autoComplete != NULL) @@ -21037,7 +21708,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) if (!methodMatcher.IsMemberAccessible(curCheckType, checkMethod->mDeclaringType)) continue; - + methodMatcher.mCheckedKind = checkedKind; methodMatcher.mTarget = target; bool hadMatch = methodMatcher.CheckMethod(startCheckTypeInst, curCheckType, checkMethod, false); @@ -21059,7 +21730,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) mPropDef = foundProp; if (foundProp->mIsStatic) { - mPropTarget = BfTypedValue(curCheckType); + mPropTarget = BfTypedValue(foundPropTypeInst); } else { @@ -21079,10 +21750,10 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) return; } } - + mModule->Fail("Unable to find indexer property", indexerExpr->mTarget); return; - } + } bool wantsChecks = checkedKind == BfCheckedKind_Checked; if (checkedKind == BfCheckedKind_NotSet) @@ -21127,7 +21798,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) return; if (!indexArgument.mType->IsIntegral()) { - if (indexArgument.mType->IsVar()) + if (indexArgument.mType->IsVar()) { isUndefIndex = true; indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr), false, BfDefaultValueKind_Undef); @@ -21135,7 +21806,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) else { indexArgument = mModule->Cast(indexerExpr->mArguments[0], indexArgument, mModule->GetPrimitiveType(BfTypeCode_IntPtr)); - if (!indexArgument) + if (!indexArgument) indexArgument = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_IntPtr)); } } @@ -21152,7 +21823,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) mModule->PopulateType(target.mType); if (target.mType->IsSizedArray()) - { + { BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)target.mType; auto underlyingType = sizedArrayType->mElementType; if (indexArgument.mValue.IsConst()) @@ -21200,11 +21871,6 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) auto oobFunc = mModule->GetMethodByName(internalType->ToTypeInstance(), "ThrowIndexOutOfRange"); if (oobFunc.mFunc) { - /*if (!mModule->mCompiler->mIsResolveOnly) - { - OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags); - }*/ - if (mModule->mIsComptimeModule) mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc); @@ -21212,16 +21878,16 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) args.push_back(mModule->GetConstValue(0)); mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args); mModule->mBfIRBuilder->CreateUnreachable(); - - mModule->mBfIRBuilder->SetInsertPoint(contBlock); } else { mModule->Fail("System.Internal class must contain method 'ThrowIndexOutOfRange'"); } + + mModule->mBfIRBuilder->SetInsertPoint(contBlock); } } - + // If this is a 'bag of bytes', we should try hard not to have to make this addressable if ((!target.IsAddr()) && (!target.mType->IsSizeAligned())) mModule->MakeAddressable(target); @@ -21231,7 +21897,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) { mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr); } - else if (sizedArrayType->IsValuelessType()) + else if (sizedArrayType->IsValuelessType()) { if (underlyingType->IsValuelessType()) mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), underlyingType, true); @@ -21241,15 +21907,14 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) } } else if (target.IsAddr()) - { + { if (target.mType->IsSizeAligned()) { auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(target.mValue, mModule->GetConstValue(0), indexArgument.mValue); mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); } else - { - + { auto indexResult = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue); mResult = BfTypedValue(indexResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); } @@ -21261,10 +21926,10 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) mModule->Fail("Unable to index value", indexerExpr->mTarget); return; } - + mModule->mBfIRBuilder->PopulateType(target.mType); auto gepResult = mModule->mBfIRBuilder->CreateExtractValue(target.mValue, indexArgument.mValue); - + if ((underlyingType->IsString()) || (underlyingType->IsPointer())) { auto resultConst = mModule->mBfIRBuilder->GetConstant(gepResult); @@ -21279,19 +21944,19 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) gepResult = mModule->GetStringCharPtr(strId); } } - + mResult = BfTypedValue(gepResult, underlyingType, BfTypedValueKind_Value); } } else - { + { target = mModule->LoadValue(target); BfPointerType* pointerType = (BfPointerType*)target.mType; auto underlyingType = pointerType->mElementType; mModule->mBfIRBuilder->PopulateType(underlyingType); if (isUndefIndex) - { + { mResult = mModule->GetDefaultTypedValue(underlyingType, false, BfDefaultValueKind_Addr); } else @@ -21299,11 +21964,11 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) BfIRValue result = mModule->CreateIndexedValue(underlyingType, target.mValue, indexArgument.mValue); mResult = BfTypedValue(result, underlyingType, true); } - } + } } void BfExprEvaluator::Visit(BfUnaryOperatorExpression* unaryOpExpr) -{ +{ BfAutoParentNodeEntry autoParentNodeEntry(mModule, unaryOpExpr); PerformUnaryOperation(unaryOpExpr->mExpression, unaryOpExpr->mOp, unaryOpExpr->mOpToken, BfUnaryOpFlag_None); } @@ -21340,8 +22005,7 @@ void BfExprEvaluator::PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp VisitChild(unaryOpExpr); mExpectingType = prevExpedcting; } - - + BfExprEvaluator::PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags); } @@ -21349,7 +22013,7 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal { if ((!inValue.mType->IsTypeInstance()) && (!inValue.mType->IsGenericParam())) return BfTypedValue(); - + SizedArray args; BfResolvedArg resolvedArg; resolvedArg.mTypedValue = inValue; @@ -21432,7 +22096,7 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal { if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None)) { - return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType); + return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType); } } } @@ -21452,7 +22116,7 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal { if (mModule->CanCast(args[0].mTypedValue, opConstraint.mRightType, isConstraintCheck ? BfCastFlags_IsConstraintCheck : BfCastFlags_None)) { - return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType); + return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), genericParam->mExternType); } } } @@ -21461,7 +22125,7 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal return BfTypedValue(); } - + if ((!baseClassWalker.mMayBeFromInterface) && (opToken != NULL)) mModule->SetElementType(opToken, BfSourceElementType_Method); @@ -21480,15 +22144,15 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal BfTypedValue targetVal = args[0].mTypedValue; BfTypedValue postOpVal; if (isPostOp) - postOpVal = mModule->LoadValue(targetVal); - + postOpVal = mModule->LoadValue(targetVal); + BfTypedValue callTarget; if (!methodMatcher.mBestMethodDef->mIsStatic) { callTarget = targetVal; args.Clear(); } - + BfTypedValue result; if (isConstraintCheck) { @@ -21510,8 +22174,8 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal BF_ASSERT(mModule->IsInGeneric()); result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType); } - - if ((methodMatcher.mBestMethodInstance) && + + if ((methodMatcher.mBestMethodInstance) && ((findOp == BfUnaryOp_Increment) || (findOp == BfUnaryOp_Decrement))) { if (methodMatcher.mBestMethodInstance.mMethodInstance->mIsIntrinsic) @@ -21524,18 +22188,18 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal } } else - { + { if (!result.mType->IsValuelessType()) { if (targetVal.IsAddr()) { result = mModule->LoadValue(result); mModule->mBfIRBuilder->CreateStore(result.mValue, targetVal.mValue); - } + } } } } - + if (postOpVal) result = postOpVal; return result; @@ -21544,17 +22208,17 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags) { BfAstNode* propSrc = mPropSrc; - BfTypedValue propTarget = mOrigPropTarget; + BfTypedValue origPropTarget = mOrigPropTarget; + BfTypedValue propTarget = mPropTarget; BfPropertyDef* propDef = mPropDef; SizedArray indexerVals = mIndexerValues; BfTypedValue writeToProp; GetResult(); if (!mResult) - return; + return; - if (mResult.mType->IsRef()) - mResult.mType = mResult.mType->GetUnderlyingType(); + mResult = mModule->RemoveRef(mResult); if (mResult.mType->IsVar()) { @@ -21596,7 +22260,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, CheckResultForReading(mResult); auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean); auto value = mModule->LoadValue(mResult); - value = mModule->Cast(unaryOpExpr, value, boolType); + value = mModule->Cast(unaryOpExpr, value, boolType); if (!value) { mResult = BfTypedValue(); @@ -21606,9 +22270,9 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, } break; case BfUnaryOp_Positive: - return; + return; case BfUnaryOp_Negate: - { + { CheckResultForReading(mResult); auto value = mModule->LoadValue(mResult); if (!value) @@ -21622,7 +22286,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, value.mType = value.mType->GetUnderlyingType(); if (value.mType->IsIntegral()) - { + { auto primType = (BfPrimitiveType*)value.mType; auto wantType = primType; @@ -21645,7 +22309,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, { int64 i64Val = constantInt->getSExtValue(); // This is a special case where the user entered -0x80000000 (maxint) but we thought "0x80000000" was a uint in the parser - // which would get upcasted to an int64 for this negate. Properly bring back down to an int32 + // which would get upcasted to an int64 for this negate. Properly bring back down to an int32 if ((primType->mTypeDef->mTypeCode == BfTypeCode_UInt32) && (i64Val == -0x80000000LL)) { mResult = BfTypedValue(mModule->GetConstValue((int)i64Val), mModule->GetPrimitiveType(BfTypeCode_Int32)); @@ -21683,11 +22347,11 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, else if (value.mType->IsFloat()) mResult = BfTypedValue(mModule->mBfIRBuilder->CreateNeg(value.mValue), origType); else - numericFail = true; + numericFail = true; } break; case BfUnaryOp_InvertBits: - { + { CheckResultForReading(mResult); auto value = mModule->LoadValue(mResult); if (!value) @@ -21705,9 +22369,9 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, } break; case BfUnaryOp_AddressOf: - { + { MarkResultUsed(); - + mModule->FixIntUnknown(mResult); mModule->PopulateType(mResult.mType); auto ptrType = mModule->CreatePointerType(mResult.mType); @@ -21728,7 +22392,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, } break; case BfUnaryOp_Dereference: - { + { CheckResultForReading(mResult); if (!mResult.mType->IsPointer()) { @@ -21761,20 +22425,20 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, auto derefTarget = mModule->LoadValue(mResult); BfPointerType* pointerType = (BfPointerType*)derefTarget.mType; - auto resolvedType = pointerType->mElementType; + auto resolvedType = pointerType->mElementType; mModule->PopulateType(resolvedType); - if (resolvedType->IsValuelessType()) + if (resolvedType->IsValuelessType()) mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedType, true); else mResult = BfTypedValue(derefTarget.mValue, resolvedType, true); } break; - case BfUnaryOp_PostIncrement: - case BfUnaryOp_Increment: - { + case BfUnaryOp_PostIncrement: + case BfUnaryOp_Increment: + { CheckResultForReading(mResult); auto ptr = mResult; - //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken))) + //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken))) if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "increment"))) return; BfTypedValue origTypedVal = mModule->LoadValue(ptr, NULL, mIsVolatileReference); @@ -21787,7 +22451,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfPointerType* ptrType = (BfPointerType*)ptr.mType; BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); constValue = mModule->GetConstValue(ptrType->mElementType->GetStride(), intPtrType); - + auto i8PtrType = mModule->mBfIRBuilder->GetPointerTo(mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8)); BfIRValue origPtrValue = mModule->mBfIRBuilder->CreateBitCast(origVal, i8PtrType); BfIRValue newPtrValue = mModule->mBfIRBuilder->CreateInBoundsGEP(origPtrValue, constValue); @@ -21800,7 +22464,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, { numericFail = true; break; - } + } if ((ptr.mType->IsIntegral()) || (ptr.mType->IsEnum()) || (ptr.mType->IsFloat())) { resultValue = mModule->mBfIRBuilder->CreateAdd(origVal, constValue/*, "inc"*/); @@ -21809,7 +22473,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, { numericFail = true; break; - } + } } if ((propDef != NULL) && (!ptr.IsAddr())) writeToProp = BfTypedValue(resultValue, ptr.mType); @@ -21826,7 +22490,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, { CheckResultForReading(mResult); auto ptr = mResult; - //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken))) + //if ((propDef == NULL) && (!mModule->CheckModifyValue(ptr, opToken))) //return; if ((propDef == NULL) && (!CheckModifyResult(ptr, opToken, "decrement"))) return; @@ -21877,7 +22541,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, else mResult = BfTypedValue(resultValue, ptr.mType, false); } - break; + break; case BfUnaryOp_Ref: case BfUnaryOp_Mut: { @@ -21888,10 +22552,10 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, } CheckResultForReading(mResult); - - if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsComposite()) && (!mResult.mType->IsGenericParam())) + + if ((unaryOp == BfUnaryOp_Mut) && (!mResult.mType->IsValueType()) && (!mResult.mType->IsGenericParam())) { - // Non-composite types are already mutable, leave them alone... + // Non-valuetypes types are already mutable, leave them alone... break; } @@ -21903,14 +22567,14 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, return; } } - + if ((mBfEvalExprFlags & BfEvalExprFlags_AllowRefExpr) == 0) { mResult = BfTypedValue(); mModule->Fail(StrFormat("Invalid usage of '%s' expression", BfGetOpName(unaryOp)), opToken); return; } - + ResolveGenericType(); if (mResult.mType->IsVar()) break; @@ -21918,7 +22582,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, } break; case BfUnaryOp_Out: - { + { if (!CheckModifyResult(mResult, unaryOpExpr, "use 'out' on")) { // Just leave the non-ref version in mResult @@ -21933,7 +22597,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, if (mInsidePendingNullable) { - // 'out' inside null conditionals never actually causes a definite assignment... + // 'out' inside null conditionals never actually causes a definite assignment... } else MarkResultAssigned(); @@ -21945,11 +22609,11 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, mResult = BfTypedValue(mResult.mValue, mModule->CreateRefType(mResult.mType, BfRefType::RefKind_Out)); } break; - case BfUnaryOp_Params: - { - bool allowParams = (mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) != 0; + case BfUnaryOp_Params: + { + bool allowParams = (mBfEvalExprFlags & BfEvalExprFlags_AllowParamsExpr) != 0; if (allowParams) - { + { if ((mResultLocalVar != NULL) && (mResultLocalVar->mCompositeCount >= 0)) // Delegate params { allowParams = true; @@ -21980,7 +22644,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, else { mModule->Fail("Illegal use of 'params' expression", opToken); - } + } } break; case BfUnaryOp_Cascade: @@ -22000,7 +22664,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, mModule->mBfIRBuilder->CreateStore(value.mValue, mModule->mBfIRBuilder->CreateInBoundsGEP(mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 1), 0, 1)); mModule->mBfIRBuilder->CreateStore(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int8, 1), mModule->mBfIRBuilder->CreateInBoundsGEP(alloca, 0, 2)); mResult = BfTypedValue(alloca, indexType, BfTypedValueKind_Addr); - } + } } break; case BfUnaryOp_PartialRangeUpTo: @@ -22056,14 +22720,20 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, SizedArray args; if (!setMethod->mIsStatic) - PushThis(propSrc, propTarget, methodInstance.mMethodInstance, args); - //args.push_back(propTarget.mValue); + { + auto usePropTarget = propTarget; + if (origPropTarget.mType == methodInstance.mMethodInstance->GetOwner()) + usePropTarget = origPropTarget; + else + BF_ASSERT(propTarget.mType == methodInstance.mMethodInstance->GetOwner()); + PushThis(propSrc, usePropTarget, methodInstance.mMethodInstance, args); + } for (int paramIdx = 0; paramIdx < (int)indexerVals.size(); paramIdx++) { auto val = mModule->Cast(propSrc, indexerVals[paramIdx].mTypedValue, methodInstance.mMethodInstance->GetParamType(paramIdx)); if (!val) - return; + return; PushArg(val, args); } @@ -22079,18 +22749,18 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp { mModule->AssertErrorState(); return; - } + } if (!leftValue) - { + { if (!rightValue) mModule->CreateValueFromExpression(rightExpression, mExpectingType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); return; } if (leftValue.mType->IsRef()) leftValue.mType = leftValue.mType->GetUnderlyingType(); - + if ((binaryOp == BfBinaryOp_ConditionalAnd) || (binaryOp == BfBinaryOp_ConditionalOr)) - { + { if (mModule->mCurMethodState->mDeferredLocalAssignData != NULL) mModule->mCurMethodState->mDeferredLocalAssignData->BreakExtendChain(); if (mModule->mCurMethodState->mCurScope->mScopeKind == BfScopeKind_StatementTarget) @@ -22133,7 +22803,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp if (isConstBranch) { if ((constResult) || (HasVariableDeclaration(rightExpression))) - { + { // Only right side rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); mResult = rightValue; @@ -22148,7 +22818,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp } } else - { + { auto rhsBB = mModule->mBfIRBuilder->CreateBlock("land.rhs"); auto endBB = mModule->mBfIRBuilder->CreateBlock("land.end"); @@ -22168,11 +22838,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp } } else - { + { // Put variables in here into a 'possibly assigned' but never commit it. - // Because if we had "if ((Get(out a)) || (GetOther(out a))" then the LHS would already set it as defined, so + // Because if we had "if ((Get(out a)) || (GetOther(out a))" then the LHS would already set it as defined, so // the RHS is inconsequential - BfDeferredLocalAssignData deferredLocalAssignData; + BfDeferredLocalAssignData deferredLocalAssignData; deferredLocalAssignData.ExtendFrom(mModule->mCurMethodState->mDeferredLocalAssignData, false); deferredLocalAssignData.mVarIdBarrier = mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId; SetAndRestoreValue prevDLA(mModule->mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); @@ -22190,11 +22860,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp } if (isConstBranch) - { + { if ((constResult) && (!HasVariableDeclaration(rightExpression))) { - // Always true - SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); + // Always true + SetAndRestoreValue prevIgnoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue prevInConstIgnore(mModule->mCurMethodState->mCurScope->mInConstIgnore, true); rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType); @@ -22207,7 +22877,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp } } else - { + { auto rhsBB = mModule->mBfIRBuilder->CreateBlock("lor.rhs"); auto endBB = mModule->mBfIRBuilder->CreateBlock("lor.end"); @@ -22216,12 +22886,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp mModule->mBfIRBuilder->CreateCondBr(leftValue.mValue, endBB, rhsBB); - mModule->AddBasicBlock(rhsBB); + mModule->AddBasicBlock(rhsBB); rightValue = mModule->CreateValueFromExpression(rightExpression, boolType, (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags)); mModule->mBfIRBuilder->CreateBr(endBB); auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock(); - mModule->AddBasicBlock(endBB); + mModule->AddBasicBlock(endBB); auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(boolType), 2); mModule->mBfIRBuilder->AddPhiIncoming(phi, mModule->GetConstValue(1, boolType), prevBB); if (rightValue) @@ -22240,7 +22910,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp if ((binaryOp == BfBinaryOp_NullCoalesce) && (PerformBinaryOperation_NullCoalesce(opToken, leftExpression, rightExpression, leftValue, wantType, NULL))) return; - + BfType* rightWantType = wantType; if (origWantType->IsIntUnknown()) rightWantType = NULL; @@ -22258,9 +22928,22 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo) { - if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject()))) + if ((leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())) || (leftValue.mType->IsNullable())) { - leftValue = mModule->LoadValue(leftValue); + leftValue = mModule->LoadOrAggregateValue(leftValue); + + BfType* nullableElementType = NULL; + BfIRValue nullableHasValue; + BfTypedValue nullableExtractedLeftValue; + if (leftValue.mType->IsNullable()) + { + nullableElementType = leftValue.mType->GetUnderlyingType(); + nullableHasValue = mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, nullableElementType->IsValuelessType() ? 1 : 2); // has_value + if (!nullableElementType->IsValuelessType()) + nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->CreateExtractValue(leftValue.mValue, 1), nullableElementType); // value + else + nullableExtractedLeftValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), nullableElementType); + } if (leftValue.mValue.IsConst()) { @@ -22279,7 +22962,7 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, return true; } - auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); + auto prevBB = mModule->mBfIRBuilder->GetInsertBlock(); auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs"); auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end"); auto lhsBB = endBB; @@ -22287,16 +22970,17 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, auto endLhsBB = prevBB; BfIRValue isNull; - if (leftValue.mType->IsFunction()) + if (nullableHasValue) + isNull = mModule->mBfIRBuilder->CreateCmpEQ(nullableHasValue, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0)); + else 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->AddBasicBlock(rhsBB); BfTypedValue rightValue; - - + if (assignTo != NULL) rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_CreateConditionalScope)); else @@ -22307,10 +22991,18 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, mModule->AssertErrorState(); return true; } + + if ((assignTo == NULL) && (leftValue.mType->IsNullable()) && (!rightValue.mType->IsNullable())) + { + if (wantType == leftValue.mType) + wantType = nullableElementType; + leftValue = nullableExtractedLeftValue; + } + rightValue = mModule->LoadValue(rightValue); - + if (assignTo == NULL) - { + { auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail); if (rightToLeftValue) { @@ -22333,7 +23025,7 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken); leftValue = mModule->GetDefaultTypedValue(rightValue.mType); } - + mModule->mBfIRBuilder->CreateBr(endBB); endLhsBB = mModule->mBfIRBuilder->GetInsertBlock(); mModule->mBfIRBuilder->SetInsertPoint(rhsBB); @@ -22345,11 +23037,11 @@ bool BfExprEvaluator::PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, mModule->mBfIRBuilder->CreateBr(endBB); auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock(); - + // Actually add CondBr at start mModule->mBfIRBuilder->SetInsertPoint(prevBB); mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, lhsBB); - + mModule->AddBasicBlock(endBB); if (assignTo != NULL) @@ -22422,13 +23114,13 @@ bool BfExprEvaluator::PerformBinaryOperation_Numeric(BfAstNode* leftExpression, } void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExpression* rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags) -{ +{ if ((binaryOp == BfBinaryOp_Range) || (binaryOp == BfBinaryOp_ClosedRange)) { auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); bool isIndexExpr = false; - BfTypeDef* typeDef = NULL; + BfTypeDef* typeDef = NULL; if (auto unaryOpExpr = BfNodeDynCast(leftExpression)) if (unaryOpExpr->mOp == BfUnaryOp_FromEnd) isIndexExpr = true; @@ -22436,14 +23128,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp isIndexExpr = true; if (auto unaryOpExpr = BfNodeDynCast(rightExpression)) if (unaryOpExpr->mOp == BfUnaryOp_FromEnd) - isIndexExpr = true; + isIndexExpr = true; if (isIndexExpr) typeDef = mModule->mCompiler->mIndexRangeTypeDef; else typeDef = (binaryOp == BfBinaryOp_Range) ? mModule->mCompiler->mRangeTypeDef : mModule->mCompiler->mClosedRangeTypeDef; - auto allocType = mModule->ResolveTypeDef(typeDef)->ToTypeInstance(); + auto allocType = mModule->ResolveTypeDef(typeDef)->ToTypeInstance(); auto alloca = mModule->CreateAlloca(allocType); BfTypedValueExpression leftTypedValueExpr; @@ -22518,7 +23210,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp { leftValue = mModule->CreateValueFromExpression(leftExpression, mExpectingType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast | BfEvalExprFlags_AllowIntUnknown)); } - PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue); + PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, leftValue); } bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue) @@ -22542,7 +23234,7 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, return false; BfTypeCode typeCode = ((BfPrimitiveType*)checkType)->mTypeDef->mTypeCode; - + int64 minValue = 0; int64 maxValue = 0; switch (typeCode) @@ -22563,7 +23255,7 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, minValue = -0x8000000000000000LL; maxValue = 0x7FFFFFFFFFFFFFFFLL; break; - case BfTypeCode_UInt8: + case BfTypeCode_UInt8: maxValue = 0xFF; break; case BfTypeCode_UInt16: @@ -22574,31 +23266,31 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, break; default: return false; - } + } int constResult = -1; if (typeCode == BfTypeCode_UInt64) - { + { switch (binaryOp) { case BfBinaryOp_Equality: case BfBinaryOp_StrictEquality: if (rightConst->mInt64 < minValue) - constResult = 0; + constResult = 0; break; case BfBinaryOp_InEquality: case BfBinaryOp_StrictInEquality: if (rightConst->mInt64 < minValue) - constResult = 1; + constResult = 1; break; case BfBinaryOp_LessThan: if (rightConst->mInt64 <= minValue) - constResult = 0; + constResult = 0; break; case BfBinaryOp_LessThanOrEqual: if (rightConst->mInt64 < minValue) - constResult = 0; - break; + constResult = 0; + break; default: break; } return false; @@ -22648,7 +23340,7 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, default: break; } } - + if (constResult == 0) { mModule->Warn(0, "The result of this operation is always 'false'", opToken); @@ -22661,7 +23353,7 @@ bool BfExprEvaluator::CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), mModule->GetPrimitiveType(BfTypeCode_Boolean)); return true; } - + return false; } @@ -22713,7 +23405,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) { - forceLeftType = true; + forceLeftType = true; } if (rightValue.mType->IsRef()) @@ -22721,9 +23413,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod BfType* origLeftType = leftValue.mType; BfType* origRightType = rightValue.mType; - + mModule->FixIntUnknown(leftValue, rightValue); - + // Prefer floats, prefer chars int leftCompareSize = leftValue.mType->mSize; if (leftValue.mType->IsFloat()) @@ -22732,14 +23424,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod leftCompareSize += 0x100; if (!leftValue.mType->IsPrimitiveType()) leftCompareSize += 0x1000; - + int rightCompareSize = rightValue.mType->mSize; if (rightValue.mType->IsFloat()) rightCompareSize += 0x10; if (rightValue.mType->IsChar()) rightCompareSize += 0x100; if (!rightValue.mType->IsPrimitiveType()) - rightCompareSize += 0x1000; + rightCompareSize += 0x1000; if ((leftValue.mType->IsTypeInstance()) && (rightValue.mType->IsTypeInstance())) { @@ -22753,12 +23445,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } - auto resultType = leftValue.mType; + auto resultType = leftValue.mType; if (!forceLeftType) { bool handled = false; - BfType* expectingType = mExpectingType; + BfType* expectingType = mExpectingType; if (leftValue.mType == rightValue.mType) { @@ -22774,7 +23466,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod handled = true; } else - { + { // If one of these is a constant that can be converted into a smaller type, then do that if (rightValue.mValue.IsConst()) { @@ -22833,14 +23525,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((!resultType->IsPointer()) && (rightValue.mType->IsPointer())) resultType = rightValue.mType; } - } + } bool explicitCast = false; BfTypedValue* resultTypedValue; BfTypedValue* otherTypedValue; BfType* otherType; BfAstNode* resultTypeSrc; - BfAstNode* otherTypeSrc; + BfAstNode* otherTypeSrc; if (resultType == leftValue.mType) { @@ -22850,7 +23542,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod otherTypeSrc = rightExpression; otherType = otherTypedValue->mType; } - else + else { resultTypedValue = &rightValue; resultTypeSrc = rightExpression; @@ -22894,7 +23586,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod std::swap(resultType, otherType); } } - + BfIRValue convLeftValue; BfIRValue convRightValue; @@ -22902,14 +23594,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod { bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual); if (isComparison) - mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean), false, BfDefaultValueKind_Addr); + mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Boolean), false, BfDefaultValueKind_Addr); else if (mExpectingType != NULL) mResult = mModule->GetDefaultTypedValue(mExpectingType, false, BfDefaultValueKind_Addr); else mResult = mModule->GetDefaultTypedValue(resultType, false, BfDefaultValueKind_Addr); return; } - + if ((otherType->IsNull()) && (BfBinOpEqualityCheck(binaryOp))) { bool isEquality = (binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality); @@ -22919,7 +23611,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod auto boolType = mModule->GetPrimitiveType(BfTypeCode_Boolean); if (resultType->IsNullable()) - { + { auto elementType = resultType->GetUnderlyingType(); mModule->PopulateType(elementType); if (elementType->IsValuelessType()) @@ -22941,12 +23633,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (isEquality) hasValueValue = mModule->mBfIRBuilder->CreateNot(hasValueValue); mResult = BfTypedValue(hasValueValue, boolType); - } + } return; } if (resultType->IsNull()) - { + { // Null always equals null mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 1 : 0, boolType), boolType); return; @@ -22955,15 +23647,15 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (!mModule->IsInSpecializedSection()) { //CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type '' - mModule->Warn(BfWarning_CS0472_ValueTypeNullCompare, - StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null", + mModule->Warn(BfWarning_CS0472_ValueTypeNullCompare, + StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null", isEquality ? "false" : "true", mModule->TypeToString(resultType).c_str()), otherTypeSrc); } - // Valuetypes never equal null + // Valuetypes never equal null mResult = BfTypedValue(mModule->GetConstValue(isEquality ? 0 : 1, boolType), boolType); return; - } + } } // Check for constant equality checks (mostly for strings) @@ -22991,7 +23683,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod int eqResult = mModule->mBfIRBuilder->CheckConstEquality(leftValue.mValue, rightValue.mValue); if (eqResult != -1) - { + { bool isEqual = eqResult == 1; if ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)) isEqual = !isEqual; @@ -23001,7 +23693,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } - if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) || + if ((leftValue.mType->IsTypeInstance()) || (leftValue.mType->IsGenericParam()) || (rightValue.mType->IsTypeInstance()) || (rightValue.mType->IsGenericParam())) { // As an optimization, we don't call user operator overloads for null checks @@ -23016,14 +23708,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((leftConstant != NULL) && (leftConstant->IsNull())) skipOpOverload = true; } - + if (!rightValue.IsAddr()) { auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue); if ((rightConstant != NULL) && (rightConstant->IsNull())) skipOpOverload = true; } - } + } if ((binaryOp == BfBinaryOp_Add) && (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef))) { @@ -23031,13 +23723,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((leftValue.mValue.IsConst()) && (rightValue.mValue.IsConst())) skipOpOverload = true; } - + if (!skipOpOverload) - { + { BfBinaryOp findBinaryOp = binaryOp; bool isComparison = (binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_LessThanOrEqual); - + for (int pass = 0; pass < 2; pass++) { BfBinaryOp oppositeBinaryOp = BfGetOppositeBinaryOp(findBinaryOp); @@ -23071,7 +23763,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } SizedArray args; - + if (pass == 0) { args.push_back(leftArg); @@ -23082,8 +23774,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod args.push_back(rightArg); args.push_back(leftArg); } - - auto checkLeftType = leftValue.mType; + + auto checkLeftType = leftValue.mType; auto checkRightType = rightValue.mType; BfMethodMatcher methodMatcher(opToken, mModule, "", args, BfMethodGenericArguments()); @@ -23091,7 +23783,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod methodMatcher.mBfEvalExprFlags = BfEvalExprFlags_NoAutoComplete; BfBaseClassWalker baseClassWalker(checkLeftType, checkRightType, mModule); - bool invertResult = false; + bool invertResult = false; BfType* operatorConstraintReturnType = NULL; bool wasTransformedUsage = (pass == 1); @@ -23103,7 +23795,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (checkType == NULL) break; - bool foundExactMatch = false; + bool foundExactMatch = false; SizedArray oppositeOperatorDefs; for (auto operatorDef : checkType->mTypeDef->mOperators) @@ -23115,7 +23807,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (allowOp) { foundOp = true; - + if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType)) continue; @@ -23138,11 +23830,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false)) { auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, operatorDef); - auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments, + auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments, mModule->mCurTypeInstance); if (returnType != NULL) { - operatorConstraintReturnType = returnType; + operatorConstraintReturnType = returnType; foundExactMatch = true; } } @@ -23159,7 +23851,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } else if ((operatorDef->mOperatorDeclaration->mBinOp == oppositeBinaryOp) || (operatorDef->mOperatorDeclaration->mBinOp == overflowBinaryOp)) - oppositeOperatorDefs.Add(operatorDef); + oppositeOperatorDefs.Add(operatorDef); } if ((((methodMatcher.mBestMethodDef == NULL) && (operatorConstraintReturnType == NULL)) || (!foundExactMatch)) && (!oppositeOperatorDefs.IsEmpty())) @@ -23188,7 +23880,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false)) { auto rawMethodInstance = mModule->GetRawMethodInstance(checkType, oppositeOperatorDef); - auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments, + auto returnType = mModule->ResolveGenericType(rawMethodInstance->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments, mModule->mCurTypeInstance); if (returnType != NULL) { @@ -23203,7 +23895,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod else { if (methodMatcher.CheckMethod(NULL, checkType, oppositeOperatorDef, false)) - { + { methodMatcher.mSelfType = entry.mSrcType; if (oppositeBinaryOp != BfBinaryOp_None) wasTransformedUsage = true; @@ -23212,7 +23904,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } } - + bool hadMatch = (methodMatcher.mBestMethodDef != NULL); if ((methodMatcher.mBestMethodDef != NULL) && ((flags & BfBinOpFlag_IgnoreOperatorWithWrongResult) != 0)) @@ -23235,13 +23927,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (hadMatch) { methodMatcher.FlushAmbiguityError(); - + auto matchedOp = ((BfOperatorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration)->mBinOp; - bool invertResult = matchedOp == oppositeBinaryOp; - + bool invertResult = matchedOp == oppositeBinaryOp; + auto methodDef = methodMatcher.mBestMethodDef; auto autoComplete = GetAutoComplete(); - bool wasCapturingMethodInfo = false; + bool wasCapturingMethodInfo = false; if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(opToken))) { auto operatorDecl = BfNodeDynCast(methodDef->mMethodDeclaration); @@ -23251,7 +23943,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((wasTransformedUsage) && (methodDef->mCommutableKind != BfCommutableKind_Operator)) { - auto error = mModule->Warn(BfWarning_BF4206_OperatorCommutableUsage, "Transformed operator usage requires 'Commutable' attribute to be added to the operator declaration", opToken); + auto error = mModule->Warn(BfWarning_BF4206_OperatorCommutableUsage, "Transformed operator usage requires 'Commutable' attribute to be added to the operator declaration", opToken); if ((error != NULL) && (methodDef->GetRefNode() != NULL)) mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See operator declaration"), methodDef->GetRefNode()); } @@ -23293,7 +23985,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mResult = mModule->LoadValue(mResult); if (mResult.mType != intType) mResult = mModule->GetDefaultTypedValue(intType); - + auto zeroVal = mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0); auto useBinaryOp = binaryOp; @@ -23331,9 +24023,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } auto _CheckBinaryOp = [&](BfGenericParamInstance* genericParam) - { + { for (auto& opConstraint : genericParam->mOperatorConstraints) - { + { BfType* returnType = genericParam->mExternType; bool works = false; if (opConstraint.mBinaryOp == findBinaryOp) @@ -23344,7 +24036,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod works = true; } } - + if ((isComparison) && (opConstraint.mBinaryOp == BfBinaryOp_Compare)) { if ((mModule->CanCast(args[0].mTypedValue, opConstraint.mLeftType)) && @@ -23370,7 +24062,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mResult = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), returnType); return true; } - } + } return false; }; @@ -23382,28 +24074,28 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod { auto genericParam = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; if (_CheckBinaryOp(genericParam)) - return; + return; } } - + // Check type generic constraints if ((mModule->mCurTypeInstance->IsGenericTypeInstance()) && (mModule->mCurTypeInstance->IsUnspecializedType())) { SizedArray genericParams; mModule->GetActiveTypeGenericParamInstances(genericParams); for (auto genericParam : genericParams) - { + { if (_CheckBinaryOp(genericParam)) - return; + return; } } - + if (pass == 1) - break; - + break; + auto flippedBinaryOp = BfGetFlippedBinaryOp(findBinaryOp); if (flippedBinaryOp != BfBinaryOp_None) - findBinaryOp = flippedBinaryOp; + findBinaryOp = flippedBinaryOp; } bool resultHandled = false; @@ -23436,7 +24128,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod { auto expectedType = resultType; if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) - expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); + expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); rightValue = mModule->CreateValueFromExpression(BfNodeDynCast(rightExpression), expectedType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast)); if (rightValue) PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, (BfBinOpFlags)(flags & ~BfBinOpFlag_DeferRight), leftValue, rightValue); @@ -23448,11 +24140,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mResult = mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var)); return; } - + if (resultType->IsPointer() && otherType->IsPointer()) { if ((binaryOp == BfBinaryOp_Add) && (resultType == otherType) && - (resultType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) + (resultType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) { AddStrings(leftValue, rightValue, opToken); return; @@ -23460,10 +24152,10 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod //TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) - { + { if (!mModule->CanCast(*otherTypedValue, resultType)) { - mModule->Fail(StrFormat("Operands '%s' and '%s' are not comparable types.", + mModule->Fail(StrFormat("Operands '%s' and '%s' are not comparable types.", mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken); return; @@ -23477,8 +24169,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mModule->Warn(0, "Subtracting pointers to zero-sized elements will always result in zero", opToken); mResult = mModule->GetDefaultTypedValue(intPtrType); } - else - { + else + { convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler)); convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler)); BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue); @@ -23495,13 +24187,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if (mModule->PreFail()) mModule->Fail("Invalid operation on pointers", opToken); return; - } - + } + if ((!BfBinOpEqualityCheck(binaryOp)) || (resultType != otherType)) { resultType = mModule->GetPrimitiveType(BfTypeCode_UIntPtr); explicitCast = true; - } + } } else if (resultType->IsPointer()) { @@ -23528,18 +24220,18 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod _OpFail(); return; } - + auto underlyingType = resultType->GetUnderlyingType(); if ((underlyingType->IsSizedArray()) && (!mModule->IsInSpecializedSection())) mModule->Warn(0, "Performing arithmetic on a pointer to a sized array. Consider performing arithmetic on an element pointer if this is not intended.", resultTypeSrc); - BfIRValue addValue = otherTypedValue->mValue; - if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize)) + BfIRValue addValue = otherTypedValue->mValue; + if ((!otherTypedValue->mType->IsSigned()) && (otherTypedValue->mType->mSize < mModule->mSystem->mPtrSize)) addValue = mModule->mBfIRBuilder->CreateNumericCast(addValue, false, BfTypeCode_UIntPtr); if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) { - if (resultTypeSrc == rightExpression) + if (resultTypeSrc == rightExpression) mModule->Fail("Cannot subtract a pointer from an integer", resultTypeSrc); addValue = mModule->mBfIRBuilder->CreateNeg(addValue); @@ -23548,33 +24240,33 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mModule->PopulateType(underlyingType); if (underlyingType->IsValuelessType()) { - if (!mModule->IsInSpecializedSection()) - mModule->Warn(0, "Adding to a pointer to a zero-sized element has no effect", opToken); + if (!mModule->IsInSpecializedSection()) + mModule->Warn(0, "Adding to a pointer to a zero-sized element has no effect", opToken); mResult = *resultTypedValue; return; } - + mModule->mBfIRBuilder->PopulateType(underlyingType); - mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType); + mResult = BfTypedValue(mModule->CreateIndexedValue(underlyingType, resultTypedValue->mValue, addValue), resultType); return; - } - + } + if ((resultType->IsFunction()) || (resultType->IsPointer()) || (resultType->IsObject()) || (resultType->IsInterface()) || (resultType->IsGenericParam())) { - if ((binaryOp == BfBinaryOp_Add) && - (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) && + if ((binaryOp == BfBinaryOp_Add) && + (resultType->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) && (otherType->IsInstanceOf(mModule->mCompiler->mStringTypeDef))) { - AddStrings(leftValue, rightValue, opToken); + AddStrings(leftValue, rightValue, opToken); return; } - + if (!BfGetBinaryOpPrecendence(binaryOp)) { //mModule->Fail("Invalid operation for objects", opToken); _OpFail(); return; - } + } if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality)) { @@ -23606,7 +24298,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod { auto convertedValue = mModule->Cast(otherTypeSrc, *otherTypedValue, resultType, BfCastFlags_NoBox); if (!convertedValue) - return; + return; convertedValue = mModule->LoadValue(convertedValue); if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality)) mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(resultTypedValue->mValue, convertedValue.mValue), mModule->GetPrimitiveType(BfTypeCode_Boolean)); @@ -23616,15 +24308,15 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } - } - + } + if (resultType->IsTypedPrimitive()) { bool needsOtherCast = true; if (otherType != resultType) - { + { if ((otherType->IsPrimitiveType()) && (!otherType->IsValuelessType())) - { + { // Allow zero comparisons to match all typed primitives if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)) { @@ -23651,7 +24343,25 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } auto underlyingType = resultType->GetUnderlyingType(); - + + if ((binaryOp == BfBinaryOp_Subtract) && (otherTypedValue->mType == resultType)) + { + intptr maxDist = 0; + auto resultTypeInstance = resultType->ToTypeInstance(); + if ((resultTypeInstance != NULL) && (resultTypeInstance->mTypeInfoEx != NULL)) + maxDist = resultTypeInstance->mTypeInfoEx->mMaxValue - resultTypeInstance->mTypeInfoEx->mMinValue; + + if (maxDist >= 0x80000000UL) + resultType = mModule->GetPrimitiveType(BfTypeCode_Int64); + else if (maxDist >= 0x8000) + resultType = mModule->GetPrimitiveType(BfTypeCode_Int32); + else if (maxDist >= 0x80) + resultType = mModule->GetPrimitiveType(BfTypeCode_Int16); + else + resultType = mModule->GetPrimitiveType(BfTypeCode_Int8); + underlyingType = resultType; + } + BfIRValue convResultValue; if (resultTypedValue->mType == resultType) convResultValue = mModule->LoadValue(*resultTypedValue).mValue; @@ -23665,17 +24375,17 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod convOtherValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, underlyingType, BfCastFlags_Explicit); if ((!underlyingType->IsValuelessType()) && ((!convResultValue) || (!convOtherValue))) - return; + return; if (resultTypedValue == &leftValue) PerformBinaryOperation(underlyingType, convResultValue, convOtherValue, binaryOp, opToken); else PerformBinaryOperation(underlyingType, convOtherValue, convResultValue, binaryOp, opToken); if (mResult.mType == underlyingType) - mResult.mType = resultType; + mResult.mType = resultType; return; } - + auto _CallValueTypeEquals = [&]() { BfModuleMethodInstance moduleMethodInstance; @@ -23709,14 +24419,14 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod resolvedArg.mTypedValue = rightValue; argValues.push_back(resolvedArg); mResult = CreateCall(opToken, BfTypedValue(), BfTypedValue(), moduleMethodInstance.mMethodInstance->mMethodDef, moduleMethodInstance, BfCreateCallFlags_None, argValues); - if ((mResult) && + if ((mResult) && ((binaryOp == BfBinaryOp_InEquality) || (binaryOp == BfBinaryOp_StrictInEquality))) mResult.mValue = mModule->mBfIRBuilder->CreateNot(mResult.mValue); return true; } return false; }; - + //if (((leftValue.mType->IsComposite()) || (leftValue.mType->IsObject()))) if (((resultType->IsComposite()) || (resultType->IsObject()))) @@ -23730,12 +24440,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod // We only do this for tuples, because we would allow an implicit struct // truncation if we allow it for all structs, which would result in only // the base class's fields being compared - if (mModule->CanCast(rightValue, leftValue.mType)) + if (mModule->CanCast(rightValue, leftValue.mType)) rightValue = mModule->Cast(opToken, rightValue, leftValue.mType, BfCastFlags_Explicit); else if (mModule->CanCast(leftValue, rightValue.mType)) leftValue = mModule->Cast(opToken, leftValue, rightValue.mType, BfCastFlags_Explicit); } - + if (leftValue.mType == rightValue.mType) { if (BfBinOpEqualityCheck(binaryOp)) @@ -23757,7 +24467,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod // Valueless types always compare as 'equal' if we can ensure no members could have an equality operator overload if (leftValue.mType->IsComposite()) { - mModule->PopulateType(leftValue.mType); + mModule->PopulateType(leftValue.mType); if (leftValue.mType->IsValuelessType()) { bool mayHaveEqualOverload = false; @@ -23811,7 +24521,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } else - { + { bool handled = false; for (int pass = 0; pass < 2; pass++) @@ -23831,7 +24541,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } } } - + if (!handled) { if ((leftValue.mType->IsUndefSizedArray()) || (rightValue.mType->IsUndefSizedArray())) @@ -23857,8 +24567,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod mModule->TypeToString(rightValue.mType).c_str()), opToken); return; } - } - } + } + } if (resultType->IsMethodRef() && otherType->IsMethodRef()) { @@ -23878,9 +24588,9 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } } - + if (resultType->IsIntegral()) - { + { if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) { if (rightValue.mValue.IsConst()) @@ -23908,11 +24618,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod (binaryOp == BfBinaryOp_StrictInEquality); if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) - { + { // For shifts we have more lenient rules - shifts are naturally limited so any int type is equally valid if (rightValue.mType->IsIntegral()) explicitCast = true; - } + } else if (((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract)) && (resultType->IsChar()) && (otherType->IsInteger())) { // charVal += intVal; @@ -23939,7 +24649,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } else { - if (((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) && + if (((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract)) && (resultType->IsChar()) && (otherType->IsChar())) { // "wchar - char" subtraction will always fit into int32, because of unicode range @@ -23949,10 +24659,10 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod else if ((otherType->IsChar()) && ((binaryOp == BfBinaryOp_Add) || (binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowAdd) || (binaryOp == BfBinaryOp_OverflowSubtract))) { - mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'", + mModule->Fail(StrFormat("Cannot perform operation between types '%s' and '%s'", mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken); - } + } } } else if ((!resultType->IsSigned()) && (binaryOp == BfBinaryOp_Subtract) && (!forceLeftType)) @@ -23962,7 +24672,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod if ((resultType->IsChar()) && (resultType->mSize == 4)) { // "wchar - wchar" subtraction will always fit into int32, because of unicode range - resultType = mModule->GetPrimitiveType(BfTypeCode_Int32); + resultType = mModule->GetPrimitiveType(BfTypeCode_Int32); } else { @@ -23985,7 +24695,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod } else if (resultType->IsChar()) { - bool canDoOp = + bool canDoOp = (binaryOp == BfBinaryOp_BitwiseAnd) || (binaryOp == BfBinaryOp_BitwiseOr) || ((binaryOp >= BfBinaryOp_Equality) && (binaryOp <= BfBinaryOp_Compare)); @@ -23995,13 +24705,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod return; } } - } + } if (!convLeftValue) - convLeftValue = mModule->CastToValue(leftExpression, leftValue, resultType, + convLeftValue = mModule->CastToValue(leftExpression, leftValue, resultType, explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None); if (!convRightValue) - convRightValue = mModule->CastToValue(rightExpression, rightValue, resultType, + convRightValue = mModule->CastToValue(rightExpression, rightValue, resultType, explicitCast ? (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler) : BfCastFlags_None); PerformBinaryOperation(resultType, convLeftValue, convRightValue, binaryOp, opToken); @@ -24010,7 +24720,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken) { if (resultType->IsValuelessType()) - { + { switch (binaryOp) { case BfBinaryOp_Equality: @@ -24025,12 +24735,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL return; default: break; - } + } } if ((!convLeftValue) || (!convRightValue)) return; - + if (resultType->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)resultType; @@ -24084,7 +24794,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL } if (resultType->IsIntegral()) - { + { switch (binaryOp) { case BfBinaryOp_BitwiseAnd: @@ -24100,15 +24810,15 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShl(convLeftValue, convRightValue), resultType); mModule->CheckRangeError(resultType, opToken); return; - case BfBinaryOp_RightShift: - mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShr(convLeftValue, convRightValue, resultType->IsSigned()), resultType); + case BfBinaryOp_RightShift: + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateShr(convLeftValue, convRightValue, resultType->IsSigned()), resultType); return; default: break; } } - + if ((resultType->IsChar()) && - ((binaryOp == BfBinaryOp_Multiply) || + ((binaryOp == BfBinaryOp_Multiply) || (binaryOp == BfBinaryOp_OverflowMultiply) || (binaryOp == BfBinaryOp_Divide) || (binaryOp == BfBinaryOp_Modulus))) @@ -24159,7 +24869,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL if (binaryOp != BfBinaryOp_OverflowMultiply) mModule->CheckRangeError(resultType, opToken); break; - case BfBinaryOp_Divide: + case BfBinaryOp_Divide: { bool isZero = false; if (convRightValue.IsConst()) @@ -24177,34 +24887,34 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL mResult = BfTypedValue(mModule->mBfIRBuilder->CreateDiv(convLeftValue, convRightValue, resultType->IsSigned()), resultType); } break; - case BfBinaryOp_Modulus: + case BfBinaryOp_Modulus: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateRem(convLeftValue, convRightValue, resultType->IsSigned()), resultType); break; case BfBinaryOp_Equality: case BfBinaryOp_StrictEquality: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpEQ(convLeftValue, convRightValue), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; - case BfBinaryOp_InEquality: + case BfBinaryOp_InEquality: case BfBinaryOp_StrictInEquality: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpNE(convLeftValue, convRightValue), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; - case BfBinaryOp_LessThan: + case BfBinaryOp_LessThan: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned()), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; case BfBinaryOp_LessThanOrEqual: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSigned()), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; case BfBinaryOp_GreaterThan: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned()), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; case BfBinaryOp_GreaterThanOrEqual: mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSigned()), - mModule->GetPrimitiveType(BfTypeCode_Boolean)); + mModule->GetPrimitiveType(BfTypeCode_Boolean)); break; case BfBinaryOp_Compare: { @@ -24230,7 +24940,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL else if ((resultType->IsIntegralOrBool()) && (resultType->mSize < intType->mSize)) { auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr); - auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr); + auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType); } else @@ -24268,13 +24978,13 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL if (mModule->PreFail()) mModule->Fail("Invalid operation", opToken); break; - } + } } void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) { BfAutoParentNodeEntry autoParentNodeEntry(mModule, binOpExpr); - + // There are a few binary operations that could actually be casts followed by an unary operation // We can't determine that until we know whether the identifier in the parens is a typename or not // (double)-1.0 (intptr)&val (BaseStruct)*val @@ -24324,7 +25034,7 @@ void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) } } - if ((binOpExpr->mOp == BfBinaryOp_LeftShift) || (binOpExpr->mOp == BfBinaryOp_RightShift) || + if ((binOpExpr->mOp == BfBinaryOp_LeftShift) || (binOpExpr->mOp == BfBinaryOp_RightShift) || (binOpExpr->mOp == BfBinaryOp_BitwiseAnd) || (binOpExpr->mOp == BfBinaryOp_BitwiseOr) || (binOpExpr->mOp == BfBinaryOp_ExclusiveOr)) { @@ -24359,4 +25069,4 @@ void BfExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) } PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, BfBinOpFlag_None); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index ca9ce83b..630ab57e 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -7,7 +7,7 @@ NS_BF_BEGIN enum BfArgFlags { - BfArgFlag_None = 0, + BfArgFlag_None = 0, BfArgFlag_DelegateBindAttempt = 1, BfArgFlag_LambdaBindAttempt = 2, BfArgFlag_UnqualifiedDotAttempt = 4, @@ -21,7 +21,9 @@ enum BfArgFlags BfArgFlag_UninitializedExpr = 0x400, BfArgFlag_StringInterpolateFormat = 0x800, BfArgFlag_StringInterpolateArg = 0x1000, - BfArgFlag_Cascade = 0x2000 + BfArgFlag_Cascade = 0x2000, + BfArgFlag_Volatile = 0x8000, + BfArgFlag_Finalized = 0x10000, }; enum BfResolveArgsFlags @@ -57,9 +59,10 @@ class BfResolvedArg public: BfTypedValue mTypedValue; BfTypedValue mUncastedTypedValue; + BfIdentifierNode* mNameNode; BfType* mResolvedType; BfAstNode* mExpression; - BfArgFlags mArgFlags; + BfArgFlags mArgFlags; BfType* mExpectedType; BfType* mBestBoundType; bool mWantsRecalc; @@ -67,6 +70,7 @@ public: public: BfResolvedArg() { + mNameNode = NULL; mResolvedType = NULL; mExpression = NULL; mArgFlags = BfArgFlag_None; @@ -83,10 +87,10 @@ public: struct BfResolvedArgs { - SizedArray mResolvedArgs; + SizedArray mResolvedArgs; BfTokenNode* mOpenToken; const BfSizedArray* mArguments; - const BfSizedArray* mCommas; + const BfSizedArray* mCommas; BfTokenNode* mCloseToken; public: @@ -130,8 +134,7 @@ public: mCloseToken = NULL; } - void HandleFixits(BfModule* module); - + void HandleFixits(BfModule* module); }; class BfGenericInferContext @@ -141,13 +144,13 @@ public: BfModule* mModule; BfTypeVector* mCheckMethodGenericArguments; SizedArray mPrevArgValues; - int mInferredCount; + int mInferredCount; public: BfGenericInferContext() { mModule = NULL; - mInferredCount = 0; + mInferredCount = 0; } bool AddToCheckedSet(BfType* argType, BfType* wantType); @@ -162,13 +165,13 @@ public: struct BfMethodGenericArguments { - BfSizedArray* mArguments; + BfSizedArray* mArguments; bool mIsPartial; bool mIsOpen; // Ends with ... BfMethodGenericArguments() { - mArguments = NULL; + mArguments = NULL; mIsPartial = false; mIsOpen = false; } @@ -194,63 +197,65 @@ public: { BackupMatchKind_None, BackupMatchKind_TooManyArgs, - BackupMatchKind_EarlyMismatch, + BackupMatchKind_EarlyMismatch, BackupMatchKind_PartialLastArgMatch }; - + public: BfAstNode* mTargetSrc; BfTypedValue mTarget; BfTypedValue mOrigTarget; BfModule* mModule; BfTypeDef* mActiveTypeDef; - String mMethodName; + String mMethodName; BfMethodInstance* mInterfaceMethodInstance; SizedArrayImpl& mArguments; BfType* mCheckReturnType; BfMethodType mMethodType; BfCheckedKind mCheckedKind; - bool mHadExplicitGenericArguments; + Array*>* mUsingLists; + bool mHasArgNames; + bool mHadExplicitGenericArguments; bool mHadOpenGenericArguments; bool mHadPartialGenericArguments; - bool mHasVarArguments; + bool mHasVarArguments; bool mHadVarConflictingReturnType; bool mBypassVirtual; bool mAllowImplicitThis; bool mAllowImplicitRef; bool mAllowImplicitWrap; bool mAllowStatic; - bool mAllowNonStatic; - bool mSkipImplicitParams; + bool mAllowNonStatic; + bool mSkipImplicitParams; bool mAutoFlushAmbiguityErrors; BfEvalExprFlags mBfEvalExprFlags; - int mMethodCheckCount; - BfType* mExplicitInterfaceCheck; + int mMethodCheckCount; + BfType* mExplicitInterfaceCheck; MatchFailKind mMatchFailKind; - - BfTypeVector mCheckMethodGenericArguments; + + BfTypeVector mCheckMethodGenericArguments; BfType* mSelfType; // Only when matching interfaces when 'Self' needs to refer back to the implementing type BfMethodDef* mBackupMethodDef; - BackupMatchKind mBackupMatchKind; + BackupMatchKind mBackupMatchKind; int mBackupArgMatchCount; BfMethodDef* mBestMethodDef; - BfTypeInstance* mBestMethodTypeInstance; + BfTypeInstance* mBestMethodTypeInstance; BfMethodInstance* mBestRawMethodInstance; BfModuleMethodInstance mBestMethodInstance; SizedArray mBestMethodGenericArgumentSrcs; BfTypeVector mBestMethodGenericArguments; BfTypeVector mExplicitMethodGenericArguments; bool mFakeConcreteTarget; - Array mAmbiguousEntries; + Array mAmbiguousEntries; public: BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType = NULL, BfResolveArgFlags flags = BfResolveArgFlag_None); bool InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs); void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute, - BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute, + BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute, bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail); - void FlushAmbiguityError(); + void FlushAmbiguityError(); bool IsType(BfTypedValue& val, BfType* type); int GetMostSpecificType(BfType* lhs, BfType* rhs); // 0, 1, or -1 @@ -268,8 +273,6 @@ public: bool IsVarCall(BfType*& outReturnType); }; - - class BfBaseClassWalker { public: @@ -313,8 +316,8 @@ class BfFunctionBindResult { public: BfTypedValue mOrigTarget; - BfTypedValue mTarget; - BfIRValue mFunc; + BfTypedValue mTarget; + BfIRValue mFunc; BfMethodInstance* mMethodInstance; BfType* mBindType; bool mSkipThis; @@ -325,7 +328,7 @@ public: public: BfFunctionBindResult() - { + { mMethodInstance = NULL; mBindType = NULL; mSkipMutCheck = false; @@ -338,8 +341,10 @@ public: struct DeferredTupleAssignData { struct Entry - { + { BfExpression* mExpr; + BfType* mVarType; + BfAstNode* mVarNameNode; BfExprEvaluator* mExprEvaluator; DeferredTupleAssignData* mInnerTuple; }; @@ -353,8 +358,8 @@ struct DeferredTupleAssignData enum BfImplicitParamKind { BfImplicitParamKind_General, - BfImplicitParamKind_GenericMethodMember, - BfImplicitParamKind_GenericTypeMember, + BfImplicitParamKind_GenericMethodMember, + BfImplicitParamKind_GenericTypeMember, BfImplicitParamKind_GenericTypeMember_Addr, }; @@ -403,11 +408,11 @@ public: BfGetMethodInstanceFlags mPropGetMethodFlags; BfCheckedKind mPropCheckedKind; BfPropertyDef* mPropDef; - BfType* mExpectingType; + BfType* mExpectingType; BfAttributeState* mPrefixedAttributeState; - BfTypedValue* mReceivingValue; + BfTypedValue* mReceivingValue; BfFunctionBindResult* mFunctionBindResult; - SizedArray mIndexerValues; + SizedArray mIndexerValues; BfAstNode* mDeferCallRef; BfScopeData* mDeferScopeAlloc; bool mUsedAsStatement; @@ -425,20 +430,21 @@ public: BfExprEvaluator(BfModule* module); ~BfExprEvaluator(); + bool CheckForMethodName(BfAstNode* refNode, BfTypeInstance* typeInst, const StringImpl& findName); bool IsVar(BfType* type, bool forceIgnoreWrites = false); void GetLiteral(BfAstNode* refNode, const BfVariant& variant); - void FinishExpressionResult(); - virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode); - BfAutoComplete* GetAutoComplete(); + void FinishExpressionResult(); + virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode); + BfAutoComplete* GetAutoComplete(); bool IsComptime(); bool IsConstEval(); bool IsComptimeEntry(); int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false); BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken); - void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true); + void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true); BfType* BindGenericType(BfAstNode* node, BfType* bindType); BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); - void ResolveGenericType(); + void ResolveGenericType(); void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags = BfResolveArgsFlag_None); void ResolveAllocTarget(BfAllocTarget& allocTarget, BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL); BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal, BfIdentifierNode* paramNameNode = NULL); @@ -446,21 +452,21 @@ public: BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef); void CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt); bool HasResult(); - BfTypedValue GetResult(bool clearResult = false, bool resolveGenericType = false); + BfTypedValue GetResult(bool clearResult = false, bool resolveGenericType = false); void CheckResultForReading(BfTypedValue& typedValue); void MarkResultUsed(); void MarkResultAssigned(); - void MakeResultAsValue(); + void MakeResultAsValue(); bool CheckIsBase(BfAstNode* checkNode); bool CheckModifyResult(BfTypedValue& typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false, bool skipCopyOnMutate = false); bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc); BfTypedValue LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInline); BfTypedValue LoadField(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfFieldDef* fieldDef, BfLookupFieldFlags flags); - BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None); + BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None); void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode); void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL); void LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError = NULL); - void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError); + void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError); void LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError); bool CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue); void AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode); @@ -475,47 +481,48 @@ public: BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL); void AddCallDependencies(BfMethodInstance* methodInstance); void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc); - BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret = NULL, BfCreateCallFlags callFlags = BfCreateCallFlags_None); + BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret = NULL, BfCreateCallFlags callFlags = BfCreateCallFlags_None, BfType* origTargetType = NULL); BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, BfCreateCallFlags callFlags, SizedArrayImpl& argValues, BfTypedValue* argCascade = NULL); BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target); void MakeBaseConcrete(BfTypedValue& typedValue); void SplatArgs(BfTypedValue value, SizedArrayImpl& irArgs); void PushArg(BfTypedValue argVal, SizedArrayImpl& irArgs, bool disableSplat = false, bool disableLowering = false, bool isIntrinsic = false, bool createCompositeCopy = false); void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl& irArgs, bool skipMutCheck = false); - BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, + BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL); BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues); - BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name, + BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name, BfResolvedArgs& argValue, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet); - BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target); + BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target); BfModuleMethodInstance GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType = NULL); BfModuleMethodInstance GetSelectedMethod(BfMethodMatcher& methodMatcher); bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail); bool HasVariableDeclaration(BfAstNode* checkNode); - void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue = NULL); - int GetMixinVariable(); + void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray& args, const BfMethodGenericArguments& methodGenericArgs, BfTypedValue* outCascadeValue = NULL); + int GetMixinVariable(); void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType); void InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray& arguments, const BfMethodGenericArguments& methodGenericArgs); void SetMethodElementType(BfAstNode* target); BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx); BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind = BfImplicitParamKind_General, const BfTypedValue& methodRefTarget = BfTypedValue()); bool CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod = NULL, BfType* origMethodExpectingType = NULL, BfTypeVector* methodGenericArgumentsSubstitute = NULL); - bool IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams = false); - BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType); + bool IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams = false); + BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType); void ConstResolve(BfExpression* expr); void ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray& values, const BfSizedArray& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl& dimLengths, int dim, bool& hasFailed); BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget); - void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor); - void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic); + void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor); + void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic); + BfTypedValue TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken); void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags); BfTypedValue PerformUnaryOperation_TryOperator(const BfTypedValue& inValue, BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags); - void PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags); - BfTypedValue PerformAssignment_CheckOp(BfAssignmentExpression* assignExpr, bool deferBinop, BfTypedValue& leftValue, BfTypedValue& rightValue, bool& evaluatedRight); - void PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue = NULL); + void PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags); + BfTypedValue PerformAssignment_CheckOp(BfAssignmentExpression* assignExpr, bool deferBinop, BfTypedValue& leftValue, BfTypedValue& rightValue, bool& evaluatedRight); + void PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue = NULL); void PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExr, DeferredTupleAssignData& deferredTupleAssignData); void AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue); - void DoTupleAssignment(BfAssignmentExpression* assignExpr); - void FinishDeferredEvals(SizedArrayImpl& argValues); + void DoTupleAssignment(BfAssignmentExpression* assignExpr); + void FinishDeferredEvals(SizedArrayImpl& argValues); void FinishDeferredEvals(BfResolvedArgs& argValues); bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName); void DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token); @@ -526,15 +533,16 @@ public: void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType); ////////////////////////////////////////////////////////////////////////// - + virtual void Visit(BfErrorNode* errorNode) override; virtual void Visit(BfTypeReference* typeRef) override; virtual void Visit(BfAttributedExpression* attribExpr) override; + virtual void Visit(BfNamedExpression* namedExpr) override; virtual void Visit(BfBlock* blockExpr) override; virtual void Visit(BfVariableDeclaration* varDecl) override; virtual void Visit(BfCaseExpression* caseExpr) override; virtual void Visit(BfTypedValueExpression* typedValueExpr) override; - virtual void Visit(BfLiteralExpression* literalExpr) override; + virtual void Visit(BfLiteralExpression* literalExpr) override; virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression) override; virtual void Visit(BfIdentifierNode* identifierNode) override; virtual void Visit(BfAttributedIdentifierNode* attrIdentifierNode) override; @@ -544,12 +552,13 @@ public: virtual void Visit(BfMixinExpression* mixinExpr) override; virtual void Visit(BfSizedArrayCreateExpression* createExpr) override; virtual void Visit(BfInitializerExpression* initExpr) override; - virtual void Visit(BfCollectionInitializerExpression* initExpr) override; + virtual void Visit(BfCollectionInitializerExpression* initExpr) override; virtual void Visit(BfTypeOfExpression* typeOfExpr) override; virtual void Visit(BfSizeOfExpression* sizeOfExpr) override; virtual void Visit(BfAlignOfExpression* alignOfExpr) override; virtual void Visit(BfStrideOfExpression* strideOfExpr) override; virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override; + virtual void Visit(BfNameOfExpression* nameOfExpr) override; virtual void Visit(BfIsConstExpression* isConstExpr) override; virtual void Visit(BfDefaultExpression* defaultExpr) override; virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override; @@ -560,7 +569,7 @@ public: virtual void Visit(BfLambdaBindExpression* lambdaBindExpr) override; virtual void Visit(BfObjectCreateExpression* objCreateExpr) override; virtual void Visit(BfBoxExpression* boxExpr) override; - virtual void Visit(BfInvocationExpression* invocationExpr) override; + virtual void Visit(BfInvocationExpression* invocationExpr) override; virtual void Visit(BfConditionalExpression* condExpr) override; virtual void Visit(BfAssignmentExpression* assignExpr) override; virtual void Visit(BfParenthesizedExpression* parenExpr) override; @@ -568,7 +577,7 @@ public: virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override; virtual void Visit(BfIndexerExpression* indexerExpr) override; virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override; - virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override; + virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override; }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfFixits.h b/IDEHelper/Compiler/BfFixits.h index cbd47d8d..13634e73 100644 --- a/IDEHelper/Compiler/BfFixits.h +++ b/IDEHelper/Compiler/BfFixits.h @@ -19,7 +19,7 @@ public: { idx++; break; - } + } idx++; } return idx; @@ -37,10 +37,10 @@ public: { char c = source->mSrc[idx]; if (c == '\n') - { + { idx++; break; - } + } idx--; } return idx; @@ -67,13 +67,13 @@ public: virtual void Visit(BfUsingDirective* usingDirective) override { - mLastIdx = FindLineStartAfter(usingDirective->GetSourceData(), usingDirective->GetSrcEnd()); + mLastIdx = FindLineStartAfter(usingDirective->GetSourceData(), usingDirective->GetSrcEnd()); } virtual void Visit(BfNamespaceDeclaration* namespaceDecl) override { if (mFromIdx != -1) - { + { if ((mFromIdx < namespaceDecl->mSrcStart) || (mFromIdx >= namespaceDecl->mSrcEnd)) { // Not inside diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 43d6b421..7ed11ec8 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -236,17 +236,17 @@ bool BfIRValue::IsFake() const } bool BfIRValue::IsConst() const -{ +{ return (mFlags & BfIRValueFlags_Const) != 0; } bool BfIRValue::IsArg() const -{ +{ return (mFlags & BfIRValueFlags_Arg) != 0; } bool BfIRValue::IsFromLLVM() const -{ +{ return (mFlags & BfIRValueFlags_FromLLVM) != 0; } @@ -261,15 +261,15 @@ BfIRFunction::BfIRFunction() ////////////////////////////////////////////////////////////////////////// BfIRFunctionType::BfIRFunctionType() -{ - mId = -1; +{ + mId = -1; } ////////////////////////////////////////////////////////////////////////// BfIRBlock::BfIRBlock() { - mFlags = BfIRValueFlags_None; + mFlags = BfIRValueFlags_None; mId = -1; } @@ -277,11 +277,191 @@ BfIRBlock::BfIRBlock() BfIRConstHolder::BfIRConstHolder(BfModule* module) { - mModule = module; + mModule = module; } BfIRConstHolder::~BfIRConstHolder() -{ +{ +} + +String BfIRConstHolder::ToString(BfIRValue irValue) +{ + if ((irValue.mFlags & BfIRValueFlags_Const) != 0) + { + auto constant = GetConstantById(irValue.mId); + + if (constant->mTypeCode == BfTypeCode_None) + { + return "void"; + } + else if (constant->mTypeCode == BfTypeCode_NullPtr) + { + String ret = "null"; + if (constant->mIRType) + { + ret += "\n"; + ret += ToString(constant->mIRType); + } + return ret; + } + else if (constant->mTypeCode == BfTypeCode_Boolean) + { + return constant->mBool ? "true" : "false"; + } + else if (constant->mTypeCode == BfTypeCode_Float) + { + return StrFormat("Constant %ff", constant->mDouble); + } + else if (constant->mTypeCode == BfTypeCode_Double) + { + return StrFormat("Constant %f", constant->mDouble); + } + else if (IsInt(constant->mTypeCode)) + { + return StrFormat("Constant %lld", constant->mInt64); + } + else if (constant->mTypeCode == BfTypeCode_StringId) + { + return StrFormat("StringId %d", constant->mInt64); + } + else if (constant->mConstType == BfConstType_GlobalVar) + { + auto gvConst = (BfGlobalVar*)constant; + return String("GlobalVar ") + gvConst->mName; + } + else if (constant->mConstType == BfConstType_BitCast) + { + auto bitcast = (BfConstantBitCast*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); + return ToString(targetConst) + " BitCast to " + ToString(bitcast->mToType); + } + else if (constant->mConstType == BfConstType_Box) + { + auto box = (BfConstantBox*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, box->mTarget); + return ToString(targetConst) + " box to " + ToString(box->mToType); + } + else if (constant->mConstType == BfConstType_GEP32_1) + { + auto gepConst = (BfConstantGEP32_1*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); + return ToString(targetConst) + StrFormat(" Gep32 %d", gepConst->mIdx0); + } + else if (constant->mConstType == BfConstType_GEP32_2) + { + auto gepConst = (BfConstantGEP32_2*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); + return ToString(targetConst) + StrFormat(" Gep32 %d,%d", gepConst->mIdx0, gepConst->mIdx1); + } + else if (constant->mConstType == BfConstType_ExtractValue) + { + auto gepConst = (BfConstantExtractValue*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); + return ToString(targetConst) + StrFormat(" ExtractValue %d", gepConst->mIdx0); + } + else if (constant->mConstType == BfConstType_PtrToInt) + { + auto ptrToIntConst = (BfConstantPtrToInt*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, ptrToIntConst->mTarget); + return ToString(targetConst) + StrFormat(" PtrToInt TypeCode:%d", ptrToIntConst->mToTypeCode); + } + else if (constant->mConstType == BfConstType_IntToPtr) + { + auto bitcast = (BfConstantIntToPtr*)constant; + BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); + return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType); + } + else if (constant->mConstType == BfConstType_Agg) + { + auto constAgg = (BfConstantAgg*)constant; + String str = ToString(constAgg->mType); + str += "("; + + for (int i = 0; i < (int)constAgg->mValues.size(); i++) + { + if (i > 0) + str += ", "; + str += ToString(constAgg->mValues[i]); + } + str += ")"; + return str; + } + else if (constant->mConstType == BfConstType_AggZero) + { + return ToString(constant->mIRType) + " zeroinitializer"; + } + else if (constant->mConstType == BfConstType_AggCE) + { + auto constAgg = (BfConstantAggCE*)constant; + return ToString(constAgg->mType) + StrFormat(" aggCe@%p", constAgg->mCEAddr); + } + else if (constant->mConstType == BfConstType_ArrayZero8) + { + return StrFormat("zero8[%d]", constant->mInt32); + } + else if (constant->mConstType == BfConstType_TypeOf) + { + auto typeofConst = (BfTypeOf_Const*)constant; + return "typeof " + mModule->TypeToString(typeofConst->mType); + } + else if (constant->mConstType == BfConstType_TypeOf_WithData) + { + auto typeofConst = (BfTypeOf_WithData_Const*)constant; + return "typeof_withData " + mModule->TypeToString(typeofConst->mType); + } + else if (constant->mConstType == BfConstType_Undef) + { + auto constUndef = (BfConstantUndef*)constant; + return "undef " + ToString(constUndef->mType); + } + else + { + BF_FATAL("Unhandled"); + } + } + else if ((irValue.mFlags & BfIRValueFlags_Arg) != 0) + { + return StrFormat("Arg %d", irValue.mId); + } + else if (irValue.mFlags != 0) + { + return "Value???"; + } + else + { + BF_ASSERT(irValue.mId == -1); + } + return "empty"; +} + +String BfIRConstHolder::ToString(BfIRType irType) +{ + if (irType.mKind == BfIRTypeData::TypeKind_TypeId) + { + return StrFormat("Type#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str()); + } + else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstId) + { + return StrFormat("TypeInst#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str()); + } + else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstPtrId) + { + return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str()); + } + else if (irType.mKind == BfIRTypeData::TypeKind_SizedArray) + { + auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(irType.mId); + return StrFormat("%s[%d]", ToString(sizedArrayType->mType).c_str(), (int)sizedArrayType->mLength); + } + else + { + return "Type ???"; + } +} + +void BfIRConstHolder::pv(const BfIRValue& irValue) +{ + OutputDebugStrF("%s\n", ToString(irValue).c_str()); } void BfIRConstHolder::FixTypeCode(BfTypeCode& typeCode) @@ -405,14 +585,13 @@ const char* BfIRConstHolder::AllocStr(const StringImpl& str) return strCopy; } - BfConstant* BfIRConstHolder::GetConstantById(int id) { return (BfConstant*)mTempAlloc.GetChunkedPtr(id); } BfConstant* BfIRConstHolder::GetConstant(BfIRValue id) -{ +{ if (!id.IsConst()) return NULL; #ifdef CHECK_CONSTHOLDER @@ -481,12 +660,12 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) auto constRHS = GetConstant(rhs); if (constRHS == NULL) return -1; - + if (constLHS == constRHS) return 1; if (constLHS->mConstType == BfConstType_BitCast) - return CheckConstEquality(BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constLHS)->mTarget), rhs); + return CheckConstEquality(BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constLHS)->mTarget), rhs); if (constRHS->mConstType == BfConstType_BitCast) return CheckConstEquality(lhs, BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constRHS)->mTarget)); @@ -511,17 +690,17 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) if (constLHS->mTypeCode != constRHS->mTypeCode) return -1; - + if ((constLHS->mTypeCode >= BfTypeCode_Boolean) && (constLHS->mTypeCode <= BfTypeCode_Double)) { return (constLHS->mUInt64 == constRHS->mUInt64) ? 1 : 0; } - + if (constLHS->mConstType == BfConstType_Agg) { auto aggLHS = (BfConstantAgg*)constLHS; auto aggRHS = (BfConstantAgg*)constRHS; - + if (aggLHS->mValues.mSize != aggRHS->mValues.mSize) return -1; @@ -532,7 +711,7 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) return elemResult; } return 1; - } + } //TODO: Why did we do this? This made global variable comparisons (ie: sA != sB) const-evaluate to false always // if (constLHS->mConstType == BfConstType_GlobalVar) @@ -540,17 +719,32 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) // // We would have already caught the (constLHS == constRHS) case further up // return 0; // } - + return -1; } +BfIRType BfIRConstHolder::GetSizedArrayType(BfIRType elementType, int length) +{ + auto constSizedArrayType = mTempAlloc.Alloc(); + constSizedArrayType->mConstType = BfConstType_SizedArrayType; + constSizedArrayType->mType = elementType; + constSizedArrayType->mLength = length; + + int chunkId = mTempAlloc.GetChunkedId(constSizedArrayType); + + BfIRType retType; + retType.mKind = BfIRTypeData::TypeKind_SizedArray; + retType.mId = chunkId; + return retType; +} + BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, uint64 val) { if (typeCode == BfTypeCode_IntUnknown) typeCode = BfTypeCode_Int64; else if (typeCode == BfTypeCode_UIntUnknown) typeCode = BfTypeCode_UInt64; - + FixTypeCode(typeCode); BfConstant* constant = mTempAlloc.Alloc(); constant->mTypeCode = typeCode; @@ -561,7 +755,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, uint64 val) case BfTypeCode_Int8: constant->mInt64 = (int8)val; break; - case BfTypeCode_Int16: + case BfTypeCode_Int16: constant->mInt64 = (int16)val; break; case BfTypeCode_Int32: @@ -601,7 +795,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, int val) { case BfTypeCode_Int8: constant->mInt64 = (int8)val; - break; + break; case BfTypeCode_Int16: constant->mInt64 = (int16)val; break; @@ -616,10 +810,10 @@ BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, int val) break; default: constant->mInt64 = val; - break; + break; } - auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); + auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; #endif @@ -632,25 +826,25 @@ BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, double val) BfConstant* constant = mTempAlloc.Alloc(); constant->mTypeCode = typeCode; constant->mDouble = val; - auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); + auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; #endif - + return irValue; } BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder) -{ +{ BfConstant* copiedConst = NULL; - + int chunkId = -1; if ((fromConst->mConstType == BfConstType_BitCast) || (fromConst->mConstType == BfConstType_BitCastNull)) - { + { //HMM- This should never happen? Is that true? We always just store string refs as ints //BF_FATAL("Bad"); - auto fromConstBitCast = (BfConstantBitCast*)fromConst; + auto fromConstBitCast = (BfConstantBitCast*)fromConst; BfIRValue copiedTarget; if (fromConstBitCast->mTarget) { @@ -678,7 +872,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f constGEP->mTarget = copiedTarget.mId; constGEP->mIdx0 = fromConstGEP->mIdx0; constGEP->mIdx1 = fromConstGEP->mIdx1; - copiedConst = (BfConstant*)constGEP; + copiedConst = (BfConstant*)constGEP; } else if (fromConst->mConstType == BfConstType_ExtractValue) { @@ -697,7 +891,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f return CreateTypeOf(typeOf->mType); } else if (fromConst->mConstType == BfConstType_TypeOf_WithData) - { + { auto typeOf = (BfTypeOf_WithData_Const*)fromConst; auto dataConstant = fromHolder->GetConstant(typeOf->mTypeData); return CreateTypeOf(typeOf->mType, CreateConst(dataConstant, fromHolder)); @@ -733,13 +927,13 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f return CreateConstArrayZero(fromConst->mInt32); } else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId)) - { - return CreateConst(fromConst->mTypeCode, fromConst->mUInt64); + { + return CreateConst(fromConst->mTypeCode, fromConst->mUInt64); } else if ((fromConst->mTypeCode == BfTypeCode_Float) || (fromConst->mTypeCode == BfTypeCode_Double)) { return CreateConst(fromConst->mTypeCode, fromConst->mDouble); - } + } else if (fromConst->mTypeCode == BfTypeCode_NullPtr) { if (fromConst->mIRType) @@ -774,12 +968,12 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f { BF_FATAL("not handled"); } - + BfIRValue retVal; retVal.mFlags = BfIRValueFlags_Const; if (chunkId == -1) chunkId = mTempAlloc.GetChunkedId(copiedConst); - retVal.mId = chunkId; + retVal.mId = chunkId; BF_ASSERT(retVal.mId >= 0); #ifdef CHECK_CONSTHOLDER retVal.mHolder = this; @@ -790,9 +984,9 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f BfIRValue BfIRConstHolder::CreateConstNull() { BfConstant* constant = mTempAlloc.Alloc(); - constant->mTypeCode = BfTypeCode_NullPtr; + constant->mTypeCode = BfTypeCode_NullPtr; constant->mIRType = BfIRType(); - auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); + auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; #endif @@ -804,7 +998,7 @@ BfIRValue BfIRConstHolder::CreateConstNull(BfIRType ptrType) BfConstant* constant = mTempAlloc.Alloc(); constant->mTypeCode = BfTypeCode_NullPtr; constant->mIRType = ptrType; - auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); + auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; #endif @@ -831,7 +1025,7 @@ BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray(); constant->mConstType = BfConstType_Agg; constant->mType = type = type; @@ -868,7 +1062,7 @@ BfIRValue BfIRConstHolder::CreateConstArrayZero(BfIRType type, int count) constant->mType = type = type; constant->mCount = count; auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant)); - + #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; #endif @@ -913,7 +1107,7 @@ BfIRValue BfIRConstHolder::CreateConstBox(BfIRValue val, BfIRType type) { auto constVal = GetConstant(val); - auto box = mTempAlloc.Alloc(); + auto box = mTempAlloc.Alloc(); box->mConstType = BfConstType_Box; BF_ASSERT(val.mId != -1); box->mTarget = val.mId; @@ -931,7 +1125,7 @@ BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type) { BfTypeOf_Const* typeOf = mTempAlloc.Alloc(); typeOf->mConstType = BfConstType_TypeOf; - typeOf->mType = type; + typeOf->mType = type; auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf)); #ifdef CHECK_CONSTHOLDER irValue.mHolder = this; @@ -953,12 +1147,12 @@ BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type, BfIRValue typeData) } BfIRValue BfIRConstHolder::GetUndefConstValue(BfIRType irType) -{ +{ auto constUndef = mTempAlloc.Alloc(); - constUndef->mConstType = BfConstType_Undef; + constUndef->mConstType = BfConstType_Undef; constUndef->mType = irType; - BfIRValue undefVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constUndef)); + BfIRValue undefVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constUndef)); #ifdef CHECK_CONSTHOLDER castedVal.mHolder = this; #endif @@ -1032,7 +1226,7 @@ bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type) int idx = 0; if (typeInst->mBaseType != NULL) - { + { if (!WriteConstant(aggConstant->mValues[0], ptr, typeInst->mBaseType)) return false; } @@ -1087,7 +1281,7 @@ bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type) if (strncmp(constGV->mName, strObjPrefix, strlen(strObjPrefix)) == 0) { *(int32*)ptr = atoi(constGV->mName + strlen(strObjPrefix)); - return true; + return true; } } @@ -1095,7 +1289,7 @@ bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type) } BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type) -{ +{ if (type->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)type; @@ -1134,7 +1328,7 @@ BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type) return BfIRValue(); } } - + if (type->IsTypedPrimitive()) { return ReadConstant(ptr, type->GetUnderlyingType()); @@ -1160,7 +1354,7 @@ BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type) } if (type->IsStruct()) - { + { mModule->PopulateType(type); auto typeInst = type->ToTypeInstance(); int idx = 0; @@ -1199,14 +1393,14 @@ BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type) BfIRType irType; irType.mKind = BfIRTypeData::TypeKind_TypeId; irType.mId = type->mTypeId; - return CreateConstAgg(irType, irValues); + return CreateConstAgg(irType, irValues); } if (type->IsInstanceOf(mModule->mCompiler->mStringTypeDef)) { return CreateConst(BfTypeCode_StringId, *(int32*)ptr); } - + return BfIRValue(); } @@ -1274,7 +1468,7 @@ int32 BfIRBuilder::CheckedAdd(int32 a, int32 b) OpFailed(); } else if (result > a) - OpFailed(); + OpFailed(); return (uint32)result; } @@ -1287,7 +1481,7 @@ int64 BfIRBuilder::CheckedAdd(int64 a, int64 b) OpFailed(); } else if (result > a) - OpFailed(); + OpFailed(); return (uint64)result; } @@ -1350,7 +1544,7 @@ int32 BfIRBuilder::CheckedSub(int32 a, int32 b) OpFailed(); } else if (result < a) - OpFailed(); + OpFailed(); return (uint32)result; } @@ -1363,7 +1557,7 @@ int64 BfIRBuilder::CheckedSub(int64 a, int64 b) OpFailed(); } else if (result < a) - OpFailed(); + OpFailed(); return (uint64)result; } @@ -1390,7 +1584,7 @@ uint32 BfIRBuilder::CheckedMul(uint32 a, uint32 b) uint64 result = (uint64)a * b; uint32 upper = (uint32)(result >> 32); if ((upper != 0) && (upper != 0xFFFFFFFF)) - OpFailed(); + OpFailed(); return (uint32)result; } @@ -1401,7 +1595,7 @@ uint64 BfIRBuilder::CheckedMul(uint64 a, uint64 b) uint32 bHigh; uint32 bLow; - // a*b can be decomposed to + // a*b can be decomposed to // (aHigh * bHigh * 2^64) + (aLow * bHigh * 2^32) + (aHigh * bLow * 2^32) + (aLow * bLow) aHigh = (uint32)(a >> 32); @@ -1413,8 +1607,8 @@ uint64 BfIRBuilder::CheckedMul(uint64 a, uint64 b) if (aHigh == 0) { - if (bHigh != 0) - ret = (uint64)aLow * (uint64)bHigh; + if (bHigh != 0) + ret = (uint64)aLow * (uint64)bHigh; } else if (bHigh == 0) { @@ -1422,26 +1616,26 @@ uint64 BfIRBuilder::CheckedMul(uint64 a, uint64 b) ret = (uint64)aHigh * (uint64)bLow; } else - OpFailed(); + OpFailed(); if (ret != 0) { uint64 tmp; - if((uint32)(ret >> 32) != 0) - OpFailed(); + if((uint32)(ret >> 32) != 0) + OpFailed(); ret <<= 32; tmp = (uint64)aLow * (uint64)bLow; ret += tmp; - if (ret < tmp) - OpFailed(); + if (ret < tmp) + OpFailed(); return ret; } - return (uint64)aLow * (uint64)bLow; + return (uint64)aLow * (uint64)bLow; } int8 BfIRBuilder::CheckedMul(int8 a, int8 b) @@ -1465,14 +1659,14 @@ int32 BfIRBuilder::CheckedMul(int32 a, int32 b) int64 result = (int64)a * b; int32 upper = (int32)(result >> 32); if ((upper != 0) && (upper != 0xFFFFFFFF)) - OpFailed(); + OpFailed(); return (int32)result; } int64 BfIRBuilder::CheckedMul(int64 a, int64 b) { - bool aNegative = false; - int64 aAbs = a; + bool aNegative = false; + int64 aAbs = a; if (aAbs < 0) { aNegative = true; @@ -1491,12 +1685,12 @@ int64 BfIRBuilder::CheckedMul(int64 a, int64 b) // Don't allow overflow into sign flag if (tmp & 0x8000000000000000LL) - OpFailed(); + OpFailed(); - if (aNegative ^ bNegative) - return -(int64)tmp; + if (aNegative ^ bNegative) + return -(int64)tmp; - return (int64)tmp; + return (int64)tmp; } /// @@ -1595,7 +1789,7 @@ BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module) mBeIRCodeGen = NULL; mBfIRCodeGen = NULL; mDbgVerifyCodeGen = false; - + mIgnoreWrites = false; mCurFakeId = -32; mOpFailed = false; @@ -1603,7 +1797,7 @@ BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module) mHasGlobalDefs = false; mNumFunctionsWithBodies = 0; mActiveFunctionHasBody = false; - mHasStarted = false; + mHasStarted = false; mCmdCount = 0; mIsBeefBackend = false; } @@ -1627,161 +1821,11 @@ String BfIRBuilder::ToString(BfIRValue irValue) { if ((irValue.mFlags & BfIRValueFlags_Const) != 0) { - auto constant = GetConstantById(irValue.mId); - - if (constant->mTypeCode == BfTypeCode_None) - { - return "void"; - } - else if (constant->mTypeCode == BfTypeCode_NullPtr) - { - String ret = "null"; - if (constant->mIRType) - { - ret += "\n"; - ret += ToString(constant->mIRType); - } - return ret; - } - else if (constant->mTypeCode == BfTypeCode_Boolean) - { - return constant->mBool ? "true" : "false"; - } - else if (constant->mTypeCode == BfTypeCode_Float) - { - return StrFormat("Constant %ff", constant->mDouble); - } - else if (constant->mTypeCode == BfTypeCode_Double) - { - return StrFormat("Constant %f", constant->mDouble); - } - else if (IsInt(constant->mTypeCode)) - { - return StrFormat("Constant %lld", constant->mInt64); - } - else if (constant->mTypeCode == BfTypeCode_StringId) - { - return StrFormat("StringId %d", constant->mInt64); - } - else if (constant->mConstType == BfConstType_GlobalVar) - { - auto gvConst = (BfGlobalVar*)constant; - if (gvConst->mStreamId == -1) - { - } - else if (mBfIRCodeGen != NULL) - { - auto val = mBfIRCodeGen->GetLLVMValue(gvConst->mStreamId); - std::string outStr; - llvm::raw_string_ostream strStream(outStr); - val->print(strStream); - strStream.flush(); - return outStr; - } - else if (mBeIRCodeGen != NULL) - { - auto val = mBeIRCodeGen->GetBeValue(gvConst->mStreamId); - String outStr; - BeDumpContext dumpCtx; - dumpCtx.ToString(outStr, val); - return outStr; - } - else - return String("GlobalVar ") + gvConst->mName; - } - else if (constant->mConstType == BfConstType_BitCast) - { - auto bitcast = (BfConstantBitCast*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); - return ToString(targetConst) + " BitCast to " + ToString(bitcast->mToType); - } - else if (constant->mConstType == BfConstType_Box) - { - auto box = (BfConstantBox*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, box->mTarget); - return ToString(targetConst) + " box to " + ToString(box->mToType); - } - else if (constant->mConstType == BfConstType_GEP32_1) - { - auto gepConst = (BfConstantGEP32_1*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); - return ToString(targetConst) + StrFormat(" Gep32 %d", gepConst->mIdx0); - } - else if (constant->mConstType == BfConstType_GEP32_2) - { - auto gepConst = (BfConstantGEP32_2*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); - return ToString(targetConst) + StrFormat(" Gep32 %d,%d", gepConst->mIdx0, gepConst->mIdx1); - } - else if (constant->mConstType == BfConstType_ExtractValue) - { - auto gepConst = (BfConstantExtractValue*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); - return ToString(targetConst) + StrFormat(" ExtractValue %d", gepConst->mIdx0); - } - else if (constant->mConstType == BfConstType_PtrToInt) - { - auto ptrToIntConst = (BfConstantPtrToInt*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, ptrToIntConst->mTarget); - return ToString(targetConst) + StrFormat(" PtrToInt TypeCode:%d", ptrToIntConst->mToTypeCode); - } - else if (constant->mConstType == BfConstType_IntToPtr) - { - auto bitcast = (BfConstantIntToPtr*)constant; - BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); - return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType); - } - else if (constant->mConstType == BfConstType_Agg) - { - auto constAgg = (BfConstantAgg*)constant; - String str = ToString(constAgg->mType); - str += "("; - - for (int i = 0; i < (int)constAgg->mValues.size(); i++) - { - if (i > 0) - str += ", "; - str += ToString(constAgg->mValues[i]); - } - str += ")"; - return str; - } - else if (constant->mConstType == BfConstType_AggZero) - { - return ToString(constant->mIRType) + " zeroinitializer"; - } - else if (constant->mConstType == BfConstType_AggCE) - { - auto constAgg = (BfConstantAggCE*)constant; - return ToString(constAgg->mType) + StrFormat(" aggCe@%p", constAgg->mCEAddr); - } - else if (constant->mConstType == BfConstType_ArrayZero8) - { - return StrFormat("zero8[%d]", constant->mInt32); - } - else if (constant->mConstType == BfConstType_TypeOf) - { - auto typeofConst = (BfTypeOf_Const*)constant; - return "typeof " + mModule->TypeToString(typeofConst->mType); - } - else if (constant->mConstType == BfConstType_TypeOf_WithData) - { - auto typeofConst = (BfTypeOf_WithData_Const*)constant; - return "typeof_withData " + mModule->TypeToString(typeofConst->mType); - } - else if (constant->mConstType == BfConstType_Undef) - { - auto constUndef = (BfConstantUndef*)constant; - return "undef " + ToString(constUndef->mType); - } - else - { - BF_FATAL("Unhandled"); - } + return BfIRConstHolder::ToString(irValue); } else if ((irValue.mFlags & BfIRValueFlags_Arg) != 0) { - return StrFormat("Arg %d in %s", irValue.mId, ActiveFuncToString().c_str()); + return StrFormat("Arg %d in %s", irValue.mId, ActiveFuncToString().c_str()); } else if (irValue.mFlags != 0) { @@ -1800,7 +1844,7 @@ String BfIRBuilder::ToString(BfIRValue irValue) { auto val = mBeIRCodeGen->GetBeValue(irValue.mId); String str; - BeDumpContext dc; + BeDumpContext dc; dc.ToString(str, val); auto type = val->GetType(); @@ -1811,7 +1855,7 @@ String BfIRBuilder::ToString(BfIRValue irValue) } return str; - } + } else return "Value???"; } @@ -1830,7 +1874,7 @@ String BfIRBuilder::ToString(BfIRType irType) if (irType.mKind == BfIRTypeData::TypeKind_Stream) { llvmType = mBfIRCodeGen->GetLLVMType(irType.mId); - } + } else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeCode) { bool isSigned = false; @@ -1846,14 +1890,14 @@ String BfIRBuilder::ToString(BfIRType irType) else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId) llvmType = typeEntry.mInstLLVMType->getPointerTo(); } - + if (llvmType == NULL) return "null"; std::string outStr; llvm::raw_string_ostream strStream(outStr); - llvmType->print(strStream); - - if (auto pointerType = llvm::dyn_cast(llvmType)) + llvmType->print(strStream); + + if (auto pointerType = llvm::dyn_cast(llvmType)) { strStream << "\n ElementType: "; pointerType->getElementType()->print(strStream); @@ -1875,7 +1919,7 @@ String BfIRBuilder::ToString(BfIRType irType) } else { - auto& typeEntry = mBeIRCodeGen->GetTypeEntry(irType.mId); + auto& typeEntry = mBeIRCodeGen->GetTypeEntry(irType.mId); if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeId) beType = typeEntry.mBeType; else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstId) @@ -1883,9 +1927,9 @@ String BfIRBuilder::ToString(BfIRType irType) else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId) beType = mBeIRCodeGen->mBeContext->GetPointerTo(typeEntry.mInstBeType); } - + String str; - BeDumpContext dc; + BeDumpContext dc; dc.ToString(str, beType); return str; } @@ -1909,7 +1953,7 @@ String BfIRBuilder::ToString(BfIRType irType) else { return "Type ???"; - } + } } String BfIRBuilder::ToString(BfIRFunction irFunc) @@ -1921,7 +1965,7 @@ String BfIRBuilder::ToString(BfIRFunction irFunc) return "null"; std::string outStr; llvm::raw_string_ostream strStream(outStr); - val->print(strStream); + val->print(strStream); strStream.flush(); return outStr; } @@ -1932,7 +1976,7 @@ String BfIRBuilder::ToString(BfIRFunction irFunc) return "null"; String str; - BeDumpContext dc; + BeDumpContext dc; dc.ToString(str, val); return str; } @@ -1958,7 +2002,7 @@ String BfIRBuilder::ToString(BfIRFunctionType irType) } String BfIRBuilder::ToString(BfIRMDNode irMDNode) -{ +{ if (mBfIRCodeGen != NULL) { auto md = mBfIRCodeGen->GetLLVMMetadata(irMDNode.mId); @@ -1976,7 +2020,7 @@ String BfIRBuilder::ToString(BfIRMDNode irMDNode) if (md == NULL) return "null"; String str; - BeDumpContext dc; + BeDumpContext dc; dc.ToString(str, md); return str; } @@ -1992,7 +2036,7 @@ String BfIRBuilder::ActiveFuncToString() llvm::raw_string_ostream strStream(outStr); mBfIRCodeGen->mActiveFunction->print(strStream); return outStr; - } + } else return "???"; } @@ -2050,7 +2094,7 @@ void BfIRBuilder::pmd(const BfIRMDNode& irMDNode) } void BfIRBuilder::GetBufferData(Array& outBuffer) -{ +{ if (mStream.GetSize() == 0) return; @@ -2090,21 +2134,21 @@ void BfIRBuilder::ClearNonConstData() } void BfIRBuilder::Start(const StringImpl& moduleName, int ptrSize, bool isOptimized) -{ +{ mHasStarted = true; WriteCmd(BfIRCmd_Module_Start, moduleName, ptrSize, isOptimized); NEW_CMD_INSERTED; } void BfIRBuilder::SetBackend(bool isBeefBackend) -{ +{ mIsBeefBackend = isBeefBackend; BF_ASSERT(mIRCodeGen == NULL); if (mDbgVerifyCodeGen) { if (isBeefBackend) - { + { mBeIRCodeGen = new BeIRCodeGen(); mBeIRCodeGen->mStream = &mStream; mBeIRCodeGen->mBfIRBuilder = this; @@ -2122,7 +2166,7 @@ void BfIRBuilder::SetBackend(bool isBeefBackend) while (mStream.GetReadPos() < mStream.GetSize()) mIRCodeGen->HandleNextCmd(); - } + } } void BfIRBuilder::RemoveIRCodeGen() @@ -2142,7 +2186,7 @@ void BfIRBuilder::WriteIR(const StringImpl& fileName) } void BfIRBuilder::Module_SetTargetTriple(const StringImpl& targetTriple, const StringImpl& targetCPU) -{ +{ WriteCmd(BfIRCmd_Module_SetTargetTriple, targetTriple, targetCPU); NEW_CMD_INSERTED; } @@ -2166,15 +2210,15 @@ void BfIRBuilder::WriteSLEB128(int64 value) bool hasMore; do { - uint8 curByte = (uint8)(value & 0x7f); + uint8 curByte = (uint8)(value & 0x7f); value >>= 7; hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) || ((value == -1) && ((curByte & 0x40) != 0)))); if (hasMore) - curByte |= 0x80; + curByte |= 0x80; mStream.Write(curByte); } - while (hasMore); + while (hasMore); } void BfIRBuilder::WriteSLEB128(int32 value) @@ -2186,7 +2230,7 @@ void BfIRBuilder::WriteSLEB128(int32 value) // mStream.Write((uint8)value); // return; // } -// +// // if (value >= -0x2000) // { // uint16 val = @@ -2195,7 +2239,7 @@ void BfIRBuilder::WriteSLEB128(int32 value) // mStream.Write_2(val); // return; // } -// +// // if (value >= -0x100000) // { // uint32 val = @@ -2205,7 +2249,7 @@ void BfIRBuilder::WriteSLEB128(int32 value) // mStream.Write_3(val); // return; // } -// +// // if (value >= -0x8000000) // { // uint32 val = @@ -2233,7 +2277,7 @@ void BfIRBuilder::WriteSLEB128(int32 value) mStream.Write_2(val); return; } -// +// // if (value <= 0x0FFFFF) // { // uint32 val = @@ -2243,7 +2287,7 @@ void BfIRBuilder::WriteSLEB128(int32 value) // mStream.Write_3(val); // return; // } -// +// // if (value <= 0x7FFFFF) // { // uint32 val = @@ -2271,12 +2315,12 @@ void BfIRBuilder::WriteSLEB128(int32 value) void BfIRBuilder::Write(uint8 val) { - mStream.Write(val); + mStream.Write(val); } void BfIRBuilder::Write(bool val) { - mStream.Write(val ? 1 : 0); + mStream.Write(val ? 1 : 0); } void BfIRBuilder::Write(int intVal) @@ -2298,18 +2342,18 @@ void BfIRBuilder::Write(Val128 val) void BfIRBuilder::Write(const StringImpl&str) { WriteSLEB128((int)str.length()); - mStream.Write(str.c_str(), (int)str.length()); + mStream.Write(str.c_str(), (int)str.length()); } void BfIRBuilder::Write(const BfIRValue& irValue) -{ +{ if ((irValue.mFlags & BfIRValueFlags_Const) != 0) { auto constant = GetConstantById(irValue.mId); - + mStream.Write(BfIRParamType_Const); mStream.Write((uint8)constant->mTypeCode); - + switch ((int)constant->mTypeCode) { case (int)BfTypeCode_Float: @@ -2318,7 +2362,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) mStream.Write(&f, sizeof(float)); } break; - case (int)BfTypeCode_Double: + case (int)BfTypeCode_Double: { mStream.Write(&constant->mDouble, sizeof(double)); } @@ -2337,7 +2381,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) case (int)BfTypeCode_UIntUnknown: case (int)BfTypeCode_Char8: case (int)BfTypeCode_Char16: - case (int)BfTypeCode_Char32: + case (int)BfTypeCode_Char32: { WriteSLEB128(constant->mInt64); } @@ -2406,7 +2450,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) auto gepConst = (BfConstantExtractValue*)constant; BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); Write(targetConst); - Write(gepConst->mIdx0); + Write(gepConst->mIdx0); } break; case (int)BfConstType_PtrToInt: @@ -2417,7 +2461,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) Write(ptrToIntConst->mToTypeCode); } break; - case (int)BfConstType_IntToPtr: + case (int)BfConstType_IntToPtr: { auto intToPtrConst = (BfConstantIntToPtr*)constant; BfIRValue targetConst(BfIRValueFlags_Const, intToPtrConst->mTarget); @@ -2441,7 +2485,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) { Write(constant->mInt64); } - break; + break; case (int)BfConstType_TypeOf: { auto typeofConst = (BfTypeOf_Const*)constant; @@ -2461,7 +2505,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) Write(typeofConst->mTypeData); } break; - default: + default: { BF_FATAL("Unhandled"); } @@ -2507,7 +2551,7 @@ void BfIRBuilder::Write(const BfIRValue& irValue) void BfIRBuilder::Write(BfTypeCode typeCode) { - mStream.Write((uint8)typeCode); + mStream.Write((uint8)typeCode); } void BfIRBuilder::Write(const BfIRTypeData& type) @@ -2522,9 +2566,9 @@ void BfIRBuilder::Write(const BfIRTypeData& type) else if (type.mKind != BfIRTypeData::TypeKind_None) WriteSLEB128(type.mId); } - + void BfIRBuilder::Write(BfIRFunctionType funcType) -{ +{ WriteSLEB128(funcType.mId); } @@ -2547,18 +2591,18 @@ void BfIRBuilder::Write(BfIRMDNode node) } BfIRValue BfIRBuilder::WriteCmd(BfIRCmd cmd) -{ +{ if (mIgnoreWrites) - return GetFakeVal(); + return GetFakeVal(); mStream.Write((uint8)cmd); return BfIRValue(BfIRValueFlags_Value, mCmdCount++); } void BfIRBuilder::NewCmdInserted() -{ +{ BF_ASSERT(mIgnoreWrites || mHasStarted); if (mIgnoreWrites) - return; + return; if (mIRCodeGen == NULL) return; @@ -2569,9 +2613,9 @@ void BfIRBuilder::NewCmdInserted() } BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope) -{ +{ BfIRMDNode curDIScope = fileDIScope; - auto typeInstance = type->ToTypeInstance(); + auto typeInstance = type->ToTypeInstance(); if (mModule->mCompiler->mOptions.IsCodeView()) { @@ -2581,7 +2625,7 @@ BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScop if (typeInstance != NULL) { - auto typeDef = typeInstance->mTypeDef; + auto typeDef = typeInstance->mTypeDef; if (!typeInstance->IsBoxed()) { @@ -2594,7 +2638,7 @@ BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScop curNamespace = innerTypeInst->mTypeDef->mNamespace; } else - curNamespace = typeDef->mNamespace; + curNamespace = typeDef->mNamespace; for (int partCount = 0; partCount < curNamespace.GetPartsCount(); partCount++) { @@ -2620,7 +2664,7 @@ String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeO if (boxedType->IsBoxedStructPtr()) typeName += "*"; typeName = "Box<" + typeName + ">"; - } + } else if (includeOuterTypeName) { typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace)); @@ -2638,7 +2682,7 @@ String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeO typeName.Insert(i, ":"); } } - + //DbgAddPrefix(typeName); return typeName; } @@ -2666,17 +2710,22 @@ public: #endif void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) -{ +{ + auto populateModule = mModule->mContext->mUnreifiedModule; + auto typeInstance = type->ToTypeInstance(); + if ((typeInstance != NULL) && (typeInstance->mModule != NULL)) + populateModule = typeInstance->mModule; + bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType()); - - // Types that don't have a proper 'defining module' need to be defined in every module they are used + + // Types that don't have a proper 'defining module' need to be defined in every module they are used bool wantsDIForwardDecl = (type->GetModule() != mModule) && (!type->IsFunction()); // Forward declarations of valuetypes don't work in LLVM backend for Win32..... //TODO: Why was this commented out? bool wantsDIPartialDef = false; if (wantsDIForwardDecl) - { + { if ((!mIsBeefBackend) && (type->IsValueType())) { wantsDIPartialDef = true; @@ -2691,10 +2740,10 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); if (!type->IsDeclared()) - mModule->PopulateType(type, BfPopulateType_Declaration); + populateModule->PopulateType(type, BfPopulateType_Declaration); BF_ASSERT(type->IsDeclared()); - + #ifdef BFIR_RENTRY_CHECK ReEntryCheck reEntryCheck(&mDeclReentrySet, type); #endif @@ -2702,8 +2751,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) BfIRType irType; BfIRMDNode diType; bool trackDIType = false; - - BfTypeInstance* typeInstance = type->ToTypeInstance(); + BfType* underlyingArrayType = NULL; int underlyingArraySize = -1; bool underlyingArrayIsVector = false; @@ -2712,61 +2760,60 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) if (type->IsPointer()) { - BfPointerType* pointerType = (BfPointerType*)type; - mModule->PopulateType(pointerType->mElementType, BfPopulateType_Data); + BfPointerType* pointerType = (BfPointerType*)type; + populateModule->PopulateType(pointerType->mElementType, BfPopulateType_Data); if (pointerType->mElementType->IsValuelessType()) { irType = GetPrimitiveType(BfTypeCode_NullPtr); } else - { + { irType = GetPointerTo(MapType(pointerType->mElementType)); } - + if (wantDIData) - { - diType = DbgCreatePointerType(DbgGetType(pointerType->mElementType, BfIRPopulateType_Declaration)); + { + diType = DbgCreatePointerType(DbgGetType(pointerType->mElementType, BfIRPopulateType_Declaration)); trackDIType = true; } } else if (type->IsRef()) { - BfRefType* refType = (BfRefType*)type; - + BfRefType* refType = (BfRefType*)type; + if (refType->mElementType->IsValuelessType()) irType = GetPrimitiveType(BfTypeCode_NullPtr); else { //mModule->PopulateType(refType->mElementType, BfPopulateType_Declaration); - irType = GetPointerTo(MapType(refType->mElementType)); + irType = GetPointerTo(MapType(refType->mElementType)); } if ((wantDIData) && (!type->IsUnspecializedType())) - { - diType = DbgCreateReferenceType(DbgGetType(refType->mElementType)); - trackDIType = true; + { + diType = DbgCreateReferenceType(DbgGetType(refType->mElementType)); + trackDIType = true; } } else if ((type->IsGenericParam()) || (type->IsModifiedTypeType())) { //mModule->PopulateType(mModule->mContext->mBfObjectType, BfPopulateType_Declaration); - irType = MapType(mModule->mContext->mBfObjectType); + irType = MapType(mModule->mContext->mBfObjectType); if (wantDIData) diType = DbgGetType(mModule->mContext->mBfObjectType); } else if (type->IsConcreteInterfaceType()) { BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)type; - irType = MapType(concreteInterfaceType->mInterface); + irType = MapType(concreteInterfaceType->mInterface); if (wantDIData) { diType = DbgGetType(concreteInterfaceType->mInterface); - - } + } } else if (type->IsMethodRef()) { - auto methodRefType = (BfMethodRefType*)type; + auto methodRefType = (BfMethodRefType*)type; BfMethodInstance* methodInstance = methodRefType->mMethodRef; String name = "_BF_MethodRef_"; @@ -2777,8 +2824,8 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) BF_ASSERT(methodInstance != NULL); if ((wantDIData) && (methodInstance != NULL)) - { - auto typeDeclaration = methodInstance->GetOwner()->mTypeDef->mTypeDeclaration; + { + auto typeDeclaration = methodInstance->GetOwner()->mTypeDef->mTypeDeclaration; BfFileInstance* bfFileInstance; if (typeDeclaration != NULL) @@ -2786,18 +2833,18 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) else bfFileInstance = mModule->GetFileFromNode(mModule->mContext->mBfObjectType->mTypeDef->mTypeDeclaration); - auto namespaceScope = DbgCreateNameSpace(bfFileInstance->mDIFile, "_bf", bfFileInstance->mDIFile, 0); - + auto namespaceScope = DbgCreateNameSpace(bfFileInstance->mDIFile, "_bf", bfFileInstance->mDIFile, 0); + StringT<128> mangledName; BfMangler::Mangle(mangledName, mModule->mCompiler->GetMangleKind(), methodInstance); - + int captureSize = 0; int captureAlign = 0; BfIRMDNode derivedFrom; Array elements; - + diType = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, name, namespaceScope, bfFileInstance->mDIFile, 0, captureSize * 8, captureAlign * 8, 0); - + auto int64Type = mModule->GetPrimitiveType(BfTypeCode_Int64); auto memberType = DbgCreateMemberType(diType, mangledName, bfFileInstance->mDIFile, 0, 0, 0, -1, 0, DbgGetType(int64Type)); elements.Add(memberType); @@ -2818,19 +2865,19 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) offset = BF_ALIGN(offset, methodRefType->mAlign); BF_ASSERT(offset == methodRefType->mSize); - + DbgMakePermanent(diType, derivedFrom, elements); } - Array members; + Array members; for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++) { - BfType* paramType = methodRefType->GetCaptureType(dataIdx); + BfType* paramType = methodRefType->GetCaptureType(dataIdx); if (paramType->IsValueType()) PopulateType(paramType, BfIRPopulateType_Eventually_Full); members.Add(MapType(paramType)); } - + irType = CreateStructType(name); StructSetBody(irType, members, type->mSize, type->mAlign, false); } @@ -2839,7 +2886,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) BfSizedArrayType* arrayType = (BfSizedArrayType*)type; auto elementType = arrayType->mElementType; BfIRType elementIrType; - + if (elementType->IsValueType()) { //mModule->PopulateType(arrayType->mElementType, BfPopulateType_Data); @@ -2850,9 +2897,9 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) //mModule->PopulateType(arrayType->mElementType, BfPopulateType_Declaration); elementIrType = MapType(arrayType->mElementType); } - - if (arrayType->mElementType->IsValuelessType()) - irType = elementIrType; + + if (arrayType->mElementType->IsValuelessType()) + irType = elementIrType; else irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0)); // else if (arrayType->mElementType->IsSizeAligned()) @@ -2860,7 +2907,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) // else // irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0)); - if (wantDIData) + if (wantDIData) diType = DbgCreateArrayType((int64)arrayType->mSize * 8, arrayType->mAlign * 8, DbgGetType(arrayType->mElementType), arrayType->mElementCount); } else if (type->IsPrimitiveType()) @@ -2870,12 +2917,12 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) if ((typeCode == BfTypeCode_Var) || (typeCode == BfTypeCode_Let) || (typeCode == BfTypeCode_Self)) { //mModule->PopulateType(mModule->mContext->mBfObjectType, BfPopulateType_Declaration); - irType = MapType(mModule->mContext->mBfObjectType); + irType = MapType(mModule->mContext->mBfObjectType); if (wantDIData) diType = DbgGetType(mModule->mContext->mBfObjectType); } else if (typeCode == BfTypeCode_NullPtr) - { + { irType = GetPrimitiveType(typeCode); if (wantDIData) @@ -2886,7 +2933,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) } else { - irType = GetPrimitiveType(typeCode); + irType = GetPrimitiveType(typeCode); if (wantDIData) { int dwarfType = 0; @@ -2909,7 +2956,7 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) case BfTypeCode_UInt16: case BfTypeCode_UInt32: case BfTypeCode_UInt64: - case BfTypeCode_UIntPtr: + case BfTypeCode_UIntPtr: dwarfType = llvm::dwarf::DW_ATE_unsigned; break; case BfTypeCode_Char8: @@ -2928,11 +2975,11 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) diType = DbgCreateBasicType(primType->mTypeDef->mName->ToString(), primType->mSize * 8, primType->mAlign * 8, dwarfType); } } - } + } else if (type->IsTypeInstance()) - { + { auto typeDef = typeInstance->mTypeDef; - + BfIRMDNode diForwardDecl; if (wantDIData) { @@ -2963,14 +3010,14 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) curDIScope = CreateNamespaceScope(checkType, fileDIScope); String typeName = GetDebugTypeName(typeInstance, false); if (wantsDIForwardDecl) - { + { if (type->IsInterface()) { int flags = 0; diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, typeName, curDIScope, fileDIScope, 0, (int64)0 * 8, (int64)0 * 8, flags); auto derivedFrom = DbgGetTypeInst(mModule->mContext->mBfObjectType); - SizedArray diFieldTypes; + SizedArray diFieldTypes; auto inheritanceType = DbgCreateInheritance(diForwardDecl, derivedFrom, 0, llvm::DINode::FlagPublic); diFieldTypes.push_back(inheritanceType); DbgMakePermanent(diForwardDecl, derivedFrom, diFieldTypes); @@ -2982,15 +3029,15 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) } } else - { + { if (wantsDIPartialDef) - typeName += "$part"; + typeName += "$part$"; - // Will fill in later (during definition phase) + // Will fill in later (during definition phase) int flags = 0; diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(typeInstance->mInstSize, typeInstance->mInstAlign) * 8, (int64)typeInstance->mInstAlign * 8, flags); - + mDITemporaryTypes.push_back(typeInstance); if (!type->IsUnspecializedType()) @@ -2998,16 +3045,16 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type)); mDeferredDbgTypeDefs.Add(type); } - } + } - DbgSetInstType(type, diForwardDecl); + DbgSetInstType(type, diForwardDecl); BfIRMDNode diType; - if (type->IsValueType()) - diType = diForwardDecl; - else + if (type->IsValueType()) + diType = diForwardDecl; + else diType = DbgCreatePointerType(diForwardDecl); - DbgSetType(type, diType); + DbgSetType(type, diType); } if (underlyingArraySize != -1) @@ -3019,14 +3066,14 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) irType = GetVectorType(MapType(underlyingArrayType), underlyingArraySize); } else - irType = GetSizedArrayType(MapType(underlyingArrayType), underlyingArraySize); + irType = GetSizedArrayType(MapType(underlyingArrayType), underlyingArraySize); SetType(type, irType); } else if (type->IsTypedPrimitive()) { - mModule->PopulateType(type); - auto underlyingType = type->GetUnderlyingType(); - irType = MapType(underlyingType); + populateModule->PopulateType(type); + auto underlyingType = type->GetUnderlyingType(); + irType = MapType(underlyingType); SetType(type, irType); SetInstType(type, irType); } @@ -3048,8 +3095,8 @@ void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine) SetType(type, irStructType); SetInstType(type, irStructType); } - } - return; + } + return; } if (irType) @@ -3071,10 +3118,10 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); auto typeDef = typeInstance->mTypeDef; bool wantDIData = true; - + BfModuleOptions moduleOptions = mModule->GetModuleOptions(); bool isOptimized = (moduleOptions.mOptLevel != BfOptLevel_O0) && (moduleOptions.mOptLevel != BfOptLevel_OgPlus); - + BfIRMDNode fileDIScope; if (wantDIData) { @@ -3090,9 +3137,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) #ifdef BFIR_RENTRY_CHECK ReEntryCheck reEntryCheck(&mDefReentrySet, type); #endif - + //BF_ASSERT(WantsDbgDefinition(type)); - + SizedArray diFieldTypes; int packing = 0; @@ -3101,10 +3148,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) BfType* underlyingArrayType = NULL; int underlyingArraySize = -1; bool underlyingArrayIsVector = false; - + if (typeInstance->IsBoxed()) { - } else { @@ -3138,8 +3184,8 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) diFieldTypes.push_back(memberType); } - bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive()); - for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++) + bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive()); + for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++) { auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx]; if (!fieldInstance->mFieldIncluded) @@ -3149,19 +3195,22 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed())) continue; - auto resolvedFieldType = fieldInstance->GetResolvedType(); + auto resolvedFieldType = fieldInstance->GetResolvedType(); mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration); BfIRType resolvedFieldIRType = MapType(resolvedFieldType); BfIRMDNode resolvedFieldDIType; if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct())) - PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full); + PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full); resolvedFieldDIType = DbgGetType(resolvedFieldType); + if (fieldInstance->IsAppendedObject()) + resolvedFieldDIType = DbgGetTypeInst(resolvedFieldType->ToTypeInstance()); + if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum())) { orderedFields.push_back(fieldInstance); - + int lineNum = 0; int flags = llvm::DINode::FlagPublic; auto fieldType = fieldInstance->mResolvedType; @@ -3182,7 +3231,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) { auto payloadType = fieldInstance->mResolvedType; if (payloadType == NULL) - payloadType = mModule->CreateTupleType(BfTypeVector(), Array()); + payloadType = mModule->CreateTupleType(BfTypeVector(), Array()); String fieldName = StrFormat("_%d_%s", -fieldInstance->mDataIdx - 1, fieldDef->mName.c_str()); @@ -3236,7 +3285,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) bool useIntConstant = false; bool wasMadeAddr = false; - + StringT<128> staticVarName; BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance); @@ -3251,18 +3300,18 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if ((constant->mConstType == BfConstType_Agg) || (constant->mConstType == BfConstType_AggZero) || (constant->mTypeCode == BfTypeCode_NullPtr)) - { + { staticValue = ConstToMemory(staticValue); - wasMadeAddr = true; + wasMadeAddr = true; } else if (constant->mTypeCode == BfTypeCode_StringId) { int stringId = constant->mInt32; const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString; if (resolvedFieldType->IsPointer()) - staticValue = mModule->GetStringCharPtr(str); - else - staticValue = mModule->GetStringObjectValue(str); + staticValue = mModule->GetStringCharPtr(str); + else + staticValue = mModule->GetStringObjectValue(str); } else { @@ -3270,9 +3319,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) continue; } } - + if (!useIntConstant) - { + { auto useType = resolvedFieldType; if (wasMadeAddr) useType = mModule->CreatePointerType(useType); @@ -3285,6 +3334,13 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) constDIType, flags, useIntConstant ? intConstant : BfIRValue()); diFieldTypes.push_back(memberType); + if (fieldDef->mUsingProtection != BfProtection_Hidden) + { + auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, 0, + constDIType, flags, useIntConstant ? intConstant : BfIRValue()); + diFieldTypes.push_back(memberType); + } + if (staticValue) { String qualifiedName = DbgGetStaticFieldName(fieldInstance); @@ -3296,7 +3352,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) { int flags = 0; String fieldName = fieldDef->mName; - if ((constant != NULL) && + if ((constant != NULL) && ((IsIntable(constant->mTypeCode)) || (IsFloat(constant->mTypeCode)))) { int64 writeVal = constant->mInt64; @@ -3309,7 +3365,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (writeVal < 0) fieldName += StrFormat("$_%llu", -writeVal); else - fieldName += StrFormat("$%llu", writeVal); + fieldName += StrFormat("$%llu", writeVal); } auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0, constDIType, flags, staticValue); @@ -3335,6 +3391,13 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) resolvedFieldDIType, flags, BfIRValue()); diFieldTypes.push_back(memberType); + if (fieldDef->mUsingProtection != BfProtection_Hidden) + { + auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldDef->mName, fileDIScope, 0, + resolvedFieldDIType, flags, BfIRValue()); + diFieldTypes.push_back(memberType); + } + StringT<128> staticVarName; BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance); if (!staticVarName.StartsWith('#')) @@ -3354,7 +3417,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) bool useForUnion = false; BF_ASSERT(!fieldInstance->mIsEnumPayloadCase); - + if (wantDIData) { int lineNum = 0; @@ -3364,9 +3427,17 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (fieldDef->mHasMultiDefs) fieldName += "$" + fieldDef->mDeclaringType->mProject->mName; auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum, - resolvedFieldType->mSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8, + fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8, flags, resolvedFieldDIType); diFieldTypes.push_back(memberType); + + if (fieldDef->mUsingProtection != BfProtection_Hidden) + { + auto memberType = DbgCreateMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, lineNum, + fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8, + flags, resolvedFieldDIType); + diFieldTypes.push_back(memberType); + } } } } @@ -3379,16 +3450,16 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) int unionSize = 0; if (typeInstance->mIsUnion) { - auto unionInnerType = typeInstance->GetUnionInnerType(); + auto unionInnerType = typeInstance->GetUnionInnerType(); unionSize = unionInnerType->mSize; dataPos += unionSize; } - + bool wantsMethods = true; // We can't directly call boxed methods from the debugger if (type->IsBoxed()) - wantsMethods = false; + wantsMethods = false; if (!isDefiningModule) wantsMethods = false; @@ -3399,8 +3470,8 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) { auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx]; auto methodInstance = methodGroup.mDefault; - - // We're only adding non-generic methods at the moment + + // We're only adding non-generic methods at the moment if ((methodInstance == NULL) || (methodInstance->mIsUnspecialized)) continue; @@ -3477,7 +3548,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) /*if (isPrimEnum) { - // Handled below + // Handled below } else*/ if (type->IsBoxed()) { @@ -3497,9 +3568,9 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) flags, DbgGetType(underlyingType)); diFieldTypes.push_back(memberType); } - } + } else - { + { auto baseType = typeInstance->mBaseType; if (baseType != NULL) @@ -3558,7 +3629,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) BfIRMDNode diType; /*if ((typeInstance->IsEnum()) && (typeInstance->IsTypedPrimitive())) - { + { llvm::SmallVector diEnumValues; for (auto& fieldInst : typeInstance->mFieldInstances) @@ -3580,10 +3651,10 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) DbgSetInstType(type, diType); } else*/ - { + { BfIRMDNode diCompositeType = DbgMakePermanent(diForwardDecl, BfIRMDNode(), diFieldTypes); diType = diCompositeType; - } + } } bool BfIRBuilder::WantsDbgDefinition(BfType* type) @@ -3667,6 +3738,9 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst if ((fieldDef != NULL) && (resolvedFieldType->IsStruct())) PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full); + if (fieldInstance->IsAppendedObject()) + PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full); + if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum())) { orderedFields.push_back(fieldInstance); @@ -3691,7 +3765,6 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst orderedFields.push_back(NULL); orderedFields[fieldInstance->mDataIdx] = fieldInstance; } - } } } @@ -3716,10 +3789,27 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst if (fieldInstance == NULL) continue; + auto fieldDef = fieldInstance->GetFieldDef(); + auto resolvedFieldType = fieldInstance->GetResolvedType(); BfIRType resolvedFieldIRType = MapType(resolvedFieldType); + if (fieldInstance->IsAppendedObject()) + { + auto fieldTypeInst = fieldInstance->mResolvedType->ToTypeInstance(); + + if (fieldInstance->mDataSize > fieldTypeInst->mInstSize) + { + SizedArray types; + types.push_back(MapTypeInst(fieldTypeInst)); + types.push_back(GetSizedArrayType(GetPrimitiveType(BfTypeCode_Int8), fieldInstance->mDataSize - fieldTypeInst->mInstSize)); + resolvedFieldIRType = CreateStructType(types); + } + else + resolvedFieldIRType = MapTypeInst(fieldTypeInst); + } + if (fieldInstance->mDataOffset > dataPos) { int fillSize = fieldInstance->mDataOffset - dataPos; @@ -3732,7 +3822,7 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst BF_ASSERT((int)irFieldTypes.size() == fieldInstance->mDataIdx); irFieldTypes.push_back(resolvedFieldIRType); - } + } if (isCRepr) { @@ -3749,7 +3839,6 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst if (typeInstance->mIsUnion) { - } else if ((typeInstance->IsEnum()) && (typeInstance->IsStruct())) { @@ -3771,7 +3860,7 @@ void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInst } void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine) -{ +{ auto populateModule = mModule->mContext->mUnreifiedModule; auto typeInstance = type->ToTypeInstance(); if (typeInstance != NULL) @@ -3780,7 +3869,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine) // This PopulateType is generally NOT needed, but here is a scenario in which it is: // ClassB derives from ClassA. ClassC uses ClassB. A method inside ClassA gets modified, // marking ClassA as incomplete, and then ClassC rebuilds and calls MapType on ClassB. - // "ClassB" itself is still populated, but its base class (ClassA) is not -- until we call + // "ClassB" itself is still populated, but its base class (ClassA) is not -- until we call // this PopulateType below. if (type->IsDataIncomplete()) populateModule->PopulateType(type, BfPopulateType_Data); @@ -3788,7 +3877,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine) bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction())); if (mModule->mExtensionCount != 0) isDefiningModule = false; - + // if (mModule->mModuleName == "vdata") // isDefiningModule = true; @@ -3807,14 +3896,14 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine) { DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8); } - + bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive()); - + if (typeInstance == NULL) - return; + return; BfType* underlyingArrayType = NULL; - int underlyingArraySize = -1; + int underlyingArraySize = -1; bool underlyingIsVector = false; typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingIsVector); if (underlyingArraySize > 0) @@ -3847,7 +3936,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine) //if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct())) //PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full); - + if ((!typeInstance->IsBoxed()) && (fieldDef != NULL)) { if (fieldDef->mIsConst) @@ -3888,10 +3977,8 @@ void BfIRBuilder::ReplaceDITemporaryTypes() mDITemporaryTypes.Clear(); } - void BfIRBuilder::PushDbgLoc(BfTypeInstance* typeInst) { - } BfIRPopulateType BfIRBuilder::GetPopulateTypeState(BfType* type) @@ -3906,7 +3993,7 @@ void BfIRBuilder::PopulateType(BfType* type, BfIRPopulateType populateType) { if (mIgnoreWrites) return; - + BF_ASSERT(!mModule->mIsScratchModule); if (populateType == BfIRPopulateType_Identity) @@ -3921,19 +4008,19 @@ void BfIRBuilder::PopulateType(BfType* type, BfIRPopulateType populateType) return; if (curPopulateType == BfIRPopulateType_Full) return; - + auto typeInst = type->ToTypeInstance(); if ((curPopulateType < BfIRPopulateType_Declaration) && (populateType >= BfIRPopulateType_Declaration)) - { + { CreateTypeDeclaration(type, populateType == BfIRPopulateType_Full_ForceDefinition); - + mTypeMap[type] = BfIRPopulateType_Declaration; } - + if ((curPopulateType < populateType) && (populateType >= BfIRPopulateType_Eventually_Full)) { - mTypeMap[type] = BfIRPopulateType_Eventually_Full; + mTypeMap[type] = BfIRPopulateType_Eventually_Full; CreateTypeDefinition(type, populateType == BfIRPopulateType_Full_ForceDefinition); mTypeMap[type] = BfIRPopulateType_Full; } @@ -3978,14 +4065,14 @@ BfIRValue BfIRBuilder::GetFakeConst() BfIRType BfIRBuilder::GetFakeType() { - BfIRType type; + BfIRType type; type.mId = GetFakeId(); return type; } BfIRType BfIRBuilder::GetFakeBlock() { - BfIRBlock block; + BfIRBlock block; block.mFlags = BfIRValueFlags_Block; block.mId = GetFakeId(); return block; @@ -4037,9 +4124,9 @@ void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray& mem } BfIRType BfIRBuilder::MapType(BfType* type, BfIRPopulateType populateType) -{ +{ if (!mIgnoreWrites) - { + { PopulateType(type, populateType); } BF_ASSERT(type->mTypeId > 0); @@ -4050,9 +4137,9 @@ BfIRType BfIRBuilder::MapType(BfType* type, BfIRPopulateType populateType) } BfIRType BfIRBuilder::MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType) -{ +{ if (!mIgnoreWrites) - { + { PopulateType(typeInst, populateType); } @@ -4065,7 +4152,7 @@ BfIRType BfIRBuilder::MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType pop } BfIRType BfIRBuilder::MapTypeInstPtr(BfTypeInstance* typeInst) -{ +{ if (!mIgnoreWrites) { PopulateType(typeInst, BfIRPopulateType_Declaration); @@ -4083,7 +4170,7 @@ BfIRType BfIRBuilder::GetType(BfIRValue val) return GetFakeType(); BfIRType retType = WriteCmd(BfIRCmd_GetType, val); - NEW_CMD_INSERTED_IRTYPE; + NEW_CMD_INSERTED_IRTYPE; return retType; } @@ -4119,7 +4206,7 @@ BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length) return retType; } else - { + { BfIRType retType = WriteCmd(BfIRCmd_GetSizedArrayType, elementType, length); NEW_CMD_INSERTED_IRTYPE; return retType; @@ -4127,10 +4214,10 @@ BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length) } BfIRType BfIRBuilder::GetVectorType(BfIRType elementType, int length) -{ +{ BfIRType retType = WriteCmd(BfIRCmd_GetVectorType, elementType, length); NEW_CMD_INSERTED_IRTYPE; - return retType; + return retType; } BfIRValue BfIRBuilder::CreateConstAgg_Value(BfIRType type, const BfSizedArray& values) @@ -4153,7 +4240,7 @@ BfIRValue BfIRBuilder::ConstToMemory(BfIRValue constVal) BfIRValue* value = NULL; if (mConstMemMap.TryGetValue(constVal.mId, &value)) return *value; - + BfIRType constType; if (constant->mConstType == BfConstType_Agg) constType = ((BfConstantAgg*)constant)->mType; @@ -4177,7 +4264,7 @@ BfIRValue BfIRBuilder::GetConfigConst(BfIRConfigConst constType, BfTypeCode type BfIRValue BfIRBuilder::GetArgument(int argIdx) { - BfIRValue retVal(BfIRValueFlags_Arg, argIdx); + BfIRValue retVal(BfIRValueFlags_Arg, argIdx); return retVal; } @@ -4273,8 +4360,8 @@ BfIRValue BfIRBuilder::CreateNumericCast(BfIRValue val, bool valIsSigned, BfType // Float -> Float return CreateConst(typeCode, constVal->mDouble); } - } - + } + auto retVal = WriteCmd(BfIRCmd_NumericCast, val, valIsSigned, typeCode); NEW_CMD_INSERTED_IRVALUE; return retVal; @@ -4283,14 +4370,14 @@ BfIRValue BfIRBuilder::CreateNumericCast(BfIRValue val, bool valIsSigned, BfType BfIRValue BfIRBuilder::CreateCmpEQ(BfIRValue lhs, BfIRValue rhs) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, ==); int eqVal = CheckConstEquality(lhs, rhs); if (eqVal != -1) return CreateConst(BfTypeCode_Boolean, (eqVal == 1) ? (uint64)1 : (uint64)0); } - auto retVal = WriteCmd(BfIRCmd_CmpEQ, lhs, rhs); + auto retVal = WriteCmd(BfIRCmd_CmpEQ, lhs, rhs); NEW_CMD_INSERTED_IRVALUE; return retVal; } @@ -4298,7 +4385,7 @@ BfIRValue BfIRBuilder::CreateCmpEQ(BfIRValue lhs, BfIRValue rhs) BfIRValue BfIRBuilder::CreateCmpNE(BfIRValue lhs, BfIRValue rhs) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, !=); int eqVal = CheckConstEquality(lhs, rhs); if (eqVal != -1) @@ -4313,18 +4400,17 @@ BfIRValue BfIRBuilder::CreateCmpNE(BfIRValue lhs, BfIRValue rhs) BfIRValue BfIRBuilder::CreateCmpLT(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, <); } else if ((!isSigned) && (rhs.IsConst())) - { + { // "unsigned < 0" is always false - auto constant = GetConstant(rhs); + auto constant = GetConstant(rhs); if ((IsInt(constant->mTypeCode)) && (constant->mUInt64 == 0)) return CreateConst(BfTypeCode_Boolean, 0); } - auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSLT : BfIRCmd_CmpULT, lhs, rhs); NEW_CMD_INSERTED_IRVALUE; return retVal; @@ -4333,10 +4419,10 @@ BfIRValue BfIRBuilder::CreateCmpLT(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateCmpLTE(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, <=); } - + auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSLE : BfIRCmd_CmpULE, lhs, rhs); NEW_CMD_INSERTED; return retVal; @@ -4345,7 +4431,7 @@ BfIRValue BfIRBuilder::CreateCmpLTE(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateCmpGT(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, >); } @@ -4357,13 +4443,13 @@ BfIRValue BfIRBuilder::CreateCmpGT(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateCmpGTE(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { CMP_APPLY(lhs, rhs, >=); } else if ((!isSigned) && (lhs.IsConst())) - { + { // "0 >= unsigned" is always true - auto constant = GetConstant(lhs); + auto constant = GetConstant(lhs); if ((IsInt(constant->mTypeCode)) && (constant->mUInt64 == 0)) return CreateConst(BfTypeCode_Boolean, 1); } @@ -4384,7 +4470,7 @@ BfIRValue BfIRBuilder::CreateAdd(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKi BINOPFUNC_APPLY(lhs, rhs, CheckedAdd); } } - + auto retVal = WriteCmd(BfIRCmd_Add, lhs, rhs, overflowCheckKind); NEW_CMD_INSERTED_IRVALUE; @@ -4401,7 +4487,7 @@ BfIRValue BfIRBuilder::CreateSub(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKi { mOpFailed = false; if ((lhs.IsConst()) && (rhs.IsConst())) - { + { BINOPFUNC_APPLY(lhs, rhs, CheckedSub); } @@ -4421,7 +4507,7 @@ BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKi { mOpFailed = false; if ((lhs.IsConst()) && (rhs.IsConst())) - { + { BINOPFUNC_APPLY(lhs, rhs, CheckedMul); } @@ -4452,7 +4538,7 @@ BfIRValue BfIRBuilder::CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned) if (constRHS->mInt64 != 0) { - INT_BINOP_APPLY(constLHS, constRHS, /); + INT_BINOP_APPLY(constLHS, constRHS, /); } } @@ -4464,7 +4550,7 @@ BfIRValue BfIRBuilder::CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { auto constLHS = GetConstantById(lhs.mId); auto constRHS = GetConstantById(rhs.mId); @@ -4476,7 +4562,7 @@ BfIRValue BfIRBuilder::CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned) if (constRHS->mInt64 != 0) { - INT_BINOP_APPLY(constLHS, constRHS, %); + INT_BINOP_APPLY(constLHS, constRHS, %); } } @@ -4488,7 +4574,7 @@ BfIRValue BfIRBuilder::CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateAnd(BfIRValue lhs, BfIRValue rhs) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { auto constLHS = GetConstantById(lhs.mId); auto constRHS = GetConstantById(rhs.mId); INT_BINOP_APPLY(constLHS, constRHS, &); @@ -4502,7 +4588,7 @@ BfIRValue BfIRBuilder::CreateAnd(BfIRValue lhs, BfIRValue rhs) BfIRValue BfIRBuilder::CreateOr(BfIRValue lhs, BfIRValue rhs) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { auto constLHS = GetConstantById(lhs.mId); auto constRHS = GetConstantById(rhs.mId); INT_BINOP_APPLY(constLHS, constRHS, |); @@ -4516,7 +4602,7 @@ BfIRValue BfIRBuilder::CreateOr(BfIRValue lhs, BfIRValue rhs) BfIRValue BfIRBuilder::CreateXor(BfIRValue lhs, BfIRValue rhs) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { auto constLHS = GetConstantById(lhs.mId); auto constRHS = GetConstantById(rhs.mId); INT_BINOP_APPLY(constLHS, constRHS, ^); @@ -4531,7 +4617,7 @@ BfIRValue BfIRBuilder::CreateShl(BfIRValue lhs, BfIRValue rhs) { mOpFailed = false; if ((lhs.IsConst()) && (rhs.IsConst())) - { + { INT_BINOPFUNC_APPLY(lhs, rhs, CheckedShl); } @@ -4543,10 +4629,10 @@ BfIRValue BfIRBuilder::CreateShl(BfIRValue lhs, BfIRValue rhs) BfIRValue BfIRBuilder::CreateShr(BfIRValue lhs, BfIRValue rhs, bool isSigned) { if ((lhs.IsConst()) && (rhs.IsConst())) - { + { auto constLHS = GetConstantById(lhs.mId); auto constRHS = GetConstantById(rhs.mId); - + uint64 val; if (isSigned) val = (uint64)(constLHS->mInt64 >> constRHS->mInt32); @@ -4563,7 +4649,7 @@ BfIRValue BfIRBuilder::CreateShr(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateNeg(BfIRValue val) { if (val.IsConst()) - { + { UNARYOP_APPLY(val, -); } @@ -4593,7 +4679,7 @@ BfIRValue BfIRBuilder::CreateNot(BfIRValue val) BfIRValue BfIRBuilder::CreateBitCast(BfIRValue val, BfIRType type) { if (val.IsConst()) - return CreateConstBitCast(val, type); + return CreateConstBitCast(val, type); auto retVal = WriteCmd(BfIRCmd_BitCast, val, type); NEW_CMD_INSERTED_IRVALUE; return retVal; @@ -4608,7 +4694,7 @@ BfIRValue BfIRBuilder::CreatePtrToInt(BfIRValue val, BfTypeCode typeCode) ptrToInt->mConstType = BfConstType_PtrToInt; ptrToInt->mTarget = val.mId; ptrToInt->mToTypeCode = typeCode; - + BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(ptrToInt)); #ifdef CHECK_CONSTHOLDER castedVal.mHolder = this; @@ -4654,7 +4740,7 @@ BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0) auto constGEP = mTempAlloc.Alloc(); constGEP->mConstType = BfConstType_GEP32_1; constGEP->mTarget = val.mId; - constGEP->mIdx0 = idx0; + constGEP->mIdx0 = idx0; BfIRValue retVal; retVal.mFlags = BfIRValueFlags_Const; @@ -4684,7 +4770,7 @@ BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0, int idx1) BfIRValue retVal; retVal.mFlags = BfIRValueFlags_Const; retVal.mId = mTempAlloc.GetChunkedId(constGEP); - + #ifdef CHECK_CONSTHOLDER retVal.mHolder = this; #endif @@ -4780,7 +4866,7 @@ BfIRValue BfIRBuilder::CreateIsNotNull(BfIRValue val) if (constant->mConstType == BfConstType_BitCastNull) return CreateConst(BfTypeCode_Boolean, 0); if (constant->mConstType == BfConstType_GlobalVar) - return CreateConst(BfTypeCode_Boolean, 1); + return CreateConst(BfTypeCode_Boolean, 1); } BfIRValue retVal = WriteCmd(BfIRCmd_IsNotNull, val); @@ -4789,7 +4875,7 @@ BfIRValue BfIRBuilder::CreateIsNotNull(BfIRValue val) } BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx) -{ +{ auto aggConstant = GetConstant(val); if (aggConstant != NULL) { @@ -4798,7 +4884,7 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx) auto arrayConstant = (BfConstantAgg*)aggConstant; return arrayConstant->mValues[idx]; } - + auto constGEP = mTempAlloc.Alloc(); constGEP->mConstType = BfConstType_ExtractValue; constGEP->mTarget = val.mId; @@ -4811,7 +4897,7 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx) #ifdef CHECK_CONSTHOLDER retVal.mHolder = this; #endif - return retVal; + return retVal; } BfIRValue retVal = WriteCmd(BfIRCmd_ExtractValue, val, idx); @@ -4820,11 +4906,11 @@ BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx) } BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, BfIRValue idx) -{ +{ auto idxConst = GetConstant(idx); if (idxConst != NULL) { - BF_ASSERT(IsInt(idxConst->mTypeCode)); + BF_ASSERT(IsInt(idxConst->mTypeCode)); return CreateExtractValue(val, idxConst->mInt32); } @@ -4901,12 +4987,19 @@ BfIRValue BfIRBuilder::CreateLifetimeStart(BfIRValue val) } BfIRValue BfIRBuilder::CreateLifetimeEnd(BfIRValue val) -{ +{ BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeEnd, val); NEW_CMD_INSERTED; return retVal; } +BfIRValue BfIRBuilder::CreateLifetimeSoftEnd(BfIRValue val) +{ + BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeSoftEnd, val); + NEW_CMD_INSERTED; + return retVal; +} + BfIRValue BfIRBuilder::CreateLifetimeExtend(BfIRValue val) { BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeExtend, val); @@ -4940,7 +5033,7 @@ void BfIRBuilder::CreateValueScopeHardEnd(BfIRValue scopeStart) } BfIRValue BfIRBuilder::CreateLoad(BfIRValue val, bool isVolatile) -{ +{ BfIRValue retVal = WriteCmd(BfIRCmd_Load, val, isVolatile); NEW_CMD_INSERTED_IRVALUE; return retVal; @@ -4961,7 +5054,7 @@ BfIRValue BfIRBuilder::CreateStore(BfIRValue val, BfIRValue ptr, bool isVolatile } BfIRValue BfIRBuilder::CreateAlignedStore(BfIRValue val, BfIRValue ptr, int align, bool isVolatile) -{ +{ BfIRValue retVal = WriteCmd(BfIRCmd_AlignedStore, val, ptr, align, isVolatile); NEW_CMD_INSERTED_IRVALUE; return retVal; @@ -4997,7 +5090,7 @@ BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal) void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue) { auto globalVar = (BfGlobalVar*)GetConstant(irValue); - + if ((!mIgnoreWrites) && (globalVar->mStreamId == -1)) { if (globalVar->mInitializer) @@ -5006,7 +5099,7 @@ void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue) 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; + NEW_CMD_INSERTED_IRVALUE; } } @@ -5038,14 +5131,14 @@ BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool i BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) { - auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS); + auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS); CreateGlobalVariable(irValue); return irValue; } void BfIRBuilder::GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr) { - BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetUnnamedAddr, val, unnamedAddr); + BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetUnnamedAddr, val, unnamedAddr); NEW_CMD_INSERTED; } @@ -5078,7 +5171,7 @@ BfIRValue BfIRBuilder::CreateGlobalStringPtr(const StringImpl& str) void BfIRBuilder::SetReflectTypeData(BfIRType type, BfIRValue globalVar) { BfIRValue retVal = WriteCmd(BfIRCmd_SetReflectTypeData, type, globalVar); - NEW_CMD_INSERTED_IRVALUE; + NEW_CMD_INSERTED_IRVALUE; } BfIRBlock BfIRBuilder::CreateBlock(const StringImpl& name, bool addNow) @@ -5086,7 +5179,7 @@ BfIRBlock BfIRBuilder::CreateBlock(const StringImpl& name, bool addNow) if (addNow) mActiveFunctionHasBody = true; mBlockCount++; - BfIRBlock retBlock = WriteCmd(BfIRCmd_CreateBlock, name, addNow); + BfIRBlock retBlock = WriteCmd(BfIRCmd_CreateBlock, name, addNow); NEW_CMD_INSERTED_IRBLOCK; return retBlock; } @@ -5125,12 +5218,12 @@ void BfIRBuilder::MergeBlockDown(BfIRBlock fromBlock, BfIRBlock intoBlock) void BfIRBuilder::SetInsertPoint(BfIRValue value) { - BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPoint, value); + BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPoint, value); NEW_CMD_INSERTED; } void BfIRBuilder::SetInsertPoint(BfIRBlock block) -{ +{ BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPoint, block); if (!mIgnoreWrites) { @@ -5199,7 +5292,7 @@ void BfIRBuilder::CreateCondBr(BfIRValue val, BfIRBlock trueBlock, BfIRBlock fal } BfIRBlock BfIRBuilder::GetInsertBlock() -{ +{ if (!mIgnoreWrites) { BF_ASSERT(!mActualInsertBlock.IsFake()); @@ -5264,7 +5357,7 @@ BfIRFunctionType BfIRBuilder::MapMethod(BfMethodInstance* methodInstance) bool useCache = (!mModule->mIsSpecialModule) && (methodInstance->mMethodDef->mIdx >= 0); if (useCache) - { + { BfIRFunctionType* funcType = NULL; if (mMethodTypeMap.TryGetValue(methodInstance, &funcType)) return *funcType; @@ -5283,23 +5376,23 @@ BfIRFunctionType BfIRBuilder::MapMethod(BfMethodInstance* methodInstance) BfIRFunctionType BfIRBuilder::CreateFunctionType(BfIRType resultType, const BfSizedArray& paramTypes, bool isVarArg) { - BfIRFunctionType retType = WriteCmd(BfIRCmd_CreateFunctionType, resultType, paramTypes, isVarArg); + BfIRFunctionType retType = WriteCmd(BfIRCmd_CreateFunctionType, resultType, paramTypes, isVarArg); NEW_CMD_INSERTED_IRFUNCTYPE; return retType; } BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name) -{ +{ if (mIgnoreWrites) { - auto fakeVal = GetFakeVal(); + auto fakeVal = GetFakeVal(); return fakeVal; } BF_ASSERT(mModule->mIsModuleMutable); - BfIRFunction retVal = WriteCmd(BfIRCmd_CreateFunction, funcType, (uint8)linkageType, name); - NEW_CMD_INSERTED_IRVALUE; + BfIRFunction retVal = WriteCmd(BfIRCmd_CreateFunction, funcType, (uint8)linkageType, name); + NEW_CMD_INSERTED_IRVALUE; StringView nameSV = StringView(AllocStr(name), name.mLength); mFunctionMap[nameSV] = retVal; @@ -5312,7 +5405,7 @@ BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageT void BfIRBuilder::SetFunctionName(BfIRValue func, const StringImpl& name) { WriteCmd(BfIRCmd_SetFunctionName, func, name); - NEW_CMD_INSERTED_IRVALUE; + NEW_CMD_INSERTED_IRVALUE; } void BfIRBuilder::EnsureFunctionPatchable() @@ -5329,7 +5422,7 @@ BfIRValue BfIRBuilder::RemapBindFunction(BfIRValue func) } void BfIRBuilder::SetActiveFunction(BfIRFunction func) -{ +{ //BfLogSys(mModule->mSystem, "BfIRBuilder::SetActiveFunction: %d\n", func.mId); if (mActiveFunctionHasBody) @@ -5337,17 +5430,17 @@ void BfIRBuilder::SetActiveFunction(BfIRFunction func) WriteCmd(BfIRCmd_SetActiveFunction, func); mActiveFunction = func; - mActiveFunctionHasBody = false; + mActiveFunctionHasBody = false; NEW_CMD_INSERTED; } BfIRFunction BfIRBuilder::GetActiveFunction() -{ +{ return mActiveFunction; } BfIRFunction BfIRBuilder::GetFunction(const StringImpl& name) -{ +{ BfIRFunction* funcPtr = NULL; if (mFunctionMap.TryGetValue(name, &funcPtr)) return *funcPtr; @@ -5417,7 +5510,7 @@ void BfIRBuilder::CreateUnreachable() void BfIRBuilder::Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr) { - WriteCmd(BfIRCmd_Call_AddAttribute, callInst, argIdx, attr); + WriteCmd(BfIRCmd_Call_AddAttribute, callInst, argIdx, attr); NEW_CMD_INSERTED; } @@ -5455,7 +5548,7 @@ void BfIRBuilder::Func_DeleteBody(BfIRFunction func) } void BfIRBuilder::Func_SafeRename(BfIRFunction func) -{ +{ WriteCmd(BfIRCmd_Func_SafeRename, func); // We don't actually remove it from the named map. It doesn't matter for us. @@ -5468,6 +5561,12 @@ void BfIRBuilder::Func_SafeRename(BfIRFunction func) NEW_CMD_INSERTED; } +void BfIRBuilder::Func_SafeRenameFrom(BfIRFunction func, const StringImpl& prevName) +{ + WriteCmd(BfIRCmd_Func_SafeRenameFrom, func, prevName); + NEW_CMD_INSERTED; +} + void BfIRBuilder::Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage) { WriteCmd(BfIRCmd_Func_SetLinkage, func, (uint8)linkage); @@ -5516,7 +5615,7 @@ BfIRValue BfIRBuilder::Comptime_GetInterfaceFunc(BfIRValue value, int typeId, in } void BfIRBuilder::SaveDebugLocation() -{ +{ if (!mIgnoreWrites) { mSavedDebugLocs.push_back(mModule->mCurFilePosition); @@ -5526,7 +5625,7 @@ void BfIRBuilder::SaveDebugLocation() } void BfIRBuilder::RestoreDebugLocation() -{ +{ if (!mIgnoreWrites) { mModule->mCurFilePosition = mSavedDebugLocs.back(); @@ -5539,12 +5638,12 @@ void BfIRBuilder::RestoreDebugLocation() void BfIRBuilder::DupDebugLocation() { - WriteCmd(BfIRCmd_DupDebugLocation); + WriteCmd(BfIRCmd_DupDebugLocation); NEW_CMD_INSERTED; } bool BfIRBuilder::HasDebugLocation() -{ +{ return mHasDebugLoc; } @@ -5605,7 +5704,7 @@ void BfIRBuilder::CreateStatementStart() void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm) { - auto retBlock = WriteCmd(BfIRCmd_ObjectAccessCheck, value, useAsm); + auto retBlock = WriteCmd(BfIRCmd_ObjectAccessCheck, value, useAsm); NEW_CMD_INSERTED_IRBLOCK; if (!mIgnoreWrites) { @@ -5619,14 +5718,14 @@ void BfIRBuilder::DbgInit() { mHasDebugInfo = true; mHasDebugLineInfo = true; - WriteCmd(BfIRCmd_DbgInit); + WriteCmd(BfIRCmd_DbgInit); NEW_CMD_INSERTED; } void BfIRBuilder::DbgFinalize() -{ +{ while ((!mDeferredDbgTypeDefs.IsEmpty()) || (!mDITemporaryTypes.IsEmpty())) - { + { //for (auto deferredType : mDeferredDbgTypeDefs) for (int i = 0; i < (int)mDeferredDbgTypeDefs.size(); i++) CreateDbgTypeDefinition(mDeferredDbgTypeDefs[i]); @@ -5641,7 +5740,7 @@ void BfIRBuilder::DbgFinalize() bool BfIRBuilder::DbgHasInfo() { - return mHasDebugInfo; + return mHasDebugInfo; } bool BfIRBuilder::DbgHasLineInfo() @@ -5656,7 +5755,7 @@ String BfIRBuilder::DbgGetStaticFieldName(BfFieldInstance* fieldInstance) auto typeInstance = fieldInstance->mOwner; auto typeDef = typeInstance->mTypeDef; if (mModule->mCompiler->mOptions.IsCodeView()) - { + { fieldName += "_bf"; for (int partIdx = 0; partIdx < typeInstance->mTypeDef->mNamespace.GetPartsCount(); partIdx++) { @@ -5692,12 +5791,12 @@ BfIRMDNode BfIRBuilder::DbgCreateCompileUnit(int lang, const StringImpl& fileNam } BfIRMDNode BfIRBuilder::DbgCreateFile(const StringImpl& fileName, const StringImpl& directory, const Val128& md5Hash) -{ +{ BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateFile, fileName, directory, md5Hash); NEW_CMD_INSERTED_IRMD; if (mDbgVerifyCodeGen && gDebugDbgLoc) - { + { OutputDebugStrF("DbgCreateFile %s %d\n", fileName.c_str(), retVal.mId); } @@ -5753,7 +5852,7 @@ BfIRMDNode BfIRBuilder::DbgGetTypeInst(BfTypeInstance* typeInst, BfIRPopulateTyp void BfIRBuilder::DbgTrackDITypes(BfType* type) { BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgTrackDITypes, type->mTypeId); - NEW_CMD_INSERTED; + NEW_CMD_INSERTED; } BfIRMDNode BfIRBuilder::DbgCreateNameSpace(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNum) @@ -5778,7 +5877,7 @@ BfIRMDNode BfIRBuilder::DbgCreateBasicType(const StringImpl& name, int64 sizeInB } BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray& elements) -{ +{ BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, (int32)sizeInBits, (int32)alignInBits, flags, derivedFrom, elements); NEW_CMD_INSERTED_IRMD; return retVal; @@ -5827,7 +5926,7 @@ BfIRMDNode BfIRBuilder::DbgCreateArrayType(int64 sizeInBits, int64 alignInBits, } BfIRMDNode BfIRBuilder::DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits, int flags) -{ +{ BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits, flags); NEW_CMD_INSERTED_IRMD; return retVal; @@ -5902,12 +6001,12 @@ BfIRMDNode BfIRBuilder::DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseTyp return retVal; } -BfIRMDNode BfIRBuilder::DbgCreateMethod(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags, +BfIRMDNode BfIRBuilder::DbgCreateMethod(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags, bool isOptimized, BfIRValue fn, const BfSizedArray& genericArgs, const BfSizedArray& genericConstValueArgs) { BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMethod, context, name, linkageName, file, lineNum, type, isLocalToUnit, isDefinition, vk, vIndex, vTableHolder, flags, isOptimized, fn, genericArgs, genericConstValueArgs); NEW_CMD_INSERTED_IRMD; - + // if (mDbgVerifyCodeGen && gDebugDbgLoc) // { // OutputDebugStrF("DbgCreateFunction Context:%d name:%s = %d\n", context.mId, name.c_str(), retVal.mId); @@ -5917,14 +6016,14 @@ BfIRMDNode BfIRBuilder::DbgCreateMethod(BfIRMDNode context, const StringImpl& na } BfIRMDNode BfIRBuilder::DbgCreateFunction(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int scopeLine, int flags, bool isOptimized, BfIRValue fn) -{ +{ BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateFunction, context, name, linkageName, file, lineNum, type, isLocalToUnit, isDefinition, scopeLine, flags, isOptimized, fn); NEW_CMD_INSERTED_IRMD; // if (mDbgVerifyCodeGen && gDebugDbgLoc) // { // OutputDebugStrF("DbgCreateFunction Context:%d name:%s = %d\n", context.mId, name.c_str(), retVal.mId); -// } +// } return retVal; } @@ -6011,8 +6110,8 @@ BfIRValue BfIRBuilder::DbgLifetimeEnd(BfIRMDNode varInfo) } void BfIRBuilder::DbgCreateGlobalVariable(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNumber, BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode decl) -{ - WriteCmd(BfIRCmd_DbgCreateGlobalVariable, context, name, linkageName, file, lineNumber, type, isLocalToUnit, val, decl); +{ + WriteCmd(BfIRCmd_DbgCreateGlobalVariable, context, name, linkageName, file, lineNumber, type, isLocalToUnit, val, decl); NEW_CMD_INSERTED; } @@ -6053,4 +6152,4 @@ void BfIRBuilder::SetState(const BfIRState& state) mActiveFunction = state.mActiveFunction; mActiveFunctionHasBody = state.mActiveFunctionHasBody; mSavedDebugLocs = state.mSavedDebugLocs; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index a892b11e..2374ea81 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -60,16 +60,16 @@ public: mCurSrcPos = 0; mCurLine = 0; mCurColumn = 0; - } + } }; enum BfTypeCode : uint8 -{ +{ BfTypeCode_None, BfTypeCode_CharPtr, BfTypeCode_StringId, BfTypeCode_Pointer, - BfTypeCode_NullPtr, + BfTypeCode_NullPtr, BfTypeCode_Self, BfTypeCode_Dot, BfTypeCode_Var, @@ -123,7 +123,7 @@ enum BfTypeCode : uint8 enum BfConstType { - BfConstType_GlobalVar = BfTypeCode_Length, + BfConstType_GlobalVar = BfTypeCode_Length, BfConstType_BitCast, BfConstType_BitCastNull, BfConstType_GEP32_1, @@ -145,13 +145,13 @@ enum BfConstType enum BfIRValueFlags : uint8 { - BfIRValueFlags_None, + BfIRValueFlags_None, BfIRValueFlags_Value = 1, BfIRValueFlags_Arg = 2, BfIRValueFlags_Const = 4, BfIRValueFlags_FromLLVM = 8, BfIRValueFlags_Block = 16, - BfIRValueFlags_Func = 32 + BfIRValueFlags_Func = 32 }; enum BfIRCmd : uint8 @@ -162,7 +162,7 @@ enum BfIRCmd : uint8 BfIRCmd_WriteIR, BfIRCmd_SetType, - BfIRCmd_SetInstType, + BfIRCmd_SetInstType, BfIRCmd_PrimitiveType, BfIRCmd_CreateAnonymousStruct, BfIRCmd_CreateStruct, @@ -175,7 +175,7 @@ enum BfIRCmd : uint8 BfIRCmd_GetPointerToType, BfIRCmd_GetSizedArrayType, BfIRCmd_GetVectorType, - + BfIRCmd_CreateConstStructZero, BfIRCmd_CreateConstAgg, BfIRCmd_CreateConstArrayZero, @@ -228,8 +228,9 @@ enum BfIRCmd : uint8 BfIRCmd_SetAllocaNoChkStkHint, BfIRCmd_SetAllocaForceMem, BfIRCmd_AliasValue, - BfIRCmd_LifetimeStart, + BfIRCmd_LifetimeStart, BfIRCmd_LifetimeEnd, + BfIRCmd_LifetimeSoftEnd, BfIRCmd_LifetimeExtend, BfIRCmd_ValueScopeStart, BfIRCmd_ValueScopeRetain, @@ -254,9 +255,9 @@ enum BfIRCmd : uint8 BfIRCmd_CreateBlock, BfIRCmd_MaybeChainNewBlock, - BfIRCmd_AddBlock, + BfIRCmd_AddBlock, BfIRCmd_DropBlocks, - BfIRCmd_MergeBlockDown, + BfIRCmd_MergeBlockDown, BfIRCmd_GetInsertBlock, BfIRCmd_SetInsertPoint, BfIRCmd_SetInsertPointAtStart, @@ -275,9 +276,9 @@ enum BfIRCmd : uint8 BfIRCmd_CreatePhi, BfIRCmd_AddPhiIncoming, - BfIRCmd_GetIntrinsic, - BfIRCmd_CreateFunctionType, - BfIRCmd_CreateFunction, + BfIRCmd_GetIntrinsic, + BfIRCmd_CreateFunctionType, + BfIRCmd_CreateFunction, BfIRCmd_SetFunctionName, BfIRCmd_EnsureFunctionPatchable, BfIRCmd_RemapBindFunction, @@ -292,12 +293,13 @@ enum BfIRCmd : uint8 BfIRCmd_CreateRetVoid, BfIRCmd_CreateUnreachable, BfIRCmd_Call_AddAttribute, - BfIRCmd_Call_AddAttribute1, + BfIRCmd_Call_AddAttribute1, BfIRCmd_Func_AddAttribute, BfIRCmd_Func_AddAttribute1, - BfIRCmd_Func_SetParamName, + BfIRCmd_Func_SetParamName, BfIRCmd_Func_DeleteBody, BfIRCmd_Func_SafeRename, + BfIRCmd_Func_SafeRenameFrom, BfIRCmd_Func_SetLinkage, BfIRCmd_Comptime_Error, @@ -383,7 +385,7 @@ enum BfIRParamType : uint8 BfIRParamType_Arg, BfIRParamType_StreamId_Abs8, BfIRParamType_StreamId_Rel, - BfIRParamType_StreamId_Back1, + BfIRParamType_StreamId_Back1, BfIRParamType_StreamId_Back_LAST = 0xFF, // Use remaining encoding }; @@ -423,9 +425,9 @@ enum BfIRIntrinsic : uint8 BfIRIntrinsic_AtomicAnd, BfIRIntrinsic_AtomicCmpStore, BfIRIntrinsic_AtomicCmpStore_Weak, - BfIRIntrinsic_AtomicCmpXChg, + BfIRIntrinsic_AtomicCmpXChg, BfIRIntrinsic_AtomicFence, - BfIRIntrinsic_AtomicLoad, + BfIRIntrinsic_AtomicLoad, BfIRIntrinsic_AtomicMax, BfIRIntrinsic_AtomicMin, BfIRIntrinsic_AtomicNAnd, @@ -438,14 +440,14 @@ enum BfIRIntrinsic : uint8 BfIRIntrinsic_AtomicXor, BfIRIntrinsic_BSwap, BfIRIntrinsic_Cast, - BfIRIntrinsic_Cos, + BfIRIntrinsic_Cos, BfIRIntrinsic_DebugTrap, BfIRIntrinsic_Div, BfIRIntrinsic_Eq, BfIRIntrinsic_Floor, - BfIRIntrinsic_Free, + BfIRIntrinsic_Free, BfIRIntrinsic_Gt, - BfIRIntrinsic_GtE, + BfIRIntrinsic_GtE, BfIRIntrinsic_Index, BfIRIntrinsic_Log, BfIRIntrinsic_Log10, @@ -457,7 +459,7 @@ enum BfIRIntrinsic : uint8 BfIRIntrinsic_MemMove, BfIRIntrinsic_MemSet, BfIRIntrinsic_Mod, - BfIRIntrinsic_Mul, + BfIRIntrinsic_Mul, BfIRIntrinsic_Neq, BfIRIntrinsic_Not, BfIRIntrinsic_Or, @@ -470,8 +472,8 @@ enum BfIRIntrinsic : uint8 BfIRIntrinsic_SHR, BfIRIntrinsic_Shuffle, BfIRIntrinsic_Sin, - BfIRIntrinsic_Sqrt, - BfIRIntrinsic_Sub, + BfIRIntrinsic_Sqrt, + BfIRIntrinsic_Sub, BfIRIntrinsic_VAArg, BfIRIntrinsic_VAEnd, BfIRIntrinsic_VAStart, @@ -535,7 +537,7 @@ public: ID_IMPLICIT = -3 }; -public: +public: int mId; BfIRValueFlags mFlags; static BfIRValue sValueless; @@ -546,7 +548,7 @@ public: public: BfIRValue() - { + { mId = -1; mFlags = BfIRValueFlags_None; #ifdef CHECK_CONSTHOLDER @@ -555,7 +557,7 @@ public: } BfIRValue(const BfIRValue& from) - { + { mFlags = from.mFlags; mId = from.mId; #ifdef CHECK_CONSTHOLDER @@ -564,23 +566,23 @@ public: } BfIRValue(BfIRValueFlags flags, int id) - { + { mFlags = flags; - mId = id; + mId = id; } - + operator bool() const - { + { return mFlags != BfIRValueFlags_None; - } - + } + bool IsFake() const; bool IsConst() const; - bool IsArg() const; + bool IsArg() const; bool IsFromLLVM() const; bool operator==(const BfIRValue& rhs) const - { + { if (mFlags != rhs.mFlags) return false; if (mId != rhs.mId) @@ -589,7 +591,7 @@ public: } bool operator!=(const BfIRValue& rhs) const - { + { if (mFlags != rhs.mFlags) return true; if (mId != rhs.mId) @@ -606,7 +608,7 @@ struct BfIRTypeData TypeKind_TypeId, TypeKind_TypeCode, TypeKind_TypeInstId, - TypeKind_TypeInstPtrId, + TypeKind_TypeInstPtrId, TypeKind_Stream, TypeKind_SizedArray }; @@ -622,12 +624,12 @@ struct BfIRTypeData struct BfIRType : public BfIRTypeData { -public: +public: BfIRType() { mKind = TypeKind_None; mId = -1; - } + } BfIRType(BfIRTypeData typeData) { @@ -635,17 +637,17 @@ public: mId = typeData.mId; } - BfIRType(const BfIRValue& val) { mKind = TypeKind_Stream; mId = val.mId; } + BfIRType(const BfIRValue& val) { mKind = TypeKind_Stream; mId = val.mId; } }; struct BfIRBlock : public BfIRValue { -public: +public: BfIRBlock(); - BfIRBlock(const BfIRValue& fromVal) : BfIRValue(fromVal) {} + BfIRBlock(const BfIRValue& fromVal) : BfIRValue(fromVal) {} }; -enum BfIRAttribute +enum BfIRAttribute { BfIRAttribute_NoReturn, BfIRAttribute_NoAlias, @@ -668,83 +670,83 @@ enum BfIRAttribute struct BfIRFunctionType { -public: - int mId; +public: + int mId; -public: +public: BfIRFunctionType(); - BfIRFunctionType(const BfIRValue& val) { mId = val.mId; } + BfIRFunctionType(const BfIRValue& val) { mId = val.mId; } operator bool() const { return mId != -1; - } + } }; struct BfIRFunction : public BfIRRawValue { -public: +public: BfIRFunction(); BfIRFunction(const BfIRValue& val) { BF_ASSERT((val.mFlags == BfIRValueFlags_None) || (val.mFlags == BfIRValueFlags_Value)); mId = val.mId; - } + } //: BfIRValue(val) {} - + bool operator==(const BfIRFunction& rhs) const - { + { if (mId != rhs.mId) return false; return true; } bool operator!=(const BfIRFunction& rhs) const - { + { if (mId == rhs.mId) return false; return true; } operator bool() const - { + { return mId != -1; } operator BfIRValue() const - { + { return BfIRValue((mId == -1) ? BfIRValueFlags_None : BfIRValueFlags_Value, mId); } }; struct BfIRMDNode { -public: +public: int mId; BfIRMDNode() - { + { mId = -1; } BfIRMDNode(const BfIRValue& val) - { + { mId = val.mId; } - + operator bool() const - { + { return mId != -1; - } + } bool operator==(const BfIRMDNode& rhs) const - { + { if (mId != rhs.mId) return false; return true; } bool operator!=(const BfIRMDNode& rhs) const - { + { if (mId == rhs.mId) return false; return true; @@ -761,7 +763,7 @@ public: public: BfFileInstance() { - mParser = NULL; + mParser = NULL; } }; @@ -774,7 +776,7 @@ struct BfGlobalVar BfIRLinkageType mLinkageType; int mStreamId; BfIRValue mInitializer; - bool mIsTLS; + bool mIsTLS; int mAlignment; }; @@ -787,7 +789,7 @@ struct BfGlobalVar_TypeInst BfIRLinkageType mLinkageType; int mStreamId; BfIRValue mInitializer; - bool mIsTLS; + bool mIsTLS; }; struct BfTypeOf_Const @@ -811,7 +813,7 @@ public: { BfTypeCode mTypeCode; BfConstType mConstType; - }; + }; union { bool mBool; @@ -884,7 +886,7 @@ struct BfConstantGEP32_1 { BfConstType mConstType; int mTarget; - int mIdx0; + int mIdx0; }; struct BfConstantGEP32_2 @@ -899,7 +901,7 @@ struct BfConstantExtractValue { BfConstType mConstType; int mTarget; - int mIdx0; + int mIdx0; }; struct BfConstantAgg @@ -929,15 +931,15 @@ public: BumpAllocatorT<256> mTempAlloc; BfModule* mModule; Dictionary mGlobalVarMap; - + public: void FixTypeCode(BfTypeCode& typeCode); int GetSize(BfTypeCode typeCode); static int GetSize(BfTypeCode typeCode, int ptrSize); - static bool IsInt(BfTypeCode typeCode); + static bool IsInt(BfTypeCode typeCode); static bool IsChar(BfTypeCode typeCode); static bool IsIntable(BfTypeCode typeCode); - static bool IsSigned(BfTypeCode typeCode); + static bool IsSigned(BfTypeCode typeCode); static bool IsFloat(BfTypeCode typeCode); const char* AllocStr(const StringImpl& str); @@ -945,7 +947,11 @@ public: BfIRConstHolder(BfModule* module); virtual ~BfIRConstHolder(); - BfConstant* GetConstantById(int id); + String ToString(BfIRValue irValue); + String ToString(BfIRType irType); + void pv(const BfIRValue& irValue); + + BfConstant* GetConstantById(int id); BfConstant* GetConstant(BfIRValue id); bool TryGetBool(BfIRValue id, bool& boolVal); int IsZero(BfIRValue val); @@ -953,7 +959,9 @@ public: int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true //void WriteConstant(void* data, BeConstant* constVal); - BfIRValue CreateConst(BfTypeCode typeCode, uint64 val); + BfIRType GetSizedArrayType(BfIRType elementType, int length); + + BfIRValue CreateConst(BfTypeCode typeCode, uint64 val); BfIRValue CreateConst(BfTypeCode typeCode, int val); BfIRValue CreateConst(BfTypeCode typeCode, double val); BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder); @@ -968,11 +976,11 @@ public: BfIRValue CreateConstBox(BfIRValue val, BfIRType type); BfIRValue CreateTypeOf(BfType* type); 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); - BfIRValue ReadConstant(void* ptr, BfType* type); + BfIRValue ReadConstant(void* ptr, BfType* type); }; enum BfIRPopulateType @@ -1003,16 +1011,16 @@ enum BfOverflowCheckKind : int8 class BfIRBuilder : public BfIRConstHolder { -public: +public: bool mIgnoreWrites; bool mDbgVerifyCodeGen; int mCurFakeId; bool mHasGlobalDefs; bool mIsBeefBackend; - int mNumFunctionsWithBodies; + int mNumFunctionsWithBodies; int mBlockCount; - bool mHasStarted; - int mCmdCount; + bool mHasStarted; + int mCmdCount; ChunkedDataBuffer mStream; BfIRBlock mActualInsertBlock; // Only when not ignoring writes @@ -1024,12 +1032,12 @@ public: Dictionary mFunctionMap; Dictionary mTypeMap; Dictionary mConstMemMap; - Array mDITemporaryTypes; + Array mDITemporaryTypes; BfIRFunction mActiveFunction; bool mActiveFunctionHasBody; Array mSavedDebugLocs; Array mDeferredDbgTypeDefs; - + BfIRCodeGenBase* mIRCodeGen; BfIRCodeGen* mBfIRCodeGen; BeIRCodeGen* mBeIRCodeGen; @@ -1042,7 +1050,7 @@ public: public: ~BfIRBuilder(); - + void WriteSLEB128(int64 val); void WriteSLEB128(int32 val); void Write(uint8 val); @@ -1053,24 +1061,24 @@ public: void Write(const StringImpl& str); void Write(const BfIRValue& irValue); void Write(BfTypeCode typeCode); - void Write(const BfIRTypeData& type); + void Write(const BfIRTypeData& type); void Write(BfIRFunctionType func); void Write(BfIRFunction funcType); void Write(BfIRBlock block); - void Write(BfIRMDNode node); + void Write(BfIRMDNode node); template void Write(const BfSizedArray& sizedArray) { - WriteSLEB128(sizedArray.mSize); + WriteSLEB128(sizedArray.mSize); for (int i = 0; i < sizedArray.mSize; i++) Write(sizedArray.mVals[i]); - } - BfIRValue WriteCmd(BfIRCmd cmd); + } + BfIRValue WriteCmd(BfIRCmd cmd); template void WriteArg(const T& first) { - Write(first); + Write(first); } template @@ -1082,17 +1090,17 @@ public: template BfIRValue WriteCmd(BfIRCmd cmd, const Args&... args) - { + { if (mIgnoreWrites) return GetFakeVal(); //int dataPos = mStream.GetSize(); - auto result = WriteCmd(cmd); - WriteArg(args...); + auto result = WriteCmd(cmd); + WriteArg(args...); return result; //return BfIRValue(BfIRValueFlags_Value, dataPos); } -public: +public: void NewCmdInserted(); BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope); String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName); @@ -1106,18 +1114,18 @@ public: BfIRPopulateType GetPopulateTypeState(BfType* type); void PopulateType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Full); void SetType(BfType* type, BfIRType irType); - void SetInstType(BfType* type, BfIRType irType); + void SetInstType(BfType* type, BfIRType irType); int GetFakeId(); BfIRValue GetFakeVal(); BfIRValue GetFakeConst(); - BfIRType GetFakeType(); - BfIRType GetFakeBlock(); - BfIRFunctionType GetFakeFunctionType(); - BfIRFunction GetFakeFunction(); + BfIRType GetFakeType(); + BfIRType GetFakeBlock(); + BfIRFunctionType GetFakeFunctionType(); + BfIRFunction GetFakeFunction(); public: void OpFailed(); - + uint8 CheckedAdd(uint8 a, uint8 b); uint16 CheckedAdd(uint16 a, uint16 b); uint32 CheckedAdd(uint32 a, uint32 b); @@ -1161,7 +1169,7 @@ public: int64 CheckedShl(int64 a, int64 b); public: - BfIRBuilder(BfModule* module); + BfIRBuilder(BfModule* module); bool HasExports(); // Contains non-empty functions and/or non-empty globals String ToString(BfIRValue irValue); @@ -1171,13 +1179,13 @@ public: String ToString(BfIRMDNode irMDNode); String ActiveFuncToString(); void PrintActiveFunc(); - void pv(const BfIRValue& irValue); + void pv(const BfIRValue& irValue); void pt(const BfIRType& irType); void pbft(BfType* type); void pt(const BfIRFunction& irFun); - void pft(const BfIRFunctionType& irType); + void pft(const BfIRFunctionType& irType); void pmd(const BfIRMDNode& irMDNode); - + void GetBufferData(Array& outBuffer); void ClearConstData(); void ClearNonConstData(); @@ -1186,11 +1194,11 @@ public: void SetBackend(bool isBeefBackend); void RemoveIRCodeGen(); void WriteIR(const StringImpl& fileName); - + void Module_SetTargetTriple(const StringImpl& targetTriple, const StringImpl& targetCPU); void Module_AddModuleFlag(const StringImpl& flag, int val); - BfIRType GetPrimitiveType(BfTypeCode typeCode); + BfIRType GetPrimitiveType(BfTypeCode typeCode); BfIRType CreateStructType(const StringImpl& name); BfIRType CreateStructType(const BfSizedArray& memberTypes); void StructSetBody(BfIRType type, const BfSizedArray& memberTypes, int size, int align, bool isPacked); @@ -1202,7 +1210,7 @@ public: BfIRType GetPointerTo(BfIRType type); BfIRType GetSizedArrayType(BfIRType elementType, int length); BfIRType GetVectorType(BfIRType elementType, int length); - + BfIRValue CreateConstAgg_Value(BfIRType type, const BfSizedArray& values); BfIRValue CreateConstString(const StringImpl& string); BfIRValue ConstToMemory(BfIRValue constVal); @@ -1244,17 +1252,18 @@ public: BfIRValue CreateExtractValue(BfIRValue val, int idx); BfIRValue CreateExtractValue(BfIRValue val, BfIRValue idx); BfIRValue CreateInsertValue(BfIRValue agg, BfIRValue val, int idx); - + BfIRValue CreateAlloca(BfIRType type); BfIRValue CreateAlloca(BfIRType type, BfIRValue arraySize); void SetAllocaAlignment(BfIRValue val, int alignment); // When we do a dynamic alloca where we know the memory access patterns will not cause a page fault, we can omit the __chkstk call // Generally, this is when we allocate less than 4k and we know there will be a write on this memory before the next alloca - void SetAllocaNoChkStkHint(BfIRValue val); + void SetAllocaNoChkStkHint(BfIRValue val); void SetAllocaForceMem(BfIRValue val); BfIRValue CreateAliasValue(BfIRValue val); - BfIRValue CreateLifetimeStart(BfIRValue val); + BfIRValue CreateLifetimeStart(BfIRValue val); BfIRValue CreateLifetimeEnd(BfIRValue val); + BfIRValue CreateLifetimeSoftEnd(BfIRValue val); BfIRValue CreateLifetimeExtend(BfIRValue val); BfIRValue CreateValueScopeStart(); void CreateValueScopeRetain(BfIRValue val); // When a value is held by a variable -- don't release until we have a HardValueScopeEnd @@ -1268,8 +1277,8 @@ public: void CreateFence(BfIRFenceType fenceType); BfIRValue CreateStackSave(); 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_SetInitializer(BfIRValue globalVar, BfIRValue initVal); @@ -1280,32 +1289,32 @@ public: BfIRBlock CreateBlock(const StringImpl& name, bool addNow = false); BfIRBlock MaybeChainNewBlock(const StringImpl& name); // Creates new block if current block isn't empty - void AddBlock(BfIRBlock block); + void AddBlock(BfIRBlock block); void DropBlocks(BfIRBlock block); - void MergeBlockDown(BfIRBlock fromBlock, BfIRBlock intoBlock); + void MergeBlockDown(BfIRBlock fromBlock, BfIRBlock intoBlock); void SetInsertPoint(BfIRValue value); void SetInsertPoint(BfIRBlock block); void SetInsertPointAtStart(BfIRBlock block); - void EraseFromParent(BfIRBlock block); + void EraseFromParent(BfIRBlock block); void DeleteBlock(BfIRBlock block); void EraseInstFromParent(BfIRValue val); BfIRValue CreateBr(BfIRBlock block); BfIRValue CreateBr_Fake(BfIRBlock block); BfIRValue CreateBr_NoCollapse(BfIRBlock block); void CreateCondBr(BfIRValue val, BfIRBlock trueBlock, BfIRBlock falseBlock); - BfIRBlock GetInsertBlock(); - void MoveBlockToEnd(BfIRBlock block); + BfIRBlock GetInsertBlock(); + void MoveBlockToEnd(BfIRBlock block); BfIRValue CreateSwitch(BfIRValue value, BfIRBlock dest, int numCases); BfIRValue AddSwitchCase(BfIRValue switchVal, BfIRValue caseVal, BfIRBlock caseBlock); void SetSwitchDefaultDest(BfIRValue switchVal, BfIRBlock caseBlock); BfIRValue CreatePhi(BfIRType type, int incomingCount); void AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comingFrom); - - BfIRFunction GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray& paramTypes); + + BfIRFunction GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray& paramTypes); BfIRFunctionType MapMethod(BfMethodInstance* methodInstance); BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray& paramTypes, bool isVarArg = false); - BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name); + BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name); void SetFunctionName(BfIRValue func, const StringImpl& name); void EnsureFunctionPatchable(); BfIRValue RemapBindFunction(BfIRValue func); @@ -1319,17 +1328,18 @@ public: void SetCallAttribute(BfIRValue callInst, int paramIdx, BfIRAttribute attribute); BfIRValue CreateRet(BfIRValue val); BfIRValue CreateSetRet(BfIRValue val, int returnTypeId); - void CreateRetVoid(); + void CreateRetVoid(); void CreateUnreachable(); void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr); - void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg); + void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg); void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr); void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr, int arg); - void Func_SetParamName(BfIRFunction func, int argIdx, const StringImpl& name); + void Func_SetParamName(BfIRFunction func, int argIdx, const StringImpl& name); void Func_DeleteBody(BfIRFunction func); void Func_SafeRename(BfIRFunction func); + void Func_SafeRenameFrom(BfIRFunction func, const StringImpl& prevName); void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage); - + void Comptime_Error(int errorKind); BfIRValue Comptime_GetBfType(int typeId, BfIRType resultType); BfIRValue Comptime_GetReflectType(int typeId, BfIRType resultType); @@ -1341,7 +1351,7 @@ public: void RestoreDebugLocation(); void DupDebugLocation(); bool HasDebugLocation(); - void ClearDebugLocation(); + void ClearDebugLocation(); void ClearDebugLocation(BfIRValue inst); void ClearDebugLocation_Last(); void UpdateDebugLocation(BfIRValue inst); @@ -1350,29 +1360,29 @@ public: void CreateEnsureInstructionAt(); void CreateStatementStart(); void CreateObjectAccessCheck(BfIRValue value, bool useAsm); - + void DbgInit(); - void DbgFinalize(); + void DbgFinalize(); bool DbgHasInfo(); bool DbgHasLineInfo(); String DbgGetStaticFieldName(BfFieldInstance* fieldInstance); void DbgAddPrefix(String& name); - BfIRMDNode DbgCreateCompileUnit(int lang, const StringImpl& filename, const StringImpl& directory, const StringImpl& producer, bool isOptimized, - const StringImpl& flags, int runtimeVer, bool linesOnly); + BfIRMDNode DbgCreateCompileUnit(int lang, const StringImpl& filename, const StringImpl& directory, const StringImpl& producer, bool isOptimized, + const StringImpl& flags, int runtimeVer, bool linesOnly); BfIRMDNode DbgCreateFile(const StringImpl& fileName, const StringImpl& directory, const Val128& md5Hash); BfIRMDNode DbgGetCurrentLocation(); void DbgSetType(BfType * type, BfIRMDNode diType); - void DbgSetInstType(BfType * type, BfIRMDNode diType); + void DbgSetInstType(BfType * type, BfIRMDNode diType); BfIRMDNode DbgCreateConstValue(int64 val); - BfIRMDNode DbgGetType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration); + BfIRMDNode DbgGetType(BfType* type, BfIRPopulateType populateType = BfIRPopulateType_Declaration); BfIRMDNode DbgGetTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType = BfIRPopulateType_Declaration); void DbgTrackDITypes(BfType* type); BfIRMDNode DbgCreateNameSpace(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNum); BfIRMDNode DbgCreateImportedModule(BfIRMDNode context, BfIRMDNode namespaceNode, int line); BfIRMDNode DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding); - BfIRMDNode DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, + BfIRMDNode DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray& elements); - BfIRMDNode DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 SizeInBits, int64 alignInBits, + BfIRMDNode DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 SizeInBits, int64 alignInBits, const BfSizedArray& elements, BfIRMDNode underlyingType); BfIRMDNode DbgCreatePointerType(BfIRMDNode diType); BfIRMDNode DbgCreateReferenceType(BfIRMDNode diType); @@ -1387,14 +1397,14 @@ public: void DbgDeleteTemporary(BfIRMDNode diNode); BfIRMDNode DbgMakePermanent(BfIRMDNode diNode, BfIRMDNode diBaseType, const BfSizedArray& elements); BfIRMDNode DbgCreateEnumerator(const StringImpl& name, int64 val); - BfIRMDNode DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, + BfIRMDNode DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type); BfIRMDNode DbgCreateStaticMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, BfIRMDNode type, int flags, BfIRValue val); BfIRMDNode DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags); BfIRMDNode DbgCreateMethod(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, - bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags, bool isOptimized, BfIRValue fn, + bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags, bool isOptimized, BfIRValue fn, const BfSizedArray& genericArgs, const BfSizedArray& genericConstValueArgs); - BfIRMDNode DbgCreateFunction(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, + BfIRMDNode DbgCreateFunction(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int scopeLine, int flags, bool isOptimized, BfIRValue fn); BfIRMDNode DbgCreateParameterVariable(BfIRMDNode scope, const StringImpl& name, int argNo, BfIRMDNode file, int lineNum, BfIRMDNode type, bool AlwaysPreserve = false, int flags = 0); @@ -1404,14 +1414,13 @@ public: BfIRValue DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo); BfIRValue DbgInsertDeclare(BfIRValue val, BfIRMDNode varInfo, BfIRValue declareBefore = BfIRValue()); BfIRValue DbgLifetimeEnd(BfIRMDNode varInfo); - void DbgCreateGlobalVariable(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNumber, + void DbgCreateGlobalVariable(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNumber, BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode Decl = BfIRMDNode()); - BfIRMDNode DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col); - void DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value); + BfIRMDNode DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col); + void DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value); BfIRState GetState(); void SetState(const BfIRState& state); }; NS_BF_END - diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 273ab80f..9b08751e 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -141,9 +141,9 @@ static const BuiltinEntry gIntrinEntries[] = {"atomic_and"}, {"atomic_cmpstore"}, {"atomic_cmpstore_weak"}, - {"atomic_cmpxchg"}, + {"atomic_cmpxchg"}, {"atomic_fence"}, - {"atomic_load"}, + {"atomic_load"}, {"atomic_max"}, {"atomic_min"}, {"atomic_nand"}, @@ -153,10 +153,10 @@ static const BuiltinEntry gIntrinEntries[] = {"atomic_umax"}, {"atomic_umin"}, {"atomic_xchg"}, - {"atomic_xor"}, + {"atomic_xor"}, {"bswap"}, {"cast"}, - {"cos"}, + {"cos"}, {"debugtrap"}, {"div"}, {"eq"}, @@ -192,7 +192,7 @@ static const BuiltinEntry gIntrinEntries[] = {"sub"}, {"va_arg"}, {"va_end"}, - {"va_start"}, + {"va_start"}, {"xor"}, }; @@ -264,19 +264,19 @@ struct BfTempFile String mContents; String mFilePath; CritSect mCritSect; - FILE* mFP; + FILE* mFP; BfTempFile() { - mFP = NULL; + mFP = NULL; } ~BfTempFile() { if (mFP != NULL) - fclose(mFP); - if (!mFilePath.IsEmpty()) - ::DeleteFileW(UTF8Decode(mFilePath).c_str()); + fclose(mFP); + if (!mFilePath.IsEmpty()) + ::DeleteFileW(UTF8Decode(mFilePath).c_str()); } bool Create() @@ -311,7 +311,7 @@ struct BfTempFile char* str = new char[size]; int readSize = (int)fread(str, 1, size, mFP); mContents.Append(str, readSize); - delete [] str; + delete [] str; fclose(mFP); mFP = NULL; @@ -324,10 +324,10 @@ struct BfTempFile static BfTempFile gTempFile; static void AddStdErrCrashInfo() -{ - String tempContents = gTempFile.GetContents(); - if (!tempContents.IsEmpty()) - BfpSystem_AddCrashInfo(tempContents.c_str()); +{ + String tempContents = gTempFile.GetContents(); + if (!tempContents.IsEmpty()) + BfpSystem_AddCrashInfo(tempContents.c_str()); } #endif @@ -356,13 +356,13 @@ BfIRCodeGen::BfIRCodeGen() mHadDLLExport = false; mConstValIdx = 0; mCmdCount = 0; - + #ifdef BF_PLATFORM_WINDOWS if (::GetStdHandle(STD_ERROR_HANDLE) == 0) { if (gTempFile.Create()) - { - _dup2(fileno(gTempFile.mFP), 2); + { + _dup2(fileno(gTempFile.mFP), 2); BfpSystem_AddCrashInfoFunc(AddStdErrCrashInfo); } } @@ -384,11 +384,11 @@ BfIRCodeGen::~BfIRCodeGen() void BfIRCodeGen::FatalError(const StringImpl &err) { - String failStr = "Fatal Error in Module: "; + String failStr = "Fatal Error in Module: "; failStr += mModuleName; failStr += "\n"; if (mLLVMModule != NULL) - { + { if (mActiveFunction != NULL) { failStr += "Function: "; @@ -396,7 +396,7 @@ void BfIRCodeGen::FatalError(const StringImpl &err) failStr += "\n"; } - auto loc = mIRBuilder->getCurrentDebugLocation(); + auto loc = mIRBuilder->getCurrentDebugLocation(); auto dbgLoc = loc.getAsMDNode(); if (dbgLoc != NULL) { @@ -417,7 +417,7 @@ void BfIRCodeGen::FatalError(const StringImpl &err) failStr += str; failStr += "\n"; } - } + } } failStr += err; @@ -477,7 +477,7 @@ void BfIRCodeGen::FixValues(llvm::StructType* structType, llvm::SmallVectorgetElementType(i)->isArrayTy()) - { + { values[i] = llvm::ConstantAggregateZero::get(structType->getElementType(i)); } else @@ -502,7 +502,7 @@ BfTypeCode BfIRCodeGen::GetTypeCode(llvm::Type* type, bool isSigned) case 1: return BfTypeCode_Boolean; case 8: - return isSigned ? BfTypeCode_Int8 : BfTypeCode_UInt8; + return isSigned ? BfTypeCode_Int8 : BfTypeCode_UInt8; case 16: return isSigned ? BfTypeCode_Int16 : BfTypeCode_UInt16; case 32: @@ -604,7 +604,7 @@ llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned) return llvm::Type::getInt64Ty(*mLLVMContext);*/ case BfTypeCode_Float: return llvm::Type::getFloatTy(*mLLVMContext); - case BfTypeCode_Double: + case BfTypeCode_Double: return llvm::Type::getDoubleTy(*mLLVMContext); case BfTypeCode_Float2: return llvm::FixedVectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2); @@ -664,9 +664,9 @@ void BfIRCodeGen::SetResultAligned(int id, llvm::Value* value) } void BfIRCodeGen::SetResult(int id, llvm::Type* type) -{ +{ BfIRCodeGenEntry entry; - entry.mKind = BfIRCodeGenEntryKind_LLVMType; + entry.mKind = BfIRCodeGenEntryKind_LLVMType; entry.mLLVMType = type; mResults.TryAdd(id, entry); } @@ -692,19 +692,19 @@ void BfIRCodeGen::ProcessBfIRData(const BfSizedArray& buffer) // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting // with LLVM 13 this function is gone. /*struct InlineAsmErrorHook - { + { static void StaticHandler(const llvm::SMDiagnostic& diag, void *context, unsigned locCookie) { if (diag.getKind() == llvm::SourceMgr::DK_Error) { BfIRCodeGen* irCodeGen = (BfIRCodeGen*)context; - + if (!irCodeGen->mErrorMsg.empty()) irCodeGen->mErrorMsg += "\n"; irCodeGen->mErrorMsg += StrFormat("Inline assembly error: \"%s\" : %s", diag.getMessage().data(), diag.getLineContents().data()); } - } - }; + } + }; mLLVMContext->setInlineAsmDiagnosticHandler(InlineAsmErrorHook::StaticHandler, this);*/ BF_ASSERT(mStream == NULL); @@ -712,7 +712,7 @@ void BfIRCodeGen::ProcessBfIRData(const BfSizedArray& buffer) mStream->InitFlatRef(buffer.mVals, buffer.mSize); while (mStream->GetReadPos() < buffer.mSize) - { + { if (mFailed) break; HandleNextCmd(); @@ -731,7 +731,6 @@ int64 BfIRCodeGen::ReadSLEB128() byteVal = mStream->Read(); val |= ((int64)(byteVal & 0x7f)) << shift; shift += 7; - } while (byteVal >= 128); // Sign extend negative numbers. if ((byteVal & 0x40) && (shift < 64)) @@ -740,8 +739,8 @@ int64 BfIRCodeGen::ReadSLEB128() } void BfIRCodeGen::Read(StringImpl& str) -{ - int len = (int)ReadSLEB128(); +{ + int len = (int)ReadSLEB128(); str.Append('?', len); mStream->Read((void*)str.c_str(), len); } @@ -853,7 +852,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, CMD_PARAM(int, streamId); if (streamId == -1) { - int streamId = mCmdCount++; + int streamId = mCmdCount++; CMD_PARAM(llvm::Type*, varType); CMD_PARAM(bool, isConstant); @@ -935,8 +934,8 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, else if (constType == BfConstType_GEP32_1) { CMD_PARAM(llvm::Constant*, target); - CMD_PARAM(int, idx0); - llvm::Value* gepArgs[] = { + CMD_PARAM(int, idx0); + llvm::Value* gepArgs[] = { llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0)}; llvmValue = FixGEP(target, llvm::ConstantExpr::getInBoundsGetElementPtr(target->getType()->getPointerElementType(), target, gepArgs)); @@ -947,7 +946,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, CMD_PARAM(llvm::Constant*, target); CMD_PARAM(int, idx0); CMD_PARAM(int, idx1); - llvm::Value* gepArgs[] = { + llvm::Value* gepArgs[] = { llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0), llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx1)}; @@ -957,7 +956,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, else if (constType == BfConstType_ExtractValue) { CMD_PARAM(llvm::Constant*, target); - CMD_PARAM(int, idx0); + CMD_PARAM(int, idx0); unsigned int gepArgs[] = { (unsigned int)idx0 }; llvmValue = FixGEP(target, llvm::ConstantExpr::getExtractValue(target, gepArgs)); @@ -985,7 +984,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, BfIRTypeEntry* typeEntry = NULL; llvm::Type* type = NULL; Read(type, &typeEntry); - if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL)) + if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL)) llvmValue = llvm::ConstantAggregateZero::get(GetSizeAlignedType(typeEntry)); else llvmValue = llvm::ConstantAggregateZero::get(type); @@ -1002,7 +1001,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, { BfIRTypeEntry* typeEntry = NULL; llvm::Type* type = NULL; - Read(type, &typeEntry); + Read(type, &typeEntry); CmdParamVec values; Read(values, type->isArrayTy() ? BfIRSizeAlignKind_Aligned : BfIRSizeAlignKind_Original); @@ -1023,7 +1022,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, { if (values[i]->getType() != structType->getElementType(i)) { - auto valArrayType = llvm::dyn_cast(values[i]->getType()); + auto valArrayType = llvm::dyn_cast(values[i]->getType()); if (valArrayType != NULL) { if (valArrayType->getNumElements() == 0) @@ -1053,7 +1052,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, llvmValue = NULL; Fail("Bad type"); } - + return; } else if (constType == BfConstType_Undef) @@ -1100,7 +1099,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, } else if (typeCode == BfTypeCode_None) { - llvmValue = NULL; + llvmValue = NULL; } else if (typeCode == BfTypeCode_NullPtr) { @@ -1111,7 +1110,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, llvmValue = llvm::ConstantPointerNull::get((llvm::PointerType*)llvmConstType); } else if (BfIRBuilder::IsInt(typeCode)) - { + { int64 intVal = ReadSLEB128(); auto constVal = llvm::ConstantInt::get(llvmConstType, intVal); auto constInt = (llvm::ConstantInt*)constVal; @@ -1141,16 +1140,16 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, int cmdId = -1; if (paramType == BfIRParamType_StreamId_Abs8) { - cmdId = mStream->Read(); + cmdId = mStream->Read(); } else if (paramType == BfIRParamType_StreamId_Rel) { - cmdId = mCmdCount - (int)ReadSLEB128(); - } + cmdId = mCmdCount - (int)ReadSLEB128(); + } else { - cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1; - } + cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1; + } auto& result = mResults[cmdId]; if (result.mKind != BfIRCodeGenEntryKind_LLVMValue) @@ -1208,7 +1207,7 @@ void BfIRCodeGen::Read(llvm::Function*& llvmFunc) return; } auto& result = mResults[streamId]; - BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue); + BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue); BF_ASSERT(llvm::isa(result.mLLVMValue)); llvmFunc = (llvm::Function*)result.mLLVMValue; } @@ -1309,7 +1308,7 @@ llvm::Value* BfIRCodeGen::TryToVector(llvm::Value* value, llvm::Type* elemType) { auto ptrElemType = ptrType->getElementType(); if (auto arrType = llvm::dyn_cast(ptrElemType)) - { + { auto vecType = llvm::FixedVectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements()); auto vecPtrType = vecType->getPointerTo(); @@ -1347,7 +1346,7 @@ llvm::Type* BfIRCodeGen::GetElemType(llvm::Value* value) auto ptrElemType = ptrType->getElementType(); if (auto arrType = llvm::dyn_cast(ptrElemType)) return arrType->getArrayElementType(); - + if (auto vecType = llvm::dyn_cast(ptrElemType)) return vecType->getElementType(); } @@ -1355,7 +1354,6 @@ llvm::Type* BfIRCodeGen::GetElemType(llvm::Value* value) return NULL; } - bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val) { auto valType = val->getType(); @@ -1370,17 +1368,17 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val) auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext); auto int32Ty = llvm::Type::getInt32Ty(*mLLVMContext); - auto int8PtrTy = int8Ty->getPointerTo(); + auto int8PtrTy = int8Ty->getPointerTo(); if (auto loadInst = llvm::dyn_cast(val)) - { + { mIRBuilder->CreateMemCpy( mIRBuilder->CreateBitCast(ptr, int8PtrTy), llvm::MaybeAlign(1), mIRBuilder->CreateBitCast(loadInst->getPointerOperand(), int8PtrTy), llvm::MaybeAlign(1), llvm::ConstantInt::get(int32Ty, arrayBytes)); - return true; + return true; } auto constVal = llvm::dyn_cast(val); @@ -1392,7 +1390,7 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val) mIRBuilder->CreateMemSet( mIRBuilder->CreateBitCast(ptr, int8PtrTy), llvm::ConstantInt::get(int8Ty, 0), - llvm::ConstantInt::get(int32Ty, arrayBytes), + llvm::ConstantInt::get(int32Ty, arrayBytes), llvm::MaybeAlign(1)); return true; } @@ -1403,10 +1401,10 @@ bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val) true, llvm::GlobalValue::InternalLinkage, constVal, - StrFormat("__ConstVal__%d", mConstValIdx++).c_str(), - NULL, + StrFormat("__ConstVal__%d", mConstValIdx++).c_str(), + NULL, llvm::GlobalValue::NotThreadLocal); - + mIRBuilder->CreateMemCpy( mIRBuilder->CreateBitCast(ptr, int8PtrTy), llvm::MaybeAlign(1), @@ -1434,16 +1432,16 @@ bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val) // auto vecType = llvm::dyn_cast(valType); // if (vecType == NULL) // return false; -// +// // for (int i = 0; i < (int)vecType->getVectorNumElements(); i++) -// { +// { // auto extract = mIRBuilder->CreateExtractElement(val, i); -// +// // llvm::Value* gepArgs[] = { // llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0), // llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), i) }; // auto gep = mIRBuilder->CreateInBoundsGEP(ptr, llvm::makeArrayRef(gepArgs)); -// +// // mIRBuilder->CreateStore(extract, gep); // } @@ -1451,7 +1449,7 @@ bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val) } llvm::Type* BfIRCodeGen::GetSizeAlignedType(BfIRTypeEntry* typeEntry) -{ +{ if ((typeEntry->mAlignLLVMType == NULL) && ((typeEntry->mSize & (typeEntry->mAlign - 1)) != 0)) { auto structType = llvm::dyn_cast(typeEntry->mLLVMType); @@ -1492,7 +1490,7 @@ llvm::Value* BfIRCodeGen::GetAlignedPtr(llvm::Value* val) auto alignedType = GetSizeAlignedType(typeEntry); if (alignedType != elemType) { - return mIRBuilder->CreateBitCast(val, alignedType->getPointerTo()); + return mIRBuilder->CreateBitCast(val, alignedType->getPointerTo()); } } } @@ -1517,7 +1515,7 @@ llvm::Value* BfIRCodeGen::FixGEP(llvm::Value* fromValue, llvm::Value* result) } llvm::Value* BfIRCodeGen::DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm) -{ +{ if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64)) useAsm = false; @@ -1687,7 +1685,7 @@ void BfIRCodeGen::InitTarget() { llvm::SMDiagnostic Err; llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple()); - llvm::CodeGenOpt::Level optLvl = llvm::CodeGenOpt::None; + llvm::CodeGenOpt::Level optLvl = llvm::CodeGenOpt::None; String cpuName = mTargetCPU; String arch = ""; @@ -1729,7 +1727,7 @@ void BfIRCodeGen::InitTarget() else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX) featuresStr = "+avx"; else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX2) - featuresStr = "+avx2"; + featuresStr = "+avx2"; llvm::Optional relocModel; llvm::CodeModel::Model cmModel = llvm::CodeModel::Small; @@ -1776,11 +1774,10 @@ void BfIRCodeGen::InitTarget() Options, relocModel, cmModel, optLvl); mLLVMModule->setDataLayout(mLLVMTargetMachine->createDataLayout()); - } void BfIRCodeGen::HandleNextCmd() -{ +{ int curId = mCmdCount; BfIRCmd cmd = (BfIRCmd)mStream->Read(); @@ -1788,8 +1785,8 @@ void BfIRCodeGen::HandleNextCmd() switch (cmd) { - case BfIRCmd_Module_Start: - { + case BfIRCmd_Module_Start: + { CMD_PARAM(String, moduleName); CMD_PARAM(int, ptrSize); CMD_PARAM(bool, isOptimized); @@ -1845,7 +1842,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_SetType: { CMD_PARAM(int, typeId); - CMD_PARAM(llvm::Type*, type); + CMD_PARAM(llvm::Type*, type); auto& typeEntry = GetTypeEntry(typeId); typeEntry.mLLVMType = type; if (typeEntry.mInstLLVMType == NULL) @@ -1859,7 +1856,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Type*, type); GetTypeEntry(typeId).mInstLLVMType = type; } - break; + break; case BfIRCmd_PrimitiveType: { BfTypeCode typeCode = (BfTypeCode)mStream->Read(); @@ -1870,7 +1867,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_CreateAnonymousStruct: { CMD_PARAM(CmdParamVec, members); - llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members); + llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members); SetResult(curId, structType); } break; @@ -1879,8 +1876,8 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(String, typeName); SetResult(curId, llvm::StructType::create(*mLLVMContext, typeName.c_str())); } - break; - case BfIRCmd_StructSetBody: + break; + case BfIRCmd_StructSetBody: { llvm::Type* type = NULL; BfIRTypeEntry* typeEntry = NULL; @@ -1890,7 +1887,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(int, instSize); CMD_PARAM(int, instAlign); CMD_PARAM(bool, isPacked); - + BF_ASSERT(llvm::isa(type)); auto structType = (llvm::StructType*)type; if (structType->isOpaque()) @@ -1920,14 +1917,14 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(BfIRTypeEntry*, typeEntry); SetResult(curId, typeEntry->mInstLLVMType->getPointerTo()); } - break; + break; case BfIRCmd_GetType: { CMD_PARAM(llvm::Value*, value); auto type = value->getType(); SetResult(curId, type); } - break; + break; case BfIRCmd_GetPointerToFuncType: { CMD_PARAM(llvm::FunctionType*, funcType); @@ -1952,19 +1949,19 @@ void BfIRCodeGen::HandleNextCmd() else SetResult(curId, llvm::ArrayType::get(elementType, length)); } - break; + break; case BfIRCmd_GetVectorType: { CMD_PARAM(llvm::Type*, elementType); CMD_PARAM(int, length); SetResult(curId, llvm::FixedVectorType::get(elementType, length)); } - break; + break; case BfIRCmd_CreateConstAgg: { CMD_PARAM(llvm::Type*, type); CMD_PARAM(CmdParamVec, values) - llvm::SmallVector copyValues; + llvm::SmallVector copyValues; if (auto arrayType = llvm::dyn_cast(type)) { @@ -2004,7 +2001,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Type*, type); SetResult(curId, llvm::ConstantAggregateZero::get(type)); } - break; + break; case BfIRCmd_CreateConstString: { CMD_PARAM(String, str); @@ -2037,18 +2034,18 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_NumericCast: - { + { CMD_PARAM(llvm::Value*, val); CMD_PARAM(bool, valIsSigned); BfTypeCode typeCode = (BfTypeCode)mStream->Read(); - BfTypeCode valTypeCode = GetTypeCode(val->getType(), valIsSigned); + BfTypeCode valTypeCode = GetTypeCode(val->getType(), valIsSigned); bool toSigned; - auto toLLVMType = GetLLVMType(typeCode, toSigned); + auto toLLVMType = GetLLVMType(typeCode, toSigned); llvm::Value* retVal = NULL; if (BfIRBuilder::IsInt(typeCode)) - { + { // Int -> Int if ((BfIRBuilder::IsInt(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean)) { @@ -2066,7 +2063,7 @@ void BfIRCodeGen::HandleNextCmd() { // Int -> Float if ((BfIRBuilder::IsInt(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean)) - { + { if (BfIRBuilder::IsSigned(valTypeCode)) retVal = mIRBuilder->CreateSIToFP(val, toLLVMType); else @@ -2113,7 +2110,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_CmpULT: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); if (lhs->getType()->isFloatingPointTy()) SetResult(curId, mIRBuilder->CreateFCmpOLT(lhs, rhs)); else @@ -2133,7 +2130,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_CmpULE: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); if (lhs->getType()->isFloatingPointTy()) SetResult(curId, mIRBuilder->CreateFCmpOLE(lhs, rhs)); else @@ -2153,7 +2150,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_CmpUGT: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); if (lhs->getType()->isFloatingPointTy()) SetResult(curId, mIRBuilder->CreateFCmpOGT(lhs, rhs)); else @@ -2173,14 +2170,14 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_CmpUGE: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); if (lhs->getType()->isFloatingPointTy()) SetResult(curId, mIRBuilder->CreateFCmpOGE(lhs, rhs)); else SetResult(curId, mIRBuilder->CreateICmpUGE(lhs, rhs)); } break; - + case BfIRCmd_Add: { CMD_PARAM(llvm::Value*, lhs); @@ -2192,7 +2189,7 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::sadd_with_overflow : llvm::Intrinsic::uadd_with_overflow, lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0)); else - SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs)); + SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs)); } break; case BfIRCmd_Sub: @@ -2236,7 +2233,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_UDiv: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateUDiv(lhs, rhs)); } break; @@ -2253,49 +2250,49 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_URem: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateURem(lhs, rhs)); } break; case BfIRCmd_And: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateAnd(lhs, rhs)); } break; case BfIRCmd_Or: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateOr(lhs, rhs)); } break; case BfIRCmd_Xor: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateXor(lhs, rhs)); } break; case BfIRCmd_Shl: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateShl(lhs, rhs)); } break; case BfIRCmd_AShr: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateAShr(lhs, rhs)); } break; case BfIRCmd_LShr: { CMD_PARAM(llvm::Value*, lhs); - CMD_PARAM(llvm::Value*, rhs); + CMD_PARAM(llvm::Value*, rhs); SetResult(curId, mIRBuilder->CreateLShr(lhs, rhs)); } break; @@ -2303,14 +2300,14 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Value*, val); if (val->getType()->isFloatingPointTy()) - SetResult(curId, mIRBuilder->CreateFNeg(val)); + SetResult(curId, mIRBuilder->CreateFNeg(val)); else SetResult(curId, mIRBuilder->CreateNeg(val)); } break; case BfIRCmd_Not: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM(llvm::Value*, val); SetResult(curId, mIRBuilder->CreateNot(val)); } break; @@ -2395,7 +2392,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Value*, idx1); FixIndexer(idx0); FixIndexer(idx1); - llvm::Value* indices[2] = { idx0, idx1 }; + llvm::Value* indices[2] = { idx0, idx1 }; SetResult(curId, FixGEP(val, mIRBuilder->CreateInBoundsGEP(val, llvm::makeArrayRef(indices)))); } break; @@ -2438,10 +2435,10 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Type*, type); if (type->isStructTy()) - { + { BF_ASSERT(!((llvm::StructType*)type)->isOpaque()); } - + SetResult(curId, mIRBuilder->CreateAlloca(type)); } break; @@ -2463,7 +2460,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetAllocaAlignment: { - CMD_PARAM_NOTRANS(llvm::Value*, val); + CMD_PARAM_NOTRANS(llvm::Value*, val); CMD_PARAM(int, alignment); auto inst = llvm::dyn_cast(val); inst->setAlignment(llvm::Align(alignment)); @@ -2487,6 +2484,11 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, mIRBuilder->CreateLifetimeEnd(val)); } break; + case BfIRCmd_LifetimeSoftEnd: + { + CMD_PARAM_NOTRANS(llvm::Value*, val); + } + break; case BfIRCmd_LifetimeExtend: { CMD_PARAM_NOTRANS(llvm::Value*, val); @@ -2494,7 +2496,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_Load: { - CMD_PARAM(llvm::Value*, val); + CMD_PARAM(llvm::Value*, val); CMD_PARAM(bool, isVolatile); SetResult(curId, mIRBuilder->CreateLoad(val, isVolatile)); } @@ -2512,7 +2514,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Value*, val); CMD_PARAM(llvm::Value*, ptr); CMD_PARAM(bool, isVolatile); - + if ((!TryMemCpy(ptr, val)) && (!TryVectorCpy(ptr, val))) SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile)); @@ -2557,7 +2559,7 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Value*, stackVal); auto intrin = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::stackrestore); - auto callInst = mIRBuilder->CreateCall(intrin, llvm::SmallVector {stackVal }); + auto callInst = mIRBuilder->CreateCall(intrin, llvm::SmallVector {stackVal }); SetResult(curId, callInst); } break; @@ -2565,7 +2567,7 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Type*, varType); CMD_PARAM(bool, isConstant); - BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); + BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); CMD_PARAM(String, name); CMD_PARAM(bool, isTLS); CMD_PARAM(llvm::Constant*, initializer); @@ -2642,9 +2644,9 @@ void BfIRCodeGen::HandleNextCmd() if (!newBlock->empty()) { auto bb = llvm::BasicBlock::Create(*mLLVMContext, name.c_str()); - mIRBuilder->CreateBr(bb); + mIRBuilder->CreateBr(bb); mActiveFunction->getBasicBlockList().push_back(bb); - mIRBuilder->SetInsertPoint(bb); + mIRBuilder->SetInsertPoint(bb); newBlock = bb; } SetResult(curId, newBlock); @@ -2662,7 +2664,7 @@ void BfIRCodeGen::HandleNextCmd() auto& basicBlockList = mActiveFunction->getBasicBlockList(); int postExitBlockIdx = -1; - auto itr = basicBlockList.rbegin(); + auto itr = basicBlockList.rbegin(); int blockIdx = (int)basicBlockList.size() - 1; while (itr != basicBlockList.rend()) { @@ -2672,13 +2674,13 @@ void BfIRCodeGen::HandleNextCmd() { postExitBlockIdx = blockIdx; break; - } + } blockIdx--; } while ((int)basicBlockList.size() > postExitBlockIdx) { - auto& block = basicBlockList.back(); + auto& block = basicBlockList.back(); block.eraseFromParent(); } } @@ -2686,7 +2688,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_MergeBlockDown: { CMD_PARAM(llvm::BasicBlock*, fromBlock); - CMD_PARAM(llvm::BasicBlock*, intoBlock); + CMD_PARAM(llvm::BasicBlock*, intoBlock); llvm::BasicBlock::InstListType& fromInstList = fromBlock->getInstList(); llvm::BasicBlock::InstListType& intoInstList = intoBlock->getInstList(); intoInstList.splice(intoInstList.begin(), fromInstList, fromInstList.begin(), fromInstList.end()); @@ -2699,7 +2701,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_SetInsertPoint: - { + { CMD_PARAM(llvm::BasicBlock*, block); if (mLockedBlocks.Contains(block)) Fail("Attempt to modify locked block"); @@ -2711,7 +2713,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::BasicBlock*, block); mIRBuilder->SetInsertPoint(block, block->begin()); } - break; + break; case BfIRCmd_EraseFromParent: { CMD_PARAM(llvm::BasicBlock*, block); @@ -2723,7 +2725,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::BasicBlock*, block); delete block; } - break; + break; case BfIRCmd_EraseInstFromParent: { CMD_PARAM(llvm::Value*, instVal); @@ -2778,8 +2780,8 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetSwitchDefaultDest: { - CMD_PARAM(llvm::Value*, switchVal); - CMD_PARAM(llvm::BasicBlock*, caseBlock); + CMD_PARAM(llvm::Value*, switchVal); + CMD_PARAM(llvm::BasicBlock*, caseBlock); ((llvm::SwitchInst*)switchVal)->setDefaultDest(caseBlock); } break; @@ -2805,9 +2807,9 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(int, intrinId); CMD_PARAM(llvm::Type*, returnType); CMD_PARAM(CmdParamVec, paramTypes); - + llvm::Function* func = NULL; - + struct _Intrinsics { llvm::Intrinsic::ID mID; @@ -2828,7 +2830,7 @@ void BfIRCodeGen::HandleNextCmd() { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore_Weak, { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpXChg, { (llvm::Intrinsic::ID)-2, -1}, // AtomicFence, - { (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad, + { (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad, { (llvm::Intrinsic::ID)-2, -1}, // AtomicMax, { (llvm::Intrinsic::ID)-2, -1}, // AtomicMin, { (llvm::Intrinsic::ID)-2, -1}, // AtomicNAnd, @@ -2846,7 +2848,7 @@ void BfIRCodeGen::HandleNextCmd() { (llvm::Intrinsic::ID)-2, -1}, // div { (llvm::Intrinsic::ID)-2, -1}, // eq { llvm::Intrinsic::floor, 0, -1}, - { (llvm::Intrinsic::ID)-2, -1}, // free + { (llvm::Intrinsic::ID)-2, -1}, // free { (llvm::Intrinsic::ID)-2, -1}, // gt { (llvm::Intrinsic::ID)-2, -1}, // gte { (llvm::Intrinsic::ID)-2, -1}, // index @@ -2874,7 +2876,7 @@ void BfIRCodeGen::HandleNextCmd() { (llvm::Intrinsic::ID)-2, -1}, // shuffle { llvm::Intrinsic::sin, 0, -1}, { llvm::Intrinsic::sqrt, 0, -1}, - { (llvm::Intrinsic::ID)-2, -1}, // sub, + { (llvm::Intrinsic::ID)-2, -1}, // sub, { (llvm::Intrinsic::ID)-2, -1}, // va_arg, { llvm::Intrinsic::vaend, -1}, // va_end, { llvm::Intrinsic::vastart, -1}, // va_start, @@ -2896,21 +2898,21 @@ void BfIRCodeGen::HandleNextCmd() } } - bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2; + bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2; if (isFakeIntrinsic) { auto intrinsicData = mIntrinsicData.Alloc(); intrinsicData->mName = intrinName; intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId; intrinsicData->mReturnType = returnType; - + BfIRCodeGenEntry entry; entry.mKind = BfIRCodeGenEntryKind_IntrinsicData; entry.mIntrinsicData = intrinsicData; mResults.TryAdd(curId, entry); break; - } - + } + if (intrinId == BfIRIntrinsic__PLATFORM) { int colonPos = (int)intrinName.IndexOf(':'); @@ -2942,8 +2944,8 @@ void BfIRCodeGen::HandleNextCmd() BF_ASSERT(intrinsics[intrinId].mID != (llvm::Intrinsic::ID)-1); func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams); } - mIntrinsicReverseMap[func] = intrinId; - + mIntrinsicReverseMap[func] = intrinId; + SetResult(curId, func); } break; @@ -2956,7 +2958,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_CreateFunction: - { + { CMD_PARAM(llvm::FunctionType*, type); BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); CMD_PARAM(String, name); @@ -2964,7 +2966,7 @@ void BfIRCodeGen::HandleNextCmd() auto func = mLLVMModule->getFunction(name.c_str()); if ((func == NULL) || (func->getFunctionType() != type)) func = llvm::Function::Create(type, LLVMMapLinkageType(linkageType), name.c_str(), mLLVMModule); - + SetResult(curId, func); } break; @@ -2977,7 +2979,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_EnsureFunctionPatchable: - { + { int minPatchSize = 5; int guessInstBytes = 1; // ret @@ -2989,21 +2991,21 @@ void BfIRCodeGen::HandleNextCmd() { for (auto& inst : block) { - if (auto loadInst = llvm::dyn_cast(&inst)) + if (auto loadInst = llvm::dyn_cast(&inst)) guessInstBytes += 2; else if (auto storeInst = llvm::dyn_cast(&inst)) guessInstBytes += 2; else if (auto callInst = llvm::dyn_cast(&inst)) { auto calledValue = callInst->getCalledOperand(); - + if (calledValue == mNopInlineAsm) guessInstBytes += 1; else if (auto func = llvm::dyn_cast(calledValue)) { if (!func->isIntrinsic()) guessInstBytes += 4; - } + } else guessInstBytes += 4; } @@ -3047,12 +3049,12 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetActiveFunction: { - CMD_PARAM(llvm::Function*, func); + CMD_PARAM(llvm::Function*, func); mActiveFunction = func; } break; case BfIRCmd_CreateCall: - { + { llvm::Value* func = NULL; BfIRCodeGenEntry* codeGenEntry = NULL; Read(func, &codeGenEntry); @@ -3086,11 +3088,11 @@ void BfIRCodeGen::HandleNextCmd() case BfIRIntrinsic_Div: case BfIRIntrinsic_Eq: case BfIRIntrinsic_Gt: - case BfIRIntrinsic_GtE: + case BfIRIntrinsic_GtE: case BfIRIntrinsic_Lt: case BfIRIntrinsic_LtE: case BfIRIntrinsic_Mod: - case BfIRIntrinsic_Mul: + case BfIRIntrinsic_Mul: case BfIRIntrinsic_Neq: case BfIRIntrinsic_Or: case BfIRIntrinsic_Sub: @@ -3098,14 +3100,14 @@ void BfIRCodeGen::HandleNextCmd() { auto val0 = TryToVector(args[0]); if (val0 != NULL) - { + { auto vecType = llvm::dyn_cast(val0->getType()); auto elemType = vecType->getElementType(); bool isFP = elemType->isFloatTy(); - + llvm::Value* val1; if (args.size() < 2) - { + { llvm::Value* val; if (isFP) val = llvm::ConstantFP::get(elemType, 1); @@ -3120,11 +3122,11 @@ void BfIRCodeGen::HandleNextCmd() { auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecType->getPointerTo()); val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, llvm::MaybeAlign(1)); - } + } else if (args[1]->getType()->isVectorTy()) - { + { val1 = args[1]; - } + } else { val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[1], (uint64)0); @@ -3191,7 +3193,7 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, result); } - } + } else { llvm::Value* result = NULL; @@ -3268,21 +3270,21 @@ void BfIRCodeGen::HandleNextCmd() { auto vecType = llvm::FixedVectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements()); auto vecPtrType = vecType->getPointerTo(); - - llvm::Value* val0; + + llvm::Value* val0; val0 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[0], (uint64)0); val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)1); val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)2); - val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)3); + val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)3); auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecPtrType); auto val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, llvm::MaybeAlign(1)); switch (intrinsicData->mIntrinsic) - { + { case BfIRIntrinsic_Div: SetResult(curId, mIRBuilder->CreateFDiv(val0, val1)); - break; + break; case BfIRIntrinsic_Mod: SetResult(curId, mIRBuilder->CreateFRem(val0, val1)); break; @@ -3303,7 +3305,7 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, mIRBuilder->CreateNot(val0)); } break; - case BfIRIntrinsic_Shuffle: + case BfIRIntrinsic_Shuffle: { llvm::SmallVector intMask; for (int i = 7; i < (int)intrinsicData->mName.length(); i++) @@ -3312,7 +3314,7 @@ void BfIRCodeGen::HandleNextCmd() auto val0 = TryToVector(args[0]); if (val0 != NULL) - { + { SetResult(curId, mIRBuilder->CreateShuffleVector(val0, val0, intMask)); } else @@ -3322,7 +3324,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRIntrinsic_Index: - { + { llvm::Value* gepArgs[] = { llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0), args[1] }; @@ -3349,7 +3351,7 @@ void BfIRCodeGen::HandleNextCmd() auto successOrdering = llvm::AtomicOrdering::Unordered; auto failOrdering = llvm::AtomicOrdering::Unordered; switch (memoryKind & BfIRAtomicOrdering_ORDERMASK) - { + { case BfIRAtomicOrdering_Acquire: successOrdering = llvm::AtomicOrdering::Acquire; failOrdering = llvm::AtomicOrdering::Acquire; @@ -3385,14 +3387,14 @@ void BfIRCodeGen::HandleNextCmd() } auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue(); switch (memoryKind & BfIRAtomicOrdering_ORDERMASK) - { - case BfIRAtomicOrdering_Acquire: + { + case BfIRAtomicOrdering_Acquire: failOrdering = llvm::AtomicOrdering::Acquire; - break; - case BfIRAtomicOrdering_Relaxed: + break; + case BfIRAtomicOrdering_Relaxed: failOrdering = llvm::AtomicOrdering::Monotonic; - break; - case BfIRAtomicOrdering_SeqCst: + break; + case BfIRAtomicOrdering_SeqCst: failOrdering = llvm::AtomicOrdering::SequentiallyConsistent; break; default: @@ -3415,7 +3417,7 @@ void BfIRCodeGen::HandleNextCmd() { auto successVal = mIRBuilder->CreateExtractValue(inst, 1); SetResult(curId, successVal); - } + } } break; case BfIRIntrinsic_AtomicFence: @@ -3455,7 +3457,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRAtomicOrdering_AcqRel: ordering = llvm::AtomicOrdering::AcquireRelease; - break; + break; case BfIRAtomicOrdering_Release: ordering = llvm::AtomicOrdering::Release; break; @@ -3477,9 +3479,9 @@ void BfIRCodeGen::HandleNextCmd() { FatalError("Non-constant success ordering on AtomicLoad"); break; - } + } auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue(); - auto ptrType = llvm::dyn_cast(args[0]->getType()); + auto ptrType = llvm::dyn_cast(args[0]->getType()); auto loadInst = mIRBuilder->CreateAlignedLoad(args[0], llvm::MaybeAlign((uint)ptrType->getElementType()->getPrimitiveSizeInBits() / 8)); switch (memoryKind & BfIRAtomicOrdering_ORDERMASK) { @@ -3500,9 +3502,9 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, loadInst); } break; - case BfIRIntrinsic_AtomicStore: - { - auto memoryKindConst = llvm::dyn_cast(args[1]); + case BfIRIntrinsic_AtomicStore: + { + auto memoryKindConst = llvm::dyn_cast(args[2]); if (memoryKindConst == NULL) { FatalError("Non-constant success ordering on AtomicLoad"); @@ -3528,15 +3530,15 @@ void BfIRCodeGen::HandleNextCmd() SetResult(curId, storeInst); } break; - case BfIRIntrinsic_AtomicAdd: + case BfIRIntrinsic_AtomicAdd: case BfIRIntrinsic_AtomicAnd: case BfIRIntrinsic_AtomicMax: case BfIRIntrinsic_AtomicMin: case BfIRIntrinsic_AtomicNAnd: case BfIRIntrinsic_AtomicOr: - case BfIRIntrinsic_AtomicSub: - case BfIRIntrinsic_AtomicUMax: - case BfIRIntrinsic_AtomicUMin: + case BfIRIntrinsic_AtomicSub: + case BfIRIntrinsic_AtomicUMax: + case BfIRIntrinsic_AtomicUMin: case BfIRIntrinsic_AtomicXChg: case BfIRIntrinsic_AtomicXor: { @@ -3545,13 +3547,13 @@ void BfIRCodeGen::HandleNextCmd() auto op = llvm::AtomicRMWInst::BinOp::Add; switch (intrinsicData->mIntrinsic) { - case BfIRIntrinsic_AtomicAdd: + case BfIRIntrinsic_AtomicAdd: op = llvm::AtomicRMWInst::BinOp::Add; break; case BfIRIntrinsic_AtomicAnd: op = llvm::AtomicRMWInst::BinOp::And; break; - case BfIRIntrinsic_AtomicMax: + case BfIRIntrinsic_AtomicMax: op = llvm::AtomicRMWInst::BinOp::Max; break; case BfIRIntrinsic_AtomicMin: @@ -3579,7 +3581,7 @@ void BfIRCodeGen::HandleNextCmd() op = llvm::AtomicRMWInst::BinOp::Xor; break; default: break; - } + } auto memoryKindConst = llvm::dyn_cast(args[2]); if (memoryKindConst == NULL) @@ -3593,25 +3595,25 @@ void BfIRCodeGen::HandleNextCmd() switch (memoryKind & BfIRAtomicOrdering_ORDERMASK) { case BfIRAtomicOrdering_Acquire: - ordering = llvm::AtomicOrdering::Acquire; + ordering = llvm::AtomicOrdering::Acquire; break; case BfIRAtomicOrdering_AcqRel: - ordering = llvm::AtomicOrdering::AcquireRelease; + ordering = llvm::AtomicOrdering::AcquireRelease; break; case BfIRAtomicOrdering_Relaxed: - ordering = llvm::AtomicOrdering::Monotonic; + ordering = llvm::AtomicOrdering::Monotonic; break; case BfIRAtomicOrdering_Release: - ordering = llvm::AtomicOrdering::Release; + ordering = llvm::AtomicOrdering::Release; break; case BfIRAtomicOrdering_SeqCst: - ordering = llvm::AtomicOrdering::SequentiallyConsistent; + ordering = llvm::AtomicOrdering::SequentiallyConsistent; break; default: Fail("Invalid ordering on atomic operation"); break; } - + auto atomicRMW = mIRBuilder->CreateAtomicRMW(op, args[0], args[1], llvm::MaybeAlign(), ordering); if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0) atomicRMW->setVolatile(true); @@ -3659,7 +3661,7 @@ void BfIRCodeGen::HandleNextCmd() } result = mIRBuilder->CreateSelect(cmpVal, atomicRMW, args[1]); } - break; + break; case BfIRIntrinsic_AtomicNAnd: result = mIRBuilder->CreateAnd(atomicRMW, args[1]); result = mIRBuilder->CreateNot(result); @@ -3717,7 +3719,7 @@ void BfIRCodeGen::HandleNextCmd() auto resultPtr = mIRBuilder->CreateBitCast(args[1], argType->getPointerTo()); mIRBuilder->CreateStore(vaArgVal, resultPtr); } - break; + break; default: FatalError("Unhandled intrinsic"); } @@ -3739,22 +3741,22 @@ void BfIRCodeGen::HandleNextCmd() int align = 1; BF_ASSERT(args.size() == 5); - auto alignConst = llvm::dyn_cast(args[3]); + auto alignConst = llvm::dyn_cast(args[3]); if (alignConst != NULL) - align = (int)alignConst->getSExtValue(); + align = (int)alignConst->getSExtValue(); bool isVolatile = false; auto volatileConst = llvm::dyn_cast(args[4]); if ((volatileConst != NULL) && (volatileConst->getSExtValue() != 0)) isVolatile = true; - CreateMemSet(args[0], args[1], args[2], align, isVolatile); - break; + CreateMemSet(args[0], args[1], args[2], align, isVolatile); + break; } else if ((intrinId == BfIRIntrinsic_MemCpy) || (intrinId == BfIRIntrinsic_MemMove)) { int align = 1; BF_ASSERT(args.size() == 5); - auto alignConst = llvm::dyn_cast(args[3]); + auto alignConst = llvm::dyn_cast(args[3]); if (alignConst != NULL) align = (int)alignConst->getSExtValue(); bool isVolatile = false; @@ -3766,7 +3768,7 @@ void BfIRCodeGen::HandleNextCmd() else mIRBuilder->CreateMemMove(args[0], llvm::MaybeAlign(align), args[1], llvm::MaybeAlign(align), args[2], isVolatile); break; - } + } } } @@ -3798,7 +3800,7 @@ void BfIRCodeGen::HandleNextCmd() case BfIRCmd_SetFuncCallingConv: { CMD_PARAM(llvm::Function*, func); - BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read(); + BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read(); ((llvm::Function*)func)->setCallingConv(GetLLVMCallingConv(callingConv, mTargetTriple)); } break; @@ -3811,10 +3813,10 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_SetCallAttribute: { - CMD_PARAM(llvm::Value*, callInst); + CMD_PARAM(llvm::Value*, callInst); CMD_PARAM(int, paramIdx); BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); - BF_ASSERT(llvm::isa(callInst)); + BF_ASSERT(llvm::isa(callInst)); llvm::Attribute::AttrKind attr = llvm::Attribute::None; if (attribute == BfIRAttribute_NoReturn) attr = llvm::Attribute::NoReturn; @@ -3884,7 +3886,7 @@ void BfIRCodeGen::HandleNextCmd() { CMD_PARAM(llvm::Function*, func); CMD_PARAM(int, argIdx); - BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); + BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); if (attribute == BFIRAttribute_DllImport) { func->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); @@ -3909,9 +3911,9 @@ void BfIRCodeGen::HandleNextCmd() CmdParamVec structVals; structVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0x7FFFFF00)); structVals.push_back(func); - structVals.push_back(llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(*mLLVMContext))); + structVals.push_back(llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(*mLLVMContext))); auto constStruct = llvm::ConstantStruct::get(structType, structVals); - + CmdParamVec structArrVals; structArrVals.push_back(constStruct); @@ -3925,8 +3927,8 @@ void BfIRCodeGen::HandleNextCmd() llvm::GlobalValue::AppendingLinkage, constArr, (attribute == BFIRAttribute_Constructor) ? "llvm.global_ctors" : "llvm.global_dtors", - NULL, llvm::GlobalValue::NotThreadLocal); - } + NULL, llvm::GlobalValue::NotThreadLocal); + } else { auto attr = LLVMMapAttribute(attribute); @@ -3946,15 +3948,15 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::Function*, func); CMD_PARAM(int, argIdx); BfIRAttribute attribute = (BfIRAttribute)mStream->Read(); - CMD_PARAM(int, arg); + CMD_PARAM(int, arg); if (attribute == BfIRAttribute_Dereferencable) { - ((llvm::Function*)func)->addDereferenceableAttr(argIdx, arg); + ((llvm::Function*)func)->addDereferenceableAttr(argIdx, arg); } else if (attribute == BfIRAttribute_ByVal) { auto funcType = func->getFunctionType(); - llvm::Attribute byValAttr = llvm::Attribute::getWithByValType(*mLLVMContext, funcType->getFunctionParamType(argIdx - 1)->getPointerElementType()); + llvm::Attribute byValAttr = llvm::Attribute::getWithByValType(*mLLVMContext, funcType->getFunctionParamType(argIdx - 1)->getPointerElementType()); llvm::Attribute alignAttr = llvm::Attribute::getWithAlignment(*mLLVMContext, llvm::Align(arg)); func->addAttribute(argIdx, byValAttr); func->addAttribute(argIdx, alignAttr); @@ -3978,7 +3980,7 @@ void BfIRCodeGen::HandleNextCmd() ++argItr; argItr->setName(name.c_str()); } - break; + break; case BfIRCmd_Func_DeleteBody: { CMD_PARAM(llvm::Function*, func); @@ -3992,10 +3994,18 @@ void BfIRCodeGen::HandleNextCmd() func->setName(llvm::Twine((Beefy::String(func->getName().data()) + StrFormat("__RENAME%d", curId)).c_str())); } break; + case BfIRCmd_Func_SafeRenameFrom: + { + CMD_PARAM(llvm::Function*, func); + CMD_PARAM(String, prevName); + if (String(func->getName().data()) == prevName) + func->setName(llvm::Twine((Beefy::String(func->getName().data()) + StrFormat("__RENAME%d", curId)).c_str())); + } + break; case BfIRCmd_Func_SetLinkage: { CMD_PARAM(llvm::Function*, func); - BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); + BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read(); ((llvm::Function*)func)->setLinkage(LLVMMapLinkageType(linkageType)); } break; @@ -4057,7 +4067,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_Nop: - case BfIRCmd_EnsureInstructionAt: + case BfIRCmd_EnsureInstructionAt: AddNop(); break; case BfIRCmd_StatementStart: @@ -4080,7 +4090,7 @@ void BfIRCodeGen::HandleNextCmd() mLockedBlocks.Add(irBuilder->GetInsertBlock()); // This is generates slower code than the inline asm in debug mode, but can optimize well in release - auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext); + auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext); auto int8Ptr = irBuilder->CreateBitCast(val, int8Ty->getPointerTo()); auto int8Val = irBuilder->CreateLoad(int8Ptr); auto cmpResult = irBuilder->CreateICmpUGE(int8Val, llvm::ConstantInt::get(int8Ty, 0x80)); @@ -4091,9 +4101,9 @@ void BfIRCodeGen::HandleNextCmd() irBuilder->CreateCondBr(cmpResult, failBB, passBB); curLLVMFunc->getBasicBlockList().push_back(failBB); - irBuilder->SetInsertPoint(failBB); + irBuilder->SetInsertPoint(failBB); - auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap); + auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap); auto callInst = irBuilder->CreateCall(trapDecl); callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoReturn); irBuilder->CreateBr(passBB); @@ -4130,12 +4140,12 @@ void BfIRCodeGen::HandleNextCmd() callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind); SetResult(curId, mIRBuilder->GetInsertBlock()); - } + } } break; case BfIRCmd_DbgInit: { - mDIBuilder = new llvm::DIBuilder(*mLLVMModule); + mDIBuilder = new llvm::DIBuilder(*mLLVMModule); } break; case BfIRCmd_DbgFinalize: @@ -4175,7 +4185,7 @@ void BfIRCodeGen::HandleNextCmd() for (int i = 0; i < 16; i++) sprintf(&hashStr[i * 2], "%.2x", ((uint8*)&md5Hash)[i]); - SetResult(curId, mDIBuilder->createFile(fileName.c_str(), directory.c_str(), + SetResult(curId, mDIBuilder->createFile(fileName.c_str(), directory.c_str(), llvm::DIFile::ChecksumInfo(llvm::DIFile::CSK_MD5, hashStr))); } break; @@ -4186,7 +4196,7 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_DbgGetCurrentLocation: - { + { SetResult(curId, mIRBuilder->getCurrentDebugLocation()); } break; @@ -4276,7 +4286,7 @@ void BfIRCodeGen::HandleNextCmd() //OutputDebugStrF("BfIRCmd_DbgCreateStructType %p\n", mdStruct); } - break; + break; case BfIRCmd_DbgCreateEnumerationType: { CMD_PARAM(llvm::MDNode*, context); @@ -4284,7 +4294,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::MDNode*, file); CMD_PARAM(int, lineNum); CMD_PARAM(int64, sizeInBits); - CMD_PARAM(int64, alignInBits); + CMD_PARAM(int64, alignInBits); CMD_PARAM(CmdParamVec, members); CMD_PARAM(llvm::MDNode*, underlyingType); auto diMembersArray = mDIBuilder->getOrCreateArray(members); @@ -4303,7 +4313,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_DbgCreatePointerType: { - CMD_PARAM(llvm::MDNode*, diType); + CMD_PARAM(llvm::MDNode*, diType); SetResult(curId, mDIBuilder->createPointerType((llvm::DIType*)diType, mPtrSize*8, (uint32)mPtrSize * 8)); } break; @@ -4331,7 +4341,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(int64, alignInBits); CMD_PARAM(llvm::MDNode*, elementType); CMD_PARAM(int64, numElements); - + llvm::SmallVector diSizeVec; diSizeVec.push_back(mDIBuilder->getOrCreateSubrange(0, numElements)); auto diSizeArray = mDIBuilder->getOrCreateArray(diSizeVec); @@ -4365,7 +4375,7 @@ void BfIRCodeGen::HandleNextCmd() auto diType = mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line); SetResult(curId, diType); } - break; + break; case BfIRCmd_DbgCreateSizedForwardDecl: { CMD_PARAM(int, tag); @@ -4378,7 +4388,7 @@ void BfIRCodeGen::HandleNextCmd() BF_ASSERT(file != NULL); SetResult(curId, mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line, 0, sizeInBits, (uint32)alignInBits)); } - break; + break; case BeIRCmd_DbgSetTypeSize: { CMD_PARAM(llvm::MDNode*, mdType); @@ -4399,10 +4409,10 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_DbgReplaceAllUses: - { + { CMD_PARAM(llvm::MDNode*, diPrevNode); CMD_PARAM(llvm::MDNode*, diNewNode); - diPrevNode->replaceAllUsesWith(diNewNode); + diPrevNode->replaceAllUsesWith(diNewNode); } break; case BfIRCmd_DbgDeleteTemporary: @@ -4412,14 +4422,14 @@ void BfIRCodeGen::HandleNextCmd() } break; case BfIRCmd_DbgMakePermanent: - { + { CMD_PARAM(llvm::MDNode*, diNode); CMD_PARAM(llvm::MDNode*, diBaseType); CMD_PARAM(CmdParamVec, members); llvm::MDNode* newNode = diNode; if (auto diComposite = llvm::dyn_cast(diNode)) - { + { //diComposite->getBaseType() if (diBaseType != NULL) @@ -4478,7 +4488,11 @@ void BfIRCodeGen::HandleNextCmd() os << "\n"; os.flush();*/ - auto member = mDIBuilder->createMemberType((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNumber, sizeInBits, (uint32)alignInBits, offsetInBits, diFlags, (llvm::DIType*)type); + const char* namePtr = name.c_str(); + if (name.IsEmpty()) + namePtr = NULL; + + auto member = mDIBuilder->createMemberType((llvm::DIScope*)scope, namePtr, (llvm::DIFile*)file, lineNumber, sizeInBits, (uint32)alignInBits, offsetInBits, diFlags, (llvm::DIType*)type); SetResult(curId, member); //OutputDebugStrF("BfIRCmd_DbgCreateMemberType = %p\n", member); } @@ -4527,8 +4541,8 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(String, name); CMD_PARAM(String, linkageName); CMD_PARAM(llvm::MDNode*, file); - CMD_PARAM(int, lineNum); - CMD_PARAM(llvm::MDNode*, type); + CMD_PARAM(int, lineNum); + CMD_PARAM(llvm::MDNode*, type); CMD_PARAM(bool, isLocalToUnit); CMD_PARAM(bool, isDefinition); CMD_PARAM(int, vk); @@ -4540,7 +4554,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(CmdParamVec, genericArgs); CMD_PARAM(CmdParamVec, genericConstValueArgs); BF_ASSERT(file != NULL); - + llvm::DITemplateParameterArray templateParamArr = NULL; llvm::DINodeArray templateParamNodes; if (genericArgs.size() != 0) @@ -4555,14 +4569,14 @@ void BfIRCodeGen::HandleNextCmd() if (i < genericConstValueArgs.size()) constant = genericConstValueArgs[i]; - if (constant != NULL) - templateParams.push_back(mDIBuilder->createTemplateValueParameter(mDICompileUnit, name.c_str(), genericArg, false, constant)); + if (constant != NULL) + templateParams.push_back(mDIBuilder->createTemplateValueParameter(mDICompileUnit, name.c_str(), genericArg, false, constant)); else templateParams.push_back(mDIBuilder->createTemplateTypeParameter(mDICompileUnit, name.c_str(), genericArg, false)); } templateParamNodes = mDIBuilder->getOrCreateArray(templateParams); templateParamArr = templateParamNodes.get(); - } + } llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags; llvm::DISubprogram::DISPFlags dispFlags = llvm::DISubprogram::DISPFlags::SPFlagZero; @@ -4576,7 +4590,7 @@ void BfIRCodeGen::HandleNextCmd() dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagVirtual); auto diSubProgram = mDIBuilder->createMethod((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum, - (llvm::DISubroutineType*)type, vIndex, 0, (llvm::DIType*)vTableHolder, diFlags, dispFlags, templateParamArr); + (llvm::DISubroutineType*)type, vIndex, 0, (llvm::DIType*)vTableHolder, diFlags, dispFlags, templateParamArr); if (fn != NULL) ((llvm::Function*)fn)->setSubprogram(diSubProgram); @@ -4591,10 +4605,10 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(String, name); CMD_PARAM(String, linkageName); CMD_PARAM(llvm::MDNode*, file); - CMD_PARAM(int, lineNum); - CMD_PARAM(llvm::MDNode*, type); + CMD_PARAM(int, lineNum); + CMD_PARAM(llvm::MDNode*, type); CMD_PARAM(bool, isLocalToUnit); - CMD_PARAM(bool, isDefinition); + CMD_PARAM(bool, isDefinition); CMD_PARAM(int, scopeLine); CMD_PARAM(int, flags); CMD_PARAM(bool, isOptimized); @@ -4637,7 +4651,7 @@ void BfIRCodeGen::HandleNextCmd() break; case BfIRCmd_DbgCreateSubroutineType: { - CMD_PARAM(CmdParamVec, elements); + CMD_PARAM(CmdParamVec, elements); auto diArray = mDIBuilder->getOrCreateTypeArray(elements); SetResult(curId, mDIBuilder->createSubroutineType(diArray)); } @@ -4665,7 +4679,7 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::MDNode*, varInfo); auto diVariable = (llvm::DILocalVariable*)varInfo; - + if (val == NULL) { val = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0); @@ -4679,7 +4693,7 @@ void BfIRCodeGen::HandleNextCmd() { writeVal = constantInt->getSExtValue(); } - + auto nameRef = diVariable->getName(); if (writeVal < 0) @@ -4689,7 +4703,7 @@ void BfIRCodeGen::HandleNextCmd() } } - mDIBuilder->insertDbgValueIntrinsic(val, diVariable, mDIBuilder->createExpression(), + mDIBuilder->insertDbgValueIntrinsic(val, diVariable, mDIBuilder->createExpression(), mIRBuilder->getCurrentDebugLocation(), (llvm::BasicBlock*)mIRBuilder->GetInsertBlock()); } break; @@ -4711,13 +4725,13 @@ void BfIRCodeGen::HandleNextCmd() { SetResult(curId, mDIBuilder->insertDeclare(val, (llvm::DILocalVariable*)varInfo, mDIBuilder->createExpression(), mIRBuilder->getCurrentDebugLocation(), mIRBuilder->GetInsertBlock())); - } + } } - break; + break; case BfIRCmd_DbgLifetimeEnd: { CMD_PARAM(llvm::MDNode*, varInfo); - } + } break; case BfIRCmd_DbgCreateGlobalVariable: { @@ -4727,21 +4741,21 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(llvm::MDNode*, file); CMD_PARAM(int, lineNum); CMD_PARAM(llvm::MDNode*, type); - CMD_PARAM(bool, isLocalToUnit); + CMD_PARAM(bool, isLocalToUnit); CMD_PARAM(llvm::Constant*, val); CMD_PARAM(llvm::MDNode*, decl); //BF_ASSERT(file != NULL); - llvm::DIExpression* diExpr = NULL; + llvm::DIExpression* diExpr = NULL; auto gve = mDIBuilder->createGlobalVariableExpression((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum, (llvm::DIType*)type, isLocalToUnit, true, diExpr, decl); - + if (val != NULL) { if (auto globalVar = llvm::dyn_cast(val)) { globalVar->addDebugInfo(gve); } - } + } SetResult(curId, diExpr); } @@ -4755,7 +4769,7 @@ void BfIRCodeGen::HandleNextCmd() BF_ASSERT(file != NULL); SetResult(curId, mDIBuilder->createLexicalBlock((llvm::DIScope*)scope, (llvm::DIFile*)file, (unsigned)lineNum, (unsigned)col)); } - break; + break; case BfIRCmd_DbgCreateAnnotation: { CMD_PARAM(llvm::MDNode*, scope); @@ -4781,7 +4795,7 @@ void BfIRCodeGen::HandleNextCmd() { writeVal = constant->getSExtValue(); } - + if (writeVal < 0) dbgName += StrFormat("$_%llu", -writeVal); else @@ -4839,7 +4853,7 @@ llvm::BasicBlock * BfIRCodeGen::GetLLVMBlock(int id) llvm::MDNode* BfIRCodeGen::GetLLVMMetadata(int id) { - auto& result = mResults[id]; + auto& result = mResults[id]; BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata); return result.mLLVMMetadata; } @@ -4892,7 +4906,7 @@ static void AddInstructionCombiningPass(llvm::legacy::PassManagerBase &PM, const PM.add(llvm::createInstructionCombiningPass(options.mExpensiveCombines)); } -static void AddFunctionSimplificationPasses(llvm::legacy::PassManagerBase &MPM, const BfCodeGenOptions& options) +static void AddFunctionSimplificationPasses(llvm::legacy::PassManagerBase &MPM, const BfCodeGenOptions& options) { // Start of function pass. // Break up aggregate allocas, using SSAUpdater. @@ -4901,7 +4915,7 @@ static void AddFunctionSimplificationPasses(llvm::legacy::PassManagerBase &MPM, //if (EnableGVNHoist) if (options.mEnableGVNHoist) MPM.add(llvm::createGVNHoistPass()); - if (options.mEnableGVNSink) + if (options.mEnableGVNSink) { MPM.add(llvm::createGVNSinkPass()); MPM.add(llvm::createCFGSimplificationPass()); @@ -5041,7 +5055,7 @@ static void PopulateModulePassManager(llvm::legacy::PassManagerBase &MPM, const // else if (GlobalExtensionsNotEmpty() || !Extensions.empty()) // MPM.add(createBarrierNoopPass()); - if (performThinLTO) + if (performThinLTO) { // Drop available_externally and unreferenced globals. This is necessary // with ThinLTO in order to avoid leaving undefined references to dead @@ -5347,7 +5361,6 @@ static void PopulateModulePassManager(llvm::legacy::PassManagerBase &MPM, const } } - namespace { struct BfPass : public llvm::MachineFunctionPass @@ -5409,13 +5422,13 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) { // { // PassManagerBuilderWrapper pmBuilder; - // - // + // + // // } - + mHasDebugLoc = false; // So fails don't show a line number - bool enableLTO = mCodeGenOptions.mLTOType != BfLTOType_None; + bool enableLTO = mCodeGenOptions.mLTOType != BfLTOType_None; if (enableLTO) { @@ -5428,7 +5441,7 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) if (mHadDLLExport) // LTO bug in LLVM-link? enableLTO = false; } - + std::error_code EC; llvm::sys::fs::OpenFlags OpenFlags = llvm::sys::fs::OF_None; @@ -5440,18 +5453,18 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) llvm::legacy::PassManager PM; llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple()); - // Add an appropriate TargetLibraryInfo pass for the module's triple. + // Add an appropriate TargetLibraryInfo pass for the module's triple. llvm::TargetLibraryInfoImpl TLII(theTriple); PM.add(new llvm::TargetLibraryInfoWrapperPass(TLII)); - // Add the target data from the target machine, if it exists, or the module. + // Add the target data from the target machine, if it exists, or the module. //PM.add(new DataLayoutPass()); PopulateModulePassManager(PM, mCodeGenOptions); llvm::raw_fd_ostream* outStream = NULL; defer ( delete outStream; ); - + if ((enableLTO) || (mCodeGenOptions.mWriteBitcode)) { std::error_code ec; @@ -5460,12 +5473,12 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) { return false; } - + if (enableLTO) PM.add(createWriteThinLTOBitcodePass(*outStream, NULL)); else PM.add(createBitcodeWriterPass(*outStream, false, false, false)); - } + } //TargetPassConfig *PassConfig = target->createPassConfig(PM); //PM.add(new BfPass()); @@ -5485,7 +5498,7 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) llvm::AnalysisID StopAfterID = nullptr; const llvm::PassRegistry *PR = llvm::PassRegistry::getPassRegistry(); - //WriteBitcode + //WriteBitcode bool noVerify = false; // Option if ((!enableLTO) && (!mCodeGenOptions.mWriteBitcode)) @@ -5515,7 +5528,7 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) fileName += "_OPT.ll"; String irError; - WriteIR(fileName, irError); + WriteIR(fileName, irError); } } @@ -5524,25 +5537,25 @@ bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName) bool BfIRCodeGen::WriteIR(const StringImpl& outFileName, StringImpl& error) { - std::error_code ec; + std::error_code ec; llvm::raw_fd_ostream outStream(outFileName.c_str(), ec, llvm::sys::fs::OpenFlags::OF_Text); if (ec) { error = ec.message(); return false; - } + } mLLVMModule->print(outStream, NULL); return true; } int BfIRCodeGen::GetIntrinsicId(const StringImpl& name) -{ +{ auto itr = std::lower_bound(std::begin(gIntrinEntries), std::end(gIntrinEntries), name); if (itr != std::end(gIntrinEntries) && strcmp(itr->mName, name.c_str()) == 0) { int id = (int)(itr - gIntrinEntries); return id; - } + } if (name.StartsWith("shuffle")) return BfIRIntrinsic_Shuffle; @@ -5594,7 +5607,7 @@ int BF_AARC64_Linkage() { LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64Target(); - LLVMInitializeAArch64TargetMC(); + LLVMInitializeAArch64TargetMC(); return 0; } #endif diff --git a/IDEHelper/Compiler/BfIRCodeGen.h b/IDEHelper/Compiler/BfIRCodeGen.h index 049ca8d7..28773467 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.h +++ b/IDEHelper/Compiler/BfIRCodeGen.h @@ -20,7 +20,7 @@ namespace llvm class AttributeList; class Module; class LLVMContext; - class TargetMachine; + class TargetMachine; }; NS_BF_BEGIN @@ -41,7 +41,7 @@ class BfIRIntrinsicData public: String mName; BfIRIntrinsic mIntrinsic; - llvm::Type* mReturnType; + llvm::Type* mReturnType; }; struct BfIRCodeGenEntry @@ -52,7 +52,7 @@ struct BfIRCodeGenEntry llvm::Value* mLLVMValue; llvm::Type* mLLVMType; llvm::BasicBlock* mLLVMBlock; - llvm::MDNode* mLLVMMetadata; + llvm::MDNode* mLLVMMetadata; BfIRIntrinsicData* mIntrinsicData; }; }; @@ -67,7 +67,7 @@ public: llvm::DIType* mInstDIType; llvm::Type* mLLVMType; llvm::Type* mAlignLLVMType; - llvm::Type* mInstLLVMType; + llvm::Type* mInstLLVMType; public: BfIRTypeEntry() @@ -87,14 +87,14 @@ enum BfIRSizeAlignKind { BfIRSizeAlignKind_NoTransform, BfIRSizeAlignKind_Original, - BfIRSizeAlignKind_Aligned, + BfIRSizeAlignKind_Aligned, }; class BfIRCodeGen : public BfIRCodeGenBase { -public: - BfIRBuilder* mBfIRBuilder; - +public: + BfIRBuilder* mBfIRBuilder; + BumpAllocator mAlloc; BfTargetTriple mTargetTriple; String mTargetCPU; @@ -113,7 +113,7 @@ public: llvm::InlineAsm* mOverflowCheckAsm; llvm::DebugLoc mDebugLoc; BfCodeGenOptions mCodeGenOptions; - bool mHasDebugLoc; + bool mHasDebugLoc; bool mIsCodeView; bool mHadDLLExport; int mConstValIdx; @@ -122,7 +122,7 @@ public: Dictionary mResults; Dictionary mTypes; Dictionary mIntrinsicMap; - Dictionary mIntrinsicReverseMap; + Dictionary mIntrinsicReverseMap; Array mConfigConsts32; Array mConfigConsts64; Dictionary mReflectDataMap; @@ -131,7 +131,7 @@ public: HashSet mLockedBlocks; OwnedArray mIntrinsicData; -public: +public: void InitTarget(); void FixValues(llvm::StructType* structType, llvm::SmallVector& values); void FixIndexer(llvm::Value*& val); @@ -141,15 +141,15 @@ public: BfIRTypeEntry* GetTypeEntry(llvm::Type* type); void SetResult(int id, llvm::Value* value); void SetResultAligned(int id, llvm::Value* value); - void SetResult(int id, llvm::Type* value); + void SetResult(int id, llvm::Type* value); void SetResult(int id, llvm::BasicBlock* value); - void SetResult(int id, llvm::MDNode* value); + void SetResult(int id, llvm::MDNode* value); void CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false); void AddNop(); llvm::Value* TryToVector(llvm::Value* value); llvm::Value* TryToVector(llvm::Value* value, llvm::Type* elemType); llvm::Type* GetElemType(llvm::Value* value); - bool TryMemCpy(llvm::Value* ptr, llvm::Value* val); + bool TryMemCpy(llvm::Value* ptr, llvm::Value* val); bool TryVectorCpy(llvm::Value* ptr, llvm::Value* val); llvm::Type* GetSizeAlignedType(BfIRTypeEntry* typeEntry); llvm::Value* GetAlignedPtr(llvm::Value* val); @@ -168,7 +168,7 @@ public: void PrintFunction(); int64 ReadSLEB128(); - void Read(StringImpl& str); + void Read(StringImpl& str); void Read(int& i); void Read(int64& i); void Read(Val128& i); @@ -227,14 +227,14 @@ public: llvm::BasicBlock* GetLLVMBlock(int streamId); llvm::MDNode* GetLLVMMetadata(int streamId); - llvm::Type* GetLLVMTypeById(int id); + llvm::Type* GetLLVMTypeById(int id); /// bool WriteObjectFile(const StringImpl& outFileName); bool WriteIR(const StringImpl& outFileName, StringImpl& error); - static int GetIntrinsicId(const StringImpl& name); + static int GetIntrinsicId(const StringImpl& name); static const char* GetIntrinsicName(int intrinId); static void SetAsmKind(BfAsmKind asmKind); @@ -242,4 +242,3 @@ public: }; NS_BF_END - diff --git a/IDEHelper/Compiler/BfMangler.cpp b/IDEHelper/Compiler/BfMangler.cpp index c3330d71..6954585f 100644 --- a/IDEHelper/Compiler/BfMangler.cpp +++ b/IDEHelper/Compiler/BfMangler.cpp @@ -16,7 +16,7 @@ int BfGNUMangler::ParseSubIdx(StringImpl& name, int strIdx) void BfGNUMangler::AddSubIdx(StringImpl& name, int subIdx) { - name += 'S'; + name += 'S'; if (subIdx != 0) { int showIdx = subIdx - 1; @@ -29,7 +29,7 @@ void BfGNUMangler::AddSubIdx(StringImpl& name, int subIdx) name += '0' + showIdx; else name += 'A' + (showIdx - 10); - } + } name += '_'; } @@ -60,20 +60,20 @@ BfTypeCode BfGNUMangler::GetPrimTypeAt(MangleContext& mangleContext, StringImpl& case 'm': return BfTypeCode_UInt64; case 'x': return BfTypeCode_Int64; case 'y': return BfTypeCode_UInt64; - case 'u': + case 'u': if (name[strIdx + 1] == '3') return BfTypeCode_IntPtr; if (name[strIdx + 1] == '4') return BfTypeCode_UIntPtr; - break; + break; case 'c': return BfTypeCode_Char8; - case 'D': + case 'D': if (name[strIdx + 1] == 'i') return BfTypeCode_Char32; else if (name[strIdx + 1] == 's') return BfTypeCode_Char16; break; - case 'f': return BfTypeCode_Float; + case 'f': return BfTypeCode_Float; case 'd': return BfTypeCode_Double; } return (BfTypeCode)-1; @@ -93,7 +93,7 @@ void BfGNUMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int { BF_ASSERT(name.EndsWith('_')); name.RemoveToEnd(startIdx); - AddSubIdx(name, matchIdx); + AddSubIdx(name, matchIdx); return; } } @@ -107,9 +107,9 @@ void BfGNUMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int { auto& entry = mangleContext.mSubstituteList[matchIdx]; if ((entry.mKind == NameSubstitute::Kind_PrimitivePrefix) && (entry.mExtendsTypeCode == typeCode) && (entry.mPrefix == prefix)) - { + { name.RemoveToEnd(startIdx); - AddSubIdx(name, matchIdx); + AddSubIdx(name, matchIdx); return; } } @@ -125,7 +125,7 @@ void BfGNUMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int } else { - // Applies to last-added one + // Applies to last-added one subIdx = (int)mangleContext.mSubstituteList.size() - 1; BF_ASSERT(isdigit(startChar) || (startChar == 'A') || (startChar == 'N') || (startChar == 'P') || (startChar == 'R') || (startChar == 'U')); } @@ -146,35 +146,35 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& bool matchFailed = false; FindOrCreateNameSub(mangleContext, name, newNameSub, curMatchIdx, matchFailed); if (!matchFailed) - AddSubIdx(name, curMatchIdx); + AddSubIdx(name, curMatchIdx); } void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub, int& curMatchIdx, bool& matchFailed) -{ +{ int parentIdx = curMatchIdx; if (!matchFailed) - { + { curMatchIdx++; for ( ; curMatchIdx < (int)mangleContext.mSubstituteList.size(); curMatchIdx++) { auto& entry = mangleContext.mSubstituteList[curMatchIdx]; if ((entry.mExtendsIdx == parentIdx) && (entry.mKind == newNameSub.mKind) && (entry.mParam == newNameSub.mParam)) - { + { return; } } - + matchFailed = true; if (newNameSub.mKind != BfGNUMangler::NameSubstitute::Kind_GenericParam) name += "N"; if (parentIdx != -1) - AddSubIdx(name, parentIdx); + AddSubIdx(name, parentIdx); } - + if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom) { AddSizedString(name, newNameSub.mAtom->mString.mPtr); - } + } else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName) { auto typeDef = newNameSub.mTypeInst->mTypeDef; @@ -182,15 +182,15 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& // when we remove the "incorrect" version. I believe this is no longer needed since our compilation model has changed /*if (typeDef->mDupDetectedRevision != -1) { - char str[64]; + char str[64]; sprintf(str, "_%p", typeDef); name += str; }*/ if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure())) - { + { auto closureType = (BfClosureType*)newNameSub.mTypeInst; - if (!closureType->mCreatedTypeDef) - name += closureType->mNameAdd; + if (!closureType->mCreatedTypeDef) + name += closureType->mNameAdd; } AddSizedString(name, typeDef->mName->mString.mPtr); } @@ -199,7 +199,7 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& int genericParamStart = 0; if (newNameSub.mTypeInst->mTypeDef->mOuterType != NULL) genericParamStart = (int)newNameSub.mTypeInst->mTypeDef->mOuterType->mGenericParamDefs.size(); - + name += "I"; auto typeDef = newNameSub.mTypeInst->mTypeDef; @@ -214,10 +214,10 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& BfTypeInstance* genericTypeInstance = (BfTypeInstance*)checkType; for (int genericParamIdx = genericParamStart; genericParamIdx < (int) typeDef->mGenericParamDefs.size(); genericParamIdx++) - { + { auto genericParam = genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx]; - Mangle(mangleContext, name, genericParam); + Mangle(mangleContext, name, genericParam); } name += "E"; @@ -229,18 +229,18 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& if (genericParamType->mGenericParamIdx < 10) name += "3"; else - name += "4"; + name += "4"; if (genericParamType->mGenericParamKind == BfGenericParamKind_Method) name += "`M"; else - name += "`T"; + name += "`T"; itoa(genericParamType->mGenericParamIdx, str, 10); name += str; } - + curMatchIdx = (int)mangleContext.mSubstituteList.size(); mangleContext.mSubstituteList.push_back(newNameSub); - + auto& nameSubRef = mangleContext.mSubstituteList.back(); nameSubRef.mExtendsIdx = parentIdx; } @@ -269,17 +269,17 @@ void BfGNUMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& if (typeDef->mGenericParamDefs.size() != numOuterGenericParams) { - FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeGenericArgs, typeInst), curMatchIdx, matchFailed); + FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_TypeGenericArgs, typeInst), curMatchIdx, matchFailed); } } void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInstance, bool* isEndOpen) -{ +{ static int sCallCount = 0; sCallCount++; - + if (typeInst->IsTuple()) - { + { auto tupleType = (BfTypeInstance*)typeInst; name += "N7__TUPLEI"; mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE' @@ -294,7 +294,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name } name += "E"; mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE' - if (isEndOpen != NULL) + if (isEndOpen != NULL) *isEndOpen = true; else name += "E"; @@ -311,7 +311,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name else name += "N8functionI"; SizedArray typeVec; - typeVec.push_back(BfNodeDynCast(methodDef->mReturnTypeRef)->mType); + typeVec.push_back(BfNodeDynCast(methodDef->mReturnTypeRef)->mType); if (methodDef->mIsMutating) name += "_mut_"; if (delegateInfo->mCallingConvention == BfCallingConvention_Cdecl) @@ -342,15 +342,15 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name name += "E"; name += "E"; } - else if (typeInst->IsBoxed()) + else if (typeInst->IsBoxed()) { - auto boxedType = (BfBoxedType*)typeInst; + auto boxedType = (BfBoxedType*)typeInst; name += "N3BoxI"; - mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box' + mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box' Mangle(mangleContext, name, boxedType->GetModifiedElementType(), postfixTypeInstance); - name += "E"; + name += "E"; mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for 'Box' - if (isEndOpen != NULL) + if (isEndOpen != NULL) *isEndOpen = true; else name += "E"; @@ -373,20 +373,20 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name if (!mangleContext.mCPPMangle) FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed); - + for (int i = 0; i < typeDef->mNamespace.mSize; i++) FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeDef->mNamespace.mParts[i]), curMatchIdx, matchFailed); - + FindOrCreateNameSub(mangleContext, name, useTypeInst, curMatchIdx, matchFailed); } if (isEndOpen != NULL) - { + { if (!matchFailed) - { + { if (curMatchIdx != -1) { name += "N"; - AddSubIdx(name, curMatchIdx); + AddSubIdx(name, curMatchIdx); *isEndOpen = true; } else @@ -403,30 +403,30 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name } else { - AddSubIdx(name, curMatchIdx); + AddSubIdx(name, curMatchIdx); } } void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType, bool isConst) -{ +{ static int sCallCount = 0; sCallCount++; - + if (type->IsPrimitiveType()) { - auto primType = (BfPrimitiveType*)type; + auto primType = (BfPrimitiveType*)type; switch (primType->mTypeDef->mTypeCode) { case BfTypeCode_NullPtr: { auto pointerType = (BfPointerType*)type; - int startIdx = (int)name.length(); + int startIdx = (int)name.length(); name += "v"; - AddPrefix(mangleContext, name, startIdx, "P"); + AddPrefix(mangleContext, name, startIdx, "P"); } return; - case BfTypeCode_Dot: + case BfTypeCode_Dot: name += "U3dot"; return; case BfTypeCode_None: @@ -434,7 +434,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType name += "v"; else name += "U4void"; - return; + return; case BfTypeCode_Self: if ((mangleContext.mCCompat) || (mangleContext.mInArgs)) name += "U8concrete"; @@ -519,28 +519,28 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType //name += Mangle(primType->mTypeDef, NULL, addName, NULL, substituteList); } else if (type->IsTypeInstance()) - { + { BfTypeInstance* postfixTypeInst = NULL; if (postfixType != NULL) postfixTypeInst = postfixType->ToTypeInstance(); - auto typeInstance = (BfTypeInstance*)type; + auto typeInstance = (BfTypeInstance*)type; int startIdx = (int)name.length(); MangleTypeInst(mangleContext, name, typeInstance, postfixTypeInst); if ((type->IsObjectOrInterface()) && (mangleContext.mPrefixObjectPointer)) - AddPrefix(mangleContext, name, startIdx, "P"); - } + AddPrefix(mangleContext, name, startIdx, "P"); + } else if (type->IsGenericParam()) - { + { FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_GenericParam, type)); } else if (type->IsPointer()) - { + { auto pointerType = (BfPointerType*)type; - int startIdx = (int)name.length(); + int startIdx = (int)name.length(); Mangle(mangleContext, name, pointerType->mElementType); - AddPrefix(mangleContext, name, startIdx, "P"); + AddPrefix(mangleContext, name, startIdx, "P"); return; } else if (type->IsRef()) @@ -555,15 +555,15 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType name += "U3mut"; Mangle(mangleContext, name, refType->mElementType); return; - } + } else if ((refType->mRefKind == BfRefType::RefKind_Out) && (!mangleContext.mCCompat)) { name += "U3out"; Mangle(mangleContext, name, refType->mElementType); return; } - int startIdx = (int)name.length(); - Mangle(mangleContext, name, refType->mElementType); + int startIdx = (int)name.length(); + Mangle(mangleContext, name, refType->mElementType); AddPrefix(mangleContext, name, startIdx, isConst ? "RK" : "R"); return; } @@ -609,7 +609,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType } else if (type->IsMethodRef()) { - auto methodRefType = (BfMethodRefType*)type; + auto methodRefType = (BfMethodRefType*)type; String mrefName = "mref_"; String mangleName; BfMethodInstance* methodInstance = methodRefType->mMethodRef; @@ -618,7 +618,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType BF_ASSERT(!methodRefType->mMangledMethodName.IsEmpty()); mangleName = methodRefType->mMangledMethodName; } - else + else { if (methodInstance->mIsAutocompleteMethod) name += "AUTOCOMPLETE"; @@ -629,7 +629,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType // There are cases where we will reprocess a method in ResolveOnly for things like // GetSymbolReferences, so we will have duplicate live local methodInstances in those cases mrefName += HashEncode64((uint64)methodRefType->mMethodRef); - } + } else { mangleName = Mangle(methodInstance); @@ -638,7 +638,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType } if (!mangleName.IsEmpty()) - { + { Val128 val128 = Hash128(mangleName.c_str(), (int)mangleName.length()); mrefName += HashEncode128(val128); } @@ -647,9 +647,9 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType name += mrefName; } else if (type->IsConstExprValue()) - { + { BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; - int64 val = constExprValueType->mValue.mInt64; + int64 val = constExprValueType->mValue.mInt64; if ((!constExprValueType->mType->IsPrimitiveType()) || (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr)) @@ -657,7 +657,7 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType Mangle(mangleContext, name, constExprValueType->mType); } - name += "$0"; + name += "$0"; if (val < 0) { @@ -677,27 +677,27 @@ void BfGNUMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType while (val > 0) { *(--strP) = (char)((val % 0x10) + 'A'); - val /= 0x10; + val /= 0x10; } name += strP; name += '`'; - } + } if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let) name += "Undef"; } else { - BF_FATAL("Not handled"); + BF_FATAL("Not handled"); } } String BfGNUMangler::Mangle(BfType* type, BfModule* module) { - StringT<256> name; + StringT<256> name; name += "_ZTS"; - MangleContext mangleContext; + MangleContext mangleContext; mangleContext.mModule = module; Mangle(mangleContext, name, type); return name; @@ -706,9 +706,9 @@ String BfGNUMangler::Mangle(BfType* type, BfModule* module) String BfGNUMangler::Mangle(BfMethodInstance* methodInst) { StringT<256> name; - + if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx)) - { + { return methodInst->mMethodDef->mName; } @@ -717,13 +717,13 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) auto typeInst = methodInst->GetOwner(); auto typeDef = typeInst->mTypeDef; - MangleContext mangleContext; + MangleContext mangleContext; mangleContext.mModule = methodInst->GetOwner()->mModule; if (methodInst->mCallingConvention != BfCallingConvention_Unspecified) - mangleContext.mCCompat = true; - bool isCMangle = false; + mangleContext.mCCompat = true; + bool isCMangle = false; HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle); - if (isCMangle) + if (isCMangle) name += methodInst->mMethodDef->mName; if (!name.IsEmpty()) return name; @@ -732,7 +732,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) bool prefixLen = false; bool isNameOpen = false; - name += "_Z"; + name += "_Z"; MangleTypeInst(mangleContext, name, methodInst->mMethodInstanceGroup->mOwner, methodInst->GetExplicitInterface(), &isNameOpen); if (methodInst->GetForeignType() != NULL) @@ -740,7 +740,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) // This won't demangle correctly. TODO: Do this 'correctly' MangleTypeInst(mangleContext, name, methodInst->GetForeignType()); } - + mangleContext.mPrefixObjectPointer = true; StringT<128> methodName = methodInst->mMethodDef->mName; for (int i = 0; i < (int)methodName.length(); i++) @@ -834,7 +834,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) break; case BfBinaryOp_As: methodName = "2as"; - break; + break; default: break; } @@ -886,7 +886,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) else if (methodInst->mMethodDef->mMethodType == BfMethodType_Ctor) { if (methodInst->mMethodDef->mIsStatic) - { + { methodName = "__BfStaticCtor"; prefixLen = true; } @@ -896,7 +896,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) else if (methodInst->mMethodDef->mMethodType == BfMethodType_Dtor) { if (methodInst->mMethodDef->mIsStatic) - { + { methodName = "__BfStaticDtor"; prefixLen = true; } @@ -922,10 +922,10 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) if (methodDef->mHasComptime) name += "`COMPTIME"; - if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) && + if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) && ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) || - ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) && - (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) && + ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) && + (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) && ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor)))) { auto declType = methodInst->mMethodDef->mDeclaringType; @@ -968,22 +968,22 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) methodName += methodInst->mMethodInstanceGroup->mOwner->mTypeDef->mProject->mName; } - if (prefixLen) - AddSizedString(name, methodName); - else + if (prefixLen) + AddSizedString(name, methodName); + else name += methodName; - + if (methodInst->GetNumGenericArguments() != 0) - { + { auto& methodGenericArguments = methodInst->mMethodInfoEx->mMethodGenericArguments; NameSubstitute nameSub(NameSubstitute::Kind_MethodName, methodInst); - nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1; + nameSub.mExtendsIdx = (int)mangleContext.mSubstituteList.size() - 1; mangleContext.mSubstituteList.push_back(nameSub); name += 'I'; for (auto genericArg : methodGenericArguments) Mangle(mangleContext, name, genericArg); - name += 'E'; + name += 'E'; } else if (methodInst->mMethodDef->mGenericParams.size() != 0) { @@ -999,7 +999,7 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) if (isNameOpen) name += 'E'; - + if (methodInst->mMethodDef->mGenericParams.size() != 0) Mangle(mangleContext, name, methodInst->mReturnType); @@ -1010,8 +1010,8 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) if (doExplicitThis) // Explicit "_this" Mangle(mangleContext, name, typeInst->GetUnderlyingType()); - for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++) - { + for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++) + { BfType* paramType = methodInst->GetParamType(paramIdx); bool isConst = false; @@ -1035,20 +1035,20 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst) } String BfGNUMangler::MangleMethodName(BfTypeInstance* type, const StringImpl& methodName) -{ +{ MangleContext mangleContext; mangleContext.mModule = type->mModule; - StringT<256> name = "_Z"; + StringT<256> name = "_Z"; auto typeInst = type->ToTypeInstance(); BF_ASSERT(typeInst != NULL); - + bool isNameOpen; - MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen); - AddSizedString(name, methodName); + MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen); + AddSizedString(name, methodName); if (isNameOpen) name += "E"; - name += "v"; + name += "v"; return name; } @@ -1061,11 +1061,11 @@ String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImp auto typeDef = typeInst->mTypeDef; if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty())) return fieldName; - - StringT<256> name = "_Z"; + + StringT<256> name = "_Z"; bool isNameOpen; MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen); - AddSizedString(name, fieldName); + AddSizedString(name, fieldName); if (isNameOpen) name += "E"; return name; @@ -1076,7 +1076,7 @@ String BfGNUMangler::Mangle(BfFieldInstance* fieldInstance) StringT<256> name; MangleContext mangleContext; mangleContext.mModule = fieldInstance->mOwner->mModule; - + bool isCMangle = false; HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle); if (isCMangle) @@ -1117,12 +1117,12 @@ void BfMSMangler::AddGenericArgs(MangleContext& mangleContext, StringImpl& name, auto prevSubList = mangleContext.mSubstituteList; auto prevSubTypeList = mangleContext.mSubstituteTypeList; mangleContext.mSubstituteList.clear(); - + for (int genericIdx = numOuterGenericParams; genericIdx < (int)genericArgs.size(); genericIdx++) - Mangle(mangleContext, name, genericArgs[genericIdx]); - + Mangle(mangleContext, name, genericArgs[genericIdx]); + mangleContext.mSubstituteList = prevSubList; - mangleContext.mSubstituteTypeList = prevSubTypeList; + mangleContext.mSubstituteTypeList = prevSubTypeList; } void BfMSMangler::AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str) @@ -1176,7 +1176,7 @@ void BfMSMangler::AddTypeStart(MangleContext& mangleContext, StringImpl& name, B BF_ASSERT(type->mSize >= 0); // The enum size is supposed to be encoded, but VC always uses '4' - //name += "W"; + //name += "W"; //name += ('0' + type->mSize); name += "W4"; return; @@ -1195,7 +1195,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& AddSubIdx(name, curMatchIdx); return true; } - } + } if (newNameSub.mKind == NameSubstitute::Kind_NamespaceAtom) { @@ -1205,7 +1205,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& else if (newNameSub.mKind == NameSubstitute::Kind_TypeInstName) { if (mangleContext.mWantsGroupStart) - { + { AddTypeStart(mangleContext, name, newNameSub.mTypeInst); mangleContext.mWantsGroupStart = false; } @@ -1231,9 +1231,9 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& else if ((newNameSub.mTypeInst->IsDelegateFromTypeRef()) || (newNameSub.mTypeInst->IsFunctionFromTypeRef())) { BF_ASSERT(newNameSub.mTypeInst->mTypeDef->mMethods[0]->mName == "Invoke"); - + auto delegateInfo = newNameSub.mTypeInst->GetDelegateInfo(); - + auto methodDef = newNameSub.mTypeInst->mTypeDef->mMethods[0]; if (newNameSub.mTypeInst->IsDelegate()) name += "?$delegate"; @@ -1250,9 +1250,9 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& SizedArray typeVec; typeVec.push_back(BfNodeDynCast(methodDef->mReturnTypeRef)->mType); - + for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) - { + { name += "_"; name += methodDef->mParams[paramIdx]->mName; if (methodDef->mParams[paramIdx]->mParamKind == BfParamKind_VarArgs) @@ -1265,14 +1265,14 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name += '@'; if (!typeVec.empty()) AddGenericArgs(mangleContext, name, typeVec); - name += '@'; + name += '@'; } else if (newNameSub.mTypeInst->IsBoxed()) { auto boxedType = (BfBoxedType*)newNameSub.mTypeInst; name += "?$Box@"; SizedArray typeVec; - typeVec.push_back(boxedType->GetModifiedElementType()); + typeVec.push_back(boxedType->GetModifiedElementType()); AddGenericArgs(mangleContext, name, typeVec); name += '@'; } @@ -1281,8 +1281,8 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& auto typeDef = newNameSub.mTypeInst->mTypeDef; BfTypeInstance* genericTypeInst = NULL; - if (newNameSub.mTypeInst->IsGenericTypeInstance()) - genericTypeInst = (BfTypeInstance*)newNameSub.mTypeInst; + if (newNameSub.mTypeInst->IsGenericTypeInstance()) + genericTypeInst = (BfTypeInstance*)newNameSub.mTypeInst; int numOuterGenericParams = 0; if ((!mangleContext.mIsSafeMangle) && (typeDef->mOuterType != NULL)) @@ -1300,16 +1300,16 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& if (genericTypeInst != NULL) { name += "?$"; - mangleContext.mWantsGroupStart = false; + mangleContext.mWantsGroupStart = false; } - -// name += *typeDef->mName->mString; + +// name += *typeDef->mName->mString; // if ((typeDef->mIsDelegate) && (newNameSub.mTypeInst->IsClosure())) // { // auto closureType = (BfClosureType*)newNameSub.mTypeInst; // if (!closureType->mCreatedTypeDef) // name += closureType->mNameAdd; -// } +// } if (newNameSub.mTypeInst->IsClosure()) { @@ -1330,11 +1330,11 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name += '@'; } } - } + } else if (newNameSub.mKind == BfGNUMangler::NameSubstitute::Kind_GenericParam) { name += "U"; // Struct - auto genericParamType = (BfGenericParamType*)newNameSub.mType; + auto genericParamType = (BfGenericParamType*)newNameSub.mType; if (genericParamType->mGenericParamKind == BfGenericParamKind_Method) name += "_M"; else @@ -1345,14 +1345,14 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name += '@'; name += '@'; } - + mangleContext.mSubstituteList.push_back(newNameSub); return false; } void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInstance, bool isAlreadyStarted, bool isOuterType) -{ +{ BfTypeInstance* genericTypeInst = NULL; if (typeInstance->IsGenericTypeInstance()) { @@ -1365,7 +1365,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeI { if ((hasNamespace) || (typeDef->mOuterType != NULL)) { - AddTypeStart(mangleContext, name, typeInstance); + AddTypeStart(mangleContext, name, typeInstance); } else { @@ -1377,14 +1377,14 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeI if (!typeDef->IsGlobalsContainer()) FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_TypeInstName, typeInstance)); - mangleContext.mWantsGroupStart = false; + mangleContext.mWantsGroupStart = false; auto useModule = typeInstance->mModule; if (useModule == NULL) useModule = mangleContext.mModule; - + if ((typeDef->mOuterType != NULL) && (!typeInstance->IsBoxed())) - { + { if (mangleContext.mIsSafeMangle) { auto outerType = typeDef->mOuterType; @@ -1401,7 +1401,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeI auto outerType = unreifiedModule->GetOuterType(typeInstance); if (outerType != NULL) Mangle(mangleContext, name, outerType, true, true); - else + else useModule->Fail("Failed to mangle name in BfMSMangler::Mangle"); } } @@ -1501,7 +1501,7 @@ void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int } else { - // Applies to last-added one + // Applies to last-added one subIdx = (int)mangleContext.mSubstituteList.size() - 1; BF_ASSERT(isdigit(startChar) || (startChar == 'N') || (startChar == 'P') || (startChar == 'R')); } @@ -1517,7 +1517,7 @@ void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int } void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList, bool isConst) -{ +{ bool isLongPrim = false; if (type->IsPrimitiveType()) @@ -1536,7 +1536,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* } return; case BfTypeCode_None: - name += "X"; return; + name += "X"; return; case BfTypeCode_Int8: name += "C"; return; case BfTypeCode_UInt8: @@ -1548,7 +1548,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* case BfTypeCode_Int32: name += "H"; return; case BfTypeCode_UInt32: - name += "I"; return; + name += "I"; return; case BfTypeCode_Char8: name += "D"; return; case BfTypeCode_Char16: @@ -1559,10 +1559,10 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* name += "N"; return; case BfTypeCode_Int64: case BfTypeCode_UInt64: - case BfTypeCode_Boolean: - case BfTypeCode_Char32: + case BfTypeCode_Boolean: + case BfTypeCode_Char32: isLongPrim = true; - break; + break; case BfTypeCode_IntPtr: if ((primType->mSize == 4) && (mangleContext.mCCompat)) { @@ -1603,9 +1603,9 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* default: name += "?"; return; - } - } - + } + } + if (useTypeList) { for (int checkIdx = 0; checkIdx < (int)mangleContext.mSubstituteTypeList.size(); checkIdx++) @@ -1643,7 +1643,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* else if (mangleContext.mCCompat) name += "_J"; else - name += "Tint@@"; + name += "Tint@@"; break; case BfTypeCode_Char32: name += "_U"; break; @@ -1665,7 +1665,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* else if (((type->IsGenericTypeInstance()) || (type->IsComposite()) || (type->IsEnum())) && (mangleContext.mInRet)) name += "?A"; - Mangle(mangleContext, name, typeInstance, false); + Mangle(mangleContext, name, typeInstance, false); } else if (type->IsGenericParam()) { @@ -1680,12 +1680,12 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* if (mangleContext.mIs64Bit) name += "PE"; else - name += "P"; + name += "P"; if (isConst) name += "B"; else name += "A"; - Mangle(mangleContext, name, pointerType->mElementType); + Mangle(mangleContext, name, pointerType->mElementType); } else if (type->IsRef()) { @@ -1698,11 +1698,11 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* else name += "A"; if (refType->mRefKind == BfRefType::RefKind_Mut) - name += "mut$"; + name += "mut$"; else if (refType->mRefKind == BfRefType::RefKind_Out) name += "out$"; Mangle(mangleContext, name, refType->mElementType); - } + } else if (type->IsModifiedTypeType()) { auto retType = (BfModifiedTypeType*)type; @@ -1734,12 +1734,12 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* } else { - // We can't use MS mangling of "_O" because it isn't size-specific + // We can't use MS mangling of "_O" because it isn't size-specific auto arrType = (BfSizedArrayType*)type; //name += StrFormat("arr_%d$", arrType->mSize); //Mangle(mangleContext, name, arrType->mElementType); - name += "?$_ARRAY@"; + name += "?$_ARRAY@"; Mangle(mangleContext, name, arrType->mElementType); MangleConst(mangleContext, name, arrType->mElementCount); name += '@'; @@ -1747,9 +1747,9 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* } else if (type->IsMethodRef()) { - auto methodRefType = (BfMethodRefType*)type; + auto methodRefType = (BfMethodRefType*)type; name += "Tmref_"; - + StringT<128> mangleName; BfMethodInstance* methodInstance = methodRefType->mMethodRef; if (methodInstance == NULL) @@ -1783,10 +1783,10 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* } // if (methodInstance->mIsAutocompleteMethod) -// name += "AUTOCOMPLETE"; -// +// name += "AUTOCOMPLETE"; +// // String mangleAdd = Mangle(mangleContext.mIs64Bit, methodInstance); -// +// // auto module = methodInstance->GetOwner()->mModule; // if (module->mCompiler->mIsResolveOnly) // { @@ -1799,19 +1799,19 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* // Val128 val128 = Hash128(mangleAdd.c_str(), (int)mangleAdd.length()); // name += HashEncode128(val128); // } - name += "@@"; + name += "@@"; } else if (type->IsConstExprValue()) { BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; int64 val = constExprValueType->mValue.mInt64; - if ((!constExprValueType->mType->IsPrimitiveType()) || + if ((!constExprValueType->mType->IsPrimitiveType()) || (((BfPrimitiveType*)constExprValueType->mType)->mTypeDef->mTypeCode != BfTypeCode_IntPtr)) { Mangle(mangleContext, name, constExprValueType->mType); name += "$"; } - MangleConst(mangleContext, name, val); + MangleConst(mangleContext, name, val); if (constExprValueType->mValue.mTypeCode == BfTypeCode_Let) name += "Undef"; } @@ -1819,7 +1819,7 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* { BF_ASSERT("Unhandled"); } - + if ((useTypeList) && (!mangleContext.mInRet) && ((int)mangleContext.mSubstituteTypeList.size() < 10)) mangleContext.mSubstituteTypeList.push_back(type); } @@ -1841,7 +1841,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfType* type, BfModule* mangleContext.mModule = module; auto typeInst = type->ToTypeInstance(); if ((typeInst != NULL) && (typeInst->mModule != NULL)) - mangleContext.mModule = typeInst->mModule; + mangleContext.mModule = typeInst->mModule; if (typeInst != NULL) Mangle(mangleContext, name, typeInst, true); else @@ -1854,7 +1854,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho { static int mangleIdx = 0; mangleIdx++; - + int startNameLen = name.mLength; if ((methodInst->mMethodDef->mCLink) && (!methodInst->mMangleWithIdx)) { @@ -1865,20 +1865,20 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho auto methodDef = methodInst->mMethodDef; auto methodDeclaration = BfNodeDynCastExact(methodDef->mMethodDeclaration); auto typeInst = methodInst->GetOwner(); - auto typeDef = typeInst->mTypeDef; - + auto typeDef = typeInst->mTypeDef; + MangleContext mangleContext; mangleContext.mIs64Bit = is64Bit; - mangleContext.mModule = methodInst->GetOwner()->mModule; + mangleContext.mModule = methodInst->GetOwner()->mModule; if (methodInst->mCallingConvention != BfCallingConvention_Unspecified) mangleContext.mCCompat = true; - bool isCMangle = false; + bool isCMangle = false; HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle); if (isCMangle) name += methodInst->mMethodDef->mName; if (name.mLength > startNameLen) return; - + name += '?'; if (methodInst->GetNumGenericArguments() != 0) @@ -2020,7 +2020,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho } switch (operatorDef->mOperatorDeclaration->mAssignOp) - { + { case BfAssignmentOp_Assign: methodName += "__a__"; break; @@ -2061,7 +2061,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho if (!methodName.empty()) { AddStr(mangleContext, name, methodName); - } + } } /*else if ((methodDef->mMethodType == BfMethodType_Ctor) && (!methodDef->mIsStatic)) { @@ -2078,7 +2078,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho else if (methodInst->GetNumGenericArguments() != 0) { AddStr(mangleContext, name, methodDef->mName); - AddGenericArgs(mangleContext, name, methodInst->mMethodInfoEx->mMethodGenericArguments); + AddGenericArgs(mangleContext, name, methodInst->mMethodInfoEx->mMethodGenericArguments); name += '@'; } else @@ -2086,13 +2086,13 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho if ((!mangleContext.mCPPMangle) && (!methodDef->mIsMutating) && (!methodDef->mIsStatic) && (methodInst->GetOwner()->IsValueType())) AddStr(mangleContext, name, methodDef->mName + "__im"); else - AddStr(mangleContext, name, methodDef->mName); + AddStr(mangleContext, name, methodDef->mName); } - if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) && + if (((methodInst->GetOwner()->mTypeDef->IsGlobalsContainer()) && ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_Dtor) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC))) || - ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) && - (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) && + ((methodInst->mMethodDef->mDeclaringType->mPartialIdx != -1) && (methodInst->mMethodDef->mDeclaringType->IsExtension()) && + (!methodInst->mIsForeignMethodDef) && (!methodInst->mMethodDef->mIsExtern) && ((!methodInst->mMethodDef->mIsOverride) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mMethodType == BfMethodType_Dtor)))) { auto declType = methodInst->mMethodDef->mDeclaringType; @@ -2100,9 +2100,9 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho auto declProject = declType->mProject; bool addProjectName = (declProject != typeInst->mTypeDef->mProject); bool addIndex = true; - + if (typeInst->mTypeDef->IsGlobalsContainer()) - { + { addProjectName = true; if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) || @@ -2110,9 +2110,9 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho { addProjectName = false; addIndex = false; - } + } } - + if (addProjectName) { name += declProject->mName; @@ -2129,7 +2129,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho if (methodDef->mCheckedKind == BfCheckedKind_Checked) name += "CHK$"; else if (methodDef->mCheckedKind == BfCheckedKind_Unchecked) - name += "UCHK$"; + name += "UCHK$"; if (methodDef->mHasComptime) name += "COMPTIME$"; @@ -2145,7 +2145,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho Mangle(mangleContext, name, methodInst->GetForeignType(), true); if (methodInst->GetExplicitInterface() != NULL) Mangle(mangleContext, name, methodInst->GetExplicitInterface(), true); - + /// { // Only use CCompat for params, not for the owning type name - unless we're doing an explicit CPP mangle @@ -2177,14 +2177,14 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho if ((methodDef->mIsVirtual) && (!methodDef->mIsOverride)) attrib += 4; - + name += attrib; auto bfSystem = methodInst->GetOwner()->mModule->mSystem; if ((!methodDef->mIsStatic) && (!doExplicitThis)) - { + { /*char cvQualifier = 'A'; - if (mangleContext.mIs64Bit) + if (mangleContext.mIs64Bit) cvQualifier = 'E'; name += cvQualifier;*/ if (mangleContext.mIs64Bit) @@ -2192,7 +2192,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho char qualifier = 'A'; // const / volatile name += qualifier; - } + } auto callingConvention = mangleContext.mModule->GetIRCallingConvention(methodInst); @@ -2229,7 +2229,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho mangleContext.mInArgs = true; if (doExplicitThis) - { + { Mangle(mangleContext, name, typeInst->GetUnderlyingType(), true); } for (auto& param : methodInst->mParams) @@ -2237,7 +2237,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho bool isConst = false; if ((param.mParamDefIdx >= 0) && (methodDeclaration != NULL) && (param.mParamDefIdx < methodDeclaration->mParams.mSize)) { - auto paramDecl = methodDeclaration->mParams[param.mParamDefIdx]; + auto paramDecl = methodDeclaration->mParams[param.mParamDefIdx]; HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst); } @@ -2247,7 +2247,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho } name += 'Z'; - + bool wantLog = false; if (wantLog) { @@ -2258,8 +2258,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho String demangled = BfDemangler::Demangle(name, DbgLanguage_Beef); BfLog2(" Demangled %d: %s\n", mangleIdx, demangled.c_str()); } - } - + } } void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldInstance) @@ -2278,41 +2277,41 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldI BF_ASSERT(fieldDef->mIsStatic); MangleContext mangleContext; mangleContext.mIs64Bit = is64Bit; - mangleContext.mModule = fieldInstance->mOwner->mModule; + mangleContext.mModule = fieldInstance->mOwner->mModule; - bool isCMangle = false; + bool isCMangle = false; HandleCustomAttributes(fieldInstance->mCustomAttributes, fieldInstance->mOwner->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle); if (isCMangle) name += fieldInstance->GetFieldDef()->mName; if (!name.IsEmpty()) return; - + name += '?'; - AddStr(mangleContext, name, fieldDef->mName); + AddStr(mangleContext, name, fieldDef->mName); Mangle(mangleContext, name, fieldInstance->mOwner, true); name += '2'; //TODO: Don't always mark as 'public' Mangle(mangleContext, name, fieldInstance->mResolvedType); - name += ('A' + /*(fieldDef->mIsConst ? 1 : 0) +*/ (fieldDef->mIsVolatile ? 2 : 0)); + name += ('A' + /*(fieldDef->mIsConst ? 1 : 0) +*/ (fieldDef->mIsVolatile ? 2 : 0)); } void BfMSMangler::MangleMethodName(StringImpl& name, bool is64Bit, BfTypeInstance* type, const StringImpl& methodName) { MangleContext mangleContext; mangleContext.mIs64Bit = is64Bit; - mangleContext.mModule = type->GetModule(); + mangleContext.mModule = type->GetModule(); name += '?'; - AddStr(mangleContext, name, methodName); - Mangle(mangleContext, name, type, true); - name += "SAXXZ"; + AddStr(mangleContext, name, methodName); + Mangle(mangleContext, name, type, true); + name += "SAXXZ"; } void BfMSMangler::MangleStaticFieldName(StringImpl& name, bool is64Bit, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType) -{ +{ MangleContext mangleContext; mangleContext.mIs64Bit = is64Bit; - mangleContext.mModule = owner->GetModule(); + mangleContext.mModule = owner->GetModule(); name += '?'; - AddStr(mangleContext, name, fieldName); + AddStr(mangleContext, name, fieldName); Mangle(mangleContext, name, owner, true); //name += "@@"; name += '2'; // public @@ -2320,7 +2319,7 @@ void BfMSMangler::MangleStaticFieldName(StringImpl& name, bool is64Bit, BfTypeIn name += 'H'; else Mangle(mangleContext, name, fieldType); - name += "A"; // static + name += "A"; // static } ////////////////////////////////////////////////////////////////////////// @@ -2331,7 +2330,7 @@ String BfSafeMangler::Mangle(BfType* type, BfModule* module) mangleContext.mIs64Bit = true; mangleContext.mModule = module; mangleContext.mIsSafeMangle = true; - auto typeInst = type->ToTypeInstance(); + auto typeInst = type->ToTypeInstance(); String name; if (typeInst != NULL) BfMSMangler::Mangle(mangleContext, name, typeInst, true); @@ -2359,9 +2358,9 @@ void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstan } void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance) -{ +{ if (mangleKind == BfMangler::MangleKind_GNU) - { + { outStr += BfGNUMangler::Mangle(fieldInstance); } else @@ -2388,7 +2387,7 @@ void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfI { if (customAttributes == NULL) return; - + auto linkNameAttr = customAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef); if (linkNameAttr != NULL) { @@ -2402,7 +2401,7 @@ void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfI if (constant != NULL) { if (constant->mInt32 == 1) // C - { + { isCMangle = true; } else if (constant->mInt32 == 2) // CPP @@ -2411,7 +2410,7 @@ void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfI } } } - } + } } void BfMangler::HandleParamCustomAttributes(BfAttributeDirective* attributes, bool isReturn, bool& isConst) @@ -2427,4 +2426,4 @@ void BfMangler::HandleParamCustomAttributes(BfAttributeDirective* attributes, bo attributes = attributes->mNextAttribute; } -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfMangler.h b/IDEHelper/Compiler/BfMangler.h index c3f0794e..5b362d2f 100644 --- a/IDEHelper/Compiler/BfMangler.h +++ b/IDEHelper/Compiler/BfMangler.h @@ -33,7 +33,7 @@ public: Kind_MethodName, Kind_Prefix, Kind_PrimitivePrefix, - Kind_GenericParam + Kind_GenericParam }; public: @@ -54,7 +54,7 @@ public: BfTypeInstance* mTypeInst; BfMethodInstance* mMethodInstance; const char* mPrefix; - }; + }; public: NameSubstitute(Kind kind, void* param) @@ -90,7 +90,7 @@ public: class BfGNUMangler : public BfMangler { -public: +public: class MangleContext { public: @@ -111,22 +111,22 @@ public: mPrefixObjectPointer = false; } }; - + static int ParseSubIdx(StringImpl& name, int strIdx); static void AddSubIdx(StringImpl& name, int strIdx); static void AddSizedString(StringImpl& name, const StringImpl& addStr); static BfTypeCode GetPrimTypeAt(MangleContext& mangleContext, StringImpl& name, int strIdx); - static void AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix); + static void AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix); static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub, int& curMatchIdx, bool& matchFailed); static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, int& curMatchIdx, bool& matchFailed); - static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub); + static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub); public: static void MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInst = NULL, bool* isEndOpen = NULL); static void Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType = NULL, bool isConst = false); static String Mangle(BfType* type, BfModule* module = NULL); - static String Mangle(BfMethodInstance* methodRef); + static String Mangle(BfMethodInstance* methodRef); static String MangleMethodName(BfTypeInstance* type, const StringImpl& methodName); static String Mangle(BfFieldInstance* methodRef); static String MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName); @@ -138,12 +138,12 @@ public: class MangleContext { public: - bool mIsSafeMangle; + bool mIsSafeMangle; BfModule* mModule; bool mCCompat; bool mCPPMangle; - bool mIs64Bit; + bool mIs64Bit; SizedArray mSubstituteList; SizedArray mSubstituteTypeList; @@ -154,7 +154,7 @@ public: public: MangleContext() { - mIsSafeMangle = false; + mIsSafeMangle = false; mModule = NULL; mCCompat = false; mIs64Bit = false; @@ -164,11 +164,11 @@ public: mInRet = false; } - BfModule* GetUnreifiedModule(); + BfModule* GetUnreifiedModule(); }; static void AddGenericArgs(MangleContext& mangleContext, StringImpl& name, const SizedArrayImpl& genericArgs, int numOuterGenericParams = 0); - + static void AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str); static void Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList = false, bool isConst = false); static void Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, bool isAlreadyStarted, bool isOuterType = false); @@ -176,8 +176,8 @@ public: void AddPrefix(MangleContext & mangleContext, StringImpl& name, int startIdx, const char * prefix); - static void AddSubIdx(StringImpl& name, int strIdx); - static void AddTypeStart(MangleContext & mangleContext, StringImpl& name, BfType* type); + static void AddSubIdx(StringImpl& name, int strIdx); + static void AddTypeStart(MangleContext & mangleContext, StringImpl& name, BfType* type); static bool FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub); public: @@ -188,7 +188,7 @@ public: static void MangleStaticFieldName(StringImpl& outStr, bool is64Bit, BfTypeInstance* type, const StringImpl& fieldName, BfType* fieldType = NULL); }; -// A "safe mangle" is used for reconnecting deleted types to their previous id. We make sure we never force a +// A "safe mangle" is used for reconnecting deleted types to their previous id. We make sure we never force a // PopulateType with this kind of mangle, as referenced types may be deleted and marked as undefined class BfSafeMangler : public BfMSMangler { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 80e18e3c..c7797481 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -40,7 +40,7 @@ USING_NS_BF; ////////////////////////////////////////////////////////////////////////// void BfLocalVariable::Init() -{ +{ if (mResolvedType->IsValuelessType()) { mAssignedKind = BfLocalVarAssignKind_Unconditional; @@ -79,13 +79,13 @@ BfLocalMethod::~BfLocalMethod() { BfLogSys(mSystem, "~BfLocalMethod %p\n", this); if (mMethodDeclaration != NULL) - { + { mSource->mRefCount--; BF_ASSERT(mSource->mRefCount >= 0); } - + delete mMethodInstanceGroup; - delete mMethodDef; + delete mMethodDef; } void BfLocalMethod::Dispose() @@ -94,7 +94,7 @@ void BfLocalMethod::Dispose() return; if (mMethodInstanceGroup->mDefault != NULL) mMethodInstanceGroup->mDefault->Dispose(); - + if (mMethodInstanceGroup->mMethodSpecializationMap != NULL) { for (auto& kv : *mMethodInstanceGroup->mMethodSpecializationMap) @@ -106,17 +106,17 @@ void BfDeferredLocalAssignData::ExtendFrom(BfDeferredLocalAssignData* outerLocal { mIsChained = doChain; if (outerLocalAssignData == NULL) - return; + return; mChainedAssignData = outerLocalAssignData; - if (!doChain) + if (!doChain) { outerLocalAssignData->BreakExtendChain(); - mAssignedLocals = outerLocalAssignData->mAssignedLocals; + mAssignedLocals = outerLocalAssignData->mAssignedLocals; } mVarIdBarrier = outerLocalAssignData->mVarIdBarrier; } -// The "extend chain" is broken when we have a conditional where the variable may not be defined after the block. +// The "extend chain" is broken when we have a conditional where the variable may not be defined after the block. // IE: "a" will be defined after the following, but "b" will not necessarily be defined. // if ((GetValue(out a)) && (GetValue(out b)) {} void BfDeferredLocalAssignData::BreakExtendChain() @@ -127,54 +127,67 @@ void BfDeferredLocalAssignData::BreakExtendChain() if (mChainedAssignData == NULL) return; mChainedAssignData->BreakExtendChain(); - mAssignedLocals = mChainedAssignData->mAssignedLocals; + mAssignedLocals = mChainedAssignData->mAssignedLocals; } void BfDeferredLocalAssignData::SetIntersection(const BfDeferredLocalAssignData& otherLocalAssignData) -{ +{ BreakExtendChain(); - for (int i = 0; i < (int)mAssignedLocals.size(); ) + if (otherLocalAssignData.mLeftBlockUncond) { - auto& local = mAssignedLocals[i]; - - bool wantRemove = true; - bool foundOtherFields = false; - for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals) + // Intersection of self and infinity is self + } + else if (mLeftBlockUncond) + { + // Intersection of infinity and other is other + mAssignedLocals = otherLocalAssignData.mAssignedLocals; + } + else + { + for (int i = 0; i < (int)mAssignedLocals.size(); ) { - if (otherLocalAssignData.mLocalVar == local.mLocalVar) - { - if ((otherLocalAssignData.mLocalVarField == local.mLocalVarField) || (otherLocalAssignData.mLocalVarField == -1)) - { - if (otherLocalAssignData.mAssignKind == BfLocalVarAssignKind_Conditional) - local.mAssignKind = BfLocalVarAssignKind_Conditional; - wantRemove = false; - } - else - foundOtherFields = true; - } - } + auto& local = mAssignedLocals[i]; - if ((wantRemove) && (foundOtherFields)) - { + bool wantRemove = true; + bool foundOtherFields = false; for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals) { if (otherLocalAssignData.mLocalVar == local.mLocalVar) { - mAssignedLocals.Add(otherLocalAssignData); + if ((otherLocalAssignData.mLocalVarField == local.mLocalVarField) || (otherLocalAssignData.mLocalVarField == -1)) + { + if (otherLocalAssignData.mAssignKind == BfLocalVarAssignKind_Conditional) + local.mAssignKind = BfLocalVarAssignKind_Conditional; + wantRemove = false; + } + else + foundOtherFields = true; } } - } - if (wantRemove) - { - mAssignedLocals.RemoveAt(i); + if ((wantRemove) && (foundOtherFields)) + { + for (auto& otherLocalAssignData : otherLocalAssignData.mAssignedLocals) + { + if (otherLocalAssignData.mLocalVar == local.mLocalVar) + { + mAssignedLocals.Add(otherLocalAssignData); + } + } + } + + if (wantRemove) + { + mAssignedLocals.RemoveAt(i); + } + else + i++; } - else - i++; } mHadFallthrough = mHadFallthrough && otherLocalAssignData.mHadFallthrough; + mLeftBlockUncond = mLeftBlockUncond && otherLocalAssignData.mLeftBlockUncond; } void BfDeferredLocalAssignData::Validate() const @@ -194,24 +207,25 @@ void BfDeferredLocalAssignData::SetUnion(const BfDeferredLocalAssignData& otherL auto otherItr = otherLocalAssignData.mAssignedLocals.begin(); while (otherItr != otherLocalAssignData.mAssignedLocals.end()) - { + { if (!mAssignedLocals.Contains(*otherItr)) mAssignedLocals.push_back(*otherItr); ++otherItr; } mHadFallthrough = mHadFallthrough || otherLocalAssignData.mHadFallthrough; + mLeftBlockUncond = mLeftBlockUncond || otherLocalAssignData.mLeftBlockUncond; } BfMethodState::~BfMethodState() -{ - BF_ASSERT(mPendingNullConditional == NULL); +{ + BF_ASSERT(mPendingNullConditional == NULL); if (mPrevMethodState != NULL) { BF_ASSERT(mCurAccessId == 1); BF_ASSERT(mCurLocalVarId <= 0); } - + for (auto local : mLocals) { if (local->mIsBumpAlloc) @@ -240,13 +254,13 @@ BfMethodState* BfMethodState::GetMethodStateForLocal(BfLocalVariable* localVar) } void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLocalVarAssignKind assignKind, bool isFromDeferredAssignData) -{ +{ auto localVarMethodState = GetMethodStateForLocal(localVar); if (localVarMethodState != this) { return; } - + if (localVar->mAssignedKind == BfLocalVarAssignKind_None) { BfDeferredLocalAssignData* ifDeferredLocalAssignData = NULL; @@ -259,15 +273,15 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca (!deferredLocalAssignData->mIfMayBeSkipped)) { ifDeferredLocalAssignData = deferredLocalAssignData; - deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData; + deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData; } - while ((deferredLocalAssignData != NULL) && + while ((deferredLocalAssignData != NULL) && ((deferredLocalAssignData->mIsChained) || (deferredLocalAssignData->mIsUnconditional))) deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData; if (assignKind == BfLocalVarAssignKind_None) - assignKind = ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mLeftBlock)) ? BfLocalVarAssignKind_Conditional : BfLocalVarAssignKind_Unconditional; + assignKind = ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mLeftBlock)) ? BfLocalVarAssignKind_Conditional : BfLocalVarAssignKind_Unconditional; if (localVar->mAssignedKind >= assignKind) { @@ -277,23 +291,30 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca { if (fieldIdx >= 0) { - localVar->mUnassignedFieldFlags &= ~((int64)1 << fieldIdx); + localVar->mUnassignedFieldFlags &= ~((int64)1 << fieldIdx); + + if (localVar->mResolvedType->IsUnion()) + { + // We need more 'smarts' to determine assignment of unions + localVar->mUnassignedFieldFlags = 0; + } + if (localVar->mUnassignedFieldFlags == 0) { if (localVar->mAssignedKind == BfLocalVarAssignKind_None) - localVar->mAssignedKind = assignKind; + localVar->mAssignedKind = assignKind; } } else { - localVar->mAssignedKind = assignKind; + localVar->mAssignedKind = assignKind; } } else - { + { BF_ASSERT(deferredLocalAssignData->mVarIdBarrier != -1); - BfAssignedLocal defineVal = {localVar, fieldIdx, assignKind}; + BfAssignedLocal defineVal = {localVar, fieldIdx, assignKind}; if (!deferredLocalAssignData->Contains(defineVal)) deferredLocalAssignData->mAssignedLocals.push_back(defineVal); @@ -311,9 +332,33 @@ void BfMethodState::ApplyDeferredLocalAssignData(const BfDeferredLocalAssignData { BF_ASSERT(&deferredLocalAssignData != mDeferredLocalAssignData); - for (auto& assignedLocal : deferredLocalAssignData.mAssignedLocals) + if (deferredLocalAssignData.mLeftBlockUncond) { - LocalDefined(assignedLocal.mLocalVar, assignedLocal.mLocalVarField, assignedLocal.mAssignKind, true); + for (int localIdx = 0; localIdx < (int)mLocals.size(); localIdx++) + { + auto localDef = mLocals[localIdx]; + if (localDef->mAssignedKind == BfLocalVarAssignKind_None) + { + bool hadAssignment = false; + if (mDeferredLocalAssignData != NULL) + { + for (auto& entry : mDeferredLocalAssignData->mAssignedLocals) + if (entry.mLocalVar == localDef) + hadAssignment = true; + } + if (!hadAssignment) + { + LocalDefined(localDef); + } + } + } + } + else + { + for (auto& assignedLocal : deferredLocalAssignData.mAssignedLocals) + { + LocalDefined(assignedLocal.mLocalVar, assignedLocal.mLocalVarField, assignedLocal.mAssignKind, true); + } } } @@ -327,8 +372,8 @@ void BfMethodState::Reset() void BfAmbiguityContext::Add(int id, BfTypeInterfaceEntry* interfaceEntry, int methodIdx, BfMethodInstance* candidateA, BfMethodInstance* candidateB) { Entry* entry = NULL; - - if (mEntries.TryAdd(id, NULL, &entry)) + + if (mEntries.TryAdd(id, NULL, &entry)) { entry->mInterfaceEntry = interfaceEntry; entry->mMethodIdx = methodIdx; @@ -340,7 +385,7 @@ void BfAmbiguityContext::Add(int id, BfTypeInterfaceEntry* interfaceEntry, int m } void BfAmbiguityContext::Remove(int id) -{ +{ mEntries.Remove(id); } @@ -503,7 +548,7 @@ public: else if (auto arrayTypeRef = BfNodeDynCast(objCreateExpr->mTypeRef)) { isArrayAlloc = true; - + bool handled = false; if (auto dotTypeRef = BfNodeDynCast(arrayTypeRef->mElementType)) @@ -519,7 +564,7 @@ public: handled = true; } } - + if (!handled) { origResolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType); @@ -576,7 +621,7 @@ public: } dimLengthVals.push_back(dimLength.mValue); } - } + } if (!isRawArrayAlloc) arrayType = mModule->CreateArrayType(origResolvedTypeRef, dimensions); @@ -671,7 +716,7 @@ public: if (arrayType == NULL) arrayType = mModule->CreateArrayType(resultType, 1); - // Array is a special case where the total size isn't aligned with mAlign + // Array is a special case where the total size isn't aligned with mAlign // since we add arbitrary elements to the end without padding the end to align EmitAppendAlign(arrayType->mAlign, resultType->mAlign); curAlign = arrayType->mAlign; @@ -727,16 +772,16 @@ public: calcAppendArgs.RemoveRange(0, 2); // Remove 'this' and 'appendIdx' auto calcAppendMethodModule = mModule->GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND); - + auto subDependSize = mModule->TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, calcAppendArgs); if (calcAppendMethodModule.mMethodInstance->mAppendAllocAlign > 0) - { + { EmitAppendAlign(calcAppendMethodModule.mMethodInstance->mAppendAllocAlign); BF_ASSERT(calcAppendMethodModule.mMethodInstance->mEndingAppendAllocAlign > -1); mModule->mCurMethodState->mCurAppendAlign = BF_MAX(calcAppendMethodModule.mMethodInstance->mEndingAppendAllocAlign, 0); } - curAlign = std::max(curAlign, (int)calcAppendMethodModule.mMethodInstance->mAppendAllocAlign); + curAlign = std::max(curAlign, (int)calcAppendMethodModule.mMethodInstance->mAppendAllocAlign); if ((!subDependSize) && (!mConstAccum)) { BF_ASSERT(calcAppendMethodModule.mFunc); @@ -750,7 +795,7 @@ public: mFailed = true; } } - } + } if (sizeValue) { @@ -771,7 +816,7 @@ public: auto addedVal = mModule->mBfIRBuilder->CreateAdd(sizeValue, prevVal); mModule->mBfIRBuilder->CreateAlignedStore(addedVal, accumValuePtr, intPtrType->mAlign); } - } + } } } } @@ -792,10 +837,10 @@ public: if (varDecl->mNameNode != NULL) { - BfLocalVariable* localDef = new BfLocalVariable(); + BfLocalVariable* localDef = new BfLocalVariable(); localDef->mName = varDecl->mNameNode->ToString(); - localDef->mNameNode = BfNodeDynCast(varDecl->mNameNode); - localDef->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_None); + localDef->mNameNode = BfNodeDynCast(varDecl->mNameNode); + localDef->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_None); localDef->mIsReadOnly = true; localDef->mParamFailed = true; localDef->mReadFromId = 0; @@ -852,8 +897,8 @@ public: BfModule* gLastCreatedModule = NULL; -BfModule::BfModule(BfContext* context, const StringImpl& moduleName) -{ +BfModule::BfModule(BfContext* context, const StringImpl& moduleName) +{ BfLogSys(context->mSystem, "BfModule::BFModule %p %s\n", this, moduleName.c_str()); gLastCreatedModule = this; @@ -873,34 +918,34 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) mBfIRBuilder = NULL; mWantsIRIgnoreWrites = false; mModuleOptions = NULL; - mLastUsedRevision = -1; + mLastUsedRevision = -1; mUsedSlotCount = -1; - + mIsReified = true; mGeneratesCode = true; mReifyQueued = false; mIsSpecialModule = false; mIsComptimeModule = false; - mIsScratchModule = false; - mIsSpecializedMethodModuleRoot = false; // There may be mNextAltModules extending from this + mIsScratchModule = false; + mIsSpecializedMethodModuleRoot = false; // There may be mNextAltModules extending from this mHadBuildError = false; mHadBuildWarning = false; mIgnoreErrors = false; mHadIgnoredError = false; - mIgnoreWarnings = false; + mIgnoreWarnings = false; mReportErrors = true; mIsInsideAutoComplete = false; mIsDeleting = false; mSkipInnerLookup = false; - mIsHotModule = false; + mIsHotModule = false; mSetIllegalSrcPosition = false; mNoResolveGenericParams = false; mWroteToLib = false; mContext = context; mCompiler = context->mCompiler; - mSystem = mCompiler->mSystem; - mProject = NULL; - mCurMethodState = NULL; + mSystem = mCompiler->mSystem; + mProject = NULL; + mCurMethodState = NULL; mAttributeState = NULL; mCurLocalMethodId = 0; mParentNodeEntry = NULL; @@ -914,7 +959,7 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) mOnDemandMethodCount = 0; mHasGenericMethods = false; mCurMethodInstance = NULL; - mCurTypeInstance = NULL; + mCurTypeInstance = NULL; mAwaitingInitFinish = false; mAwaitingFinish = false; mHasFullDebugInfo = false; @@ -929,13 +974,13 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) void BfReportMemory(); BfModule::~BfModule() -{ +{ mRevision = -2; BfLogSysM("Deleting module %p: %s \n", this, mModuleName.c_str()); if (!mIsDeleting) - RemoveModuleData(); + RemoveModuleData(); } void BfModule::RemoveModuleData() @@ -945,7 +990,7 @@ void BfModule::RemoveModuleData() if (!mModuleName.empty()) { // Note: module names not necessarily unique - mContext->mUsedModuleNames.Remove(ToUpper(mModuleName)); + mContext->mUsedModuleNames.Remove(ToUpper(mModuleName)); } CleanupFileInstances(); @@ -1024,7 +1069,7 @@ void BfModule::Init(bool isFullRebuild) mCurMethodState = NULL; mAwaitingInitFinish = true; mOnDemandMethodCount = 0; - mAwaitingFinish = false; + mAwaitingFinish = false; mHasForceLinkMarker = false; mUsedSlotCount = -1; } @@ -1049,7 +1094,7 @@ void BfModule::FinishInit() mBfIRBuilder->Module_SetTargetTriple(mCompiler->mOptions.mTargetTriple, mCompiler->mOptions.mTargetCPU); - mBfIRBuilder->SetBackend(IsTargetingBeefBackend()); + mBfIRBuilder->SetBackend(IsTargetingBeefBackend()); if (moduleOptions.mOptLevel == BfOptLevel_OgPlus) { @@ -1061,7 +1106,7 @@ void BfModule::FinishInit() if (mIsComptimeModule) mHasFullDebugInfo = true; - + if (((!mCompiler->mIsResolveOnly) && (!mIsScratchModule) && (moduleOptions.mEmitDebugInfo != 0) && (mIsReified)) || (mIsComptimeModule)) { @@ -1069,7 +1114,7 @@ void BfModule::FinishInit() } else mHasFullDebugInfo = false; - + if ((mBfIRBuilder->DbgHasInfo()) && (mModuleName != "") && ((moduleOptions.mEmitDebugInfo != 0))) { @@ -1080,13 +1125,13 @@ void BfModule::FinishInit() else { mBfIRBuilder->Module_AddModuleFlag("Dwarf Version", 4); - } + } mBfIRBuilder->Module_AddModuleFlag("Debug Info Version", 3); mDICompileUnit = mBfIRBuilder->DbgCreateCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus, mModuleName, ".", "Beef Compiler 0.42.3", /*moduleOptions.mOptLevel > 0*/false, "", 0, !mHasFullDebugInfo); - } + } - mAwaitingInitFinish = false; + mAwaitingInitFinish = false; } void BfModule::CalcGeneratesCode() @@ -1104,7 +1149,7 @@ void BfModule::CalcGeneratesCode() } void BfModule::ReifyModule() -{ +{ BF_ASSERT((mCompiler->mCompileState != BfCompiler::CompileState_Unreified) && (mCompiler->mCompileState != BfCompiler::CompileState_VData)); BfLogSysM("ReifyModule %@ %s\n", this, mModuleName.c_str()); @@ -1113,14 +1158,14 @@ void BfModule::ReifyModule() CalcGeneratesCode(); mReifyQueued = false; StartNewRevision(RebuildKind_SkipOnDemandTypes, true); - mCompiler->mStats.mModulesReified++; + mCompiler->mStats.mModulesReified++; } void BfModule::UnreifyModule() { BfLogSysM("UnreifyModule %p %s\n", this, mModuleName.c_str()); BF_ASSERT((this != mContext->mScratchModule) && (this != mContext->mUnreifiedModule)); - mIsReified = false; + mIsReified = false; CalcGeneratesCode(); mReifyQueued = false; StartNewRevision(RebuildKind_None, true); @@ -1148,7 +1193,7 @@ void BfModule::PrepareForIRWriting(BfTypeInstance* typeInst) { if (HasCompiledOutput()) { - // It's possible that the target's code hasn't changed but we're requesting a new generic method specialization + // It's possible that the target's code hasn't changed but we're requesting a new generic method specialization if ((!mIsModuleMutable) && (!typeInst->IsUnspecializedType()) && (!typeInst->mResolvingVarField)) { StartExtension(); @@ -1165,7 +1210,7 @@ void BfModule::SetupIRBuilder(bool dbgVerifyCodeGen) if (mIsScratchModule) { mBfIRBuilder->mIgnoreWrites = true; - BF_ASSERT(!dbgVerifyCodeGen); + BF_ASSERT(!dbgVerifyCodeGen); } #ifdef _DEBUG if (mCompiler->mIsResolveOnly) @@ -1183,7 +1228,7 @@ void BfModule::SetupIRBuilder(bool dbgVerifyCodeGen) // The only purpose of not ignoring writes is so we can verify the codegen one instruction at a time mBfIRBuilder->mDbgVerifyCodeGen = true; } - } + } else if (!mGeneratesCode) { mBfIRBuilder->mIgnoreWrites = true; @@ -1230,10 +1275,10 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen) if ((!mIsScratchModule) && (!mAddedToCount)) { mCompiler->mStats.mModulesStarted++; - mAddedToCount = true; + mAddedToCount = true; } BF_ASSERT(mStaticFieldRefs.GetCount() == 0); - + /*if (mCompiler->mIsResolveOnly) BF_ASSERT(mIsResolveOnly);*/ mBfIRBuilder = new BfIRBuilder(this); @@ -1245,7 +1290,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen) BfIRValue BfModule::CreateForceLinkMarker(BfModule* module, String* outName) { - String name = "FORCELINKMOD_" + module->mModuleName; + String name = "FORCELINKMOD_" + module->mModuleName; if (outName != NULL) *outName = name; auto markerType = GetPrimitiveType(BfTypeCode_Int8); @@ -1254,7 +1299,7 @@ BfIRValue BfModule::CreateForceLinkMarker(BfModule* module, String* outName) void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) { - BP_ZONE("BfModule::StartNewRevision"); + BP_ZONE("BfModule::StartNewRevision"); // The project MAY be deleted because disabling a project can cause types to be deleted which // causes other types rebuild BEFORE they get deleted, which is okay (though wasteful) @@ -1269,13 +1314,13 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) // Already on new revision? if ((mRevision == mCompiler->mRevision) && (!force)) return; - + mHadBuildError = false; - mHadBuildWarning = false; + mHadBuildWarning = false; mExtensionCount = 0; mRevision = mCompiler->mRevision; mRebuildIdx++; - ClearModuleData(!force); + ClearModuleData(!force); // Clear this here, not in ClearModuleData, so we preserve those references even after writing out module if (rebuildKind != BfModule::RebuildKind_None) // Leave string pool refs for when we need to use things like [LinkName("")] methods bofore re-reification @@ -1290,7 +1335,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) mDeferredMethodCallData.Clear(); mDeferredMethodIds.Clear(); mModuleRefs.Clear(); - mOutFileNames.Clear(); + mOutFileNames.Clear(); mTypeDataRefs.Clear(); mInterfaceSlotRefs.Clear(); @@ -1327,7 +1372,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) mNextAltModule = NULL; BF_ASSERT(mModuleOptions == NULL); - BfLogSysM("Mod:%p StartNewRevision: %s Revision: %d\n", this, mModuleName.c_str(), mRevision); + BfLogSysM("Mod:%p StartNewRevision: %s Revision: %d\n", this, mModuleName.c_str(), mRevision); bool needsTypePopulated = false; int oldOnDemandCount = 0; @@ -1339,7 +1384,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) { for (int typeIdx = 0; typeIdx < (int)mOwnedTypeInstances.size(); typeIdx++) { - auto typeInst = mOwnedTypeInstances[typeIdx]; + auto typeInst = mOwnedTypeInstances[typeIdx]; if (!typeInst->IsDeleting()) { typeInst->mIsReified = mIsReified; @@ -1389,7 +1434,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force) } } } - + if (!mIsDeleting) Init(); mOnDemandMethodCount += oldOnDemandCount; @@ -1403,12 +1448,12 @@ void BfModule::StartExtension() BfLogSysM("Extension started of module %p\n", this); mExtensionCount++; - + if (mBfIRBuilder != NULL) - mPrevIRBuilders.push_back(mBfIRBuilder); + mPrevIRBuilders.push_back(mBfIRBuilder); mBfIRBuilder = NULL; mWantsIRIgnoreWrites = false; - + mFuncReferences.Clear(); mClassVDataRefs.Clear(); mClassVDataExtRefs.Clear(); @@ -1445,22 +1490,22 @@ void BfModule::GetConstClassValueParam(BfIRValue classVData, SizedArrayImplCreatePtrToInt(classVData, BfTypeCode_IntPtr); else - vDataValue = mBfIRBuilder->CreateBitCast(classVData, mBfIRBuilder->MapType(mContext->mBfClassVDataPtrType)); + vDataValue = mBfIRBuilder->CreateBitCast(classVData, mBfIRBuilder->MapType(mContext->mBfClassVDataPtrType)); typeValueParams.push_back(vDataValue); if (hasObjectDebugFlags) { auto primType = GetPrimitiveType(BfTypeCode_IntPtr); - typeValueParams.push_back(GetDefaultValue(primType)); + typeValueParams.push_back(GetDefaultValue(primType)); } } BfIRValue BfModule::GetConstValue(int64 val) -{ +{ return mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)val); } BfIRValue BfModule::GetConstValue(int64 val, BfType* type) -{ +{ BfType* checkType = type; if (type->IsTypedPrimitive()) { @@ -1478,7 +1523,7 @@ BfIRValue BfModule::GetConstValue(int64 val, BfType* type) } BfIRValue BfModule::GetConstValue8(int val) -{ +{ return mBfIRBuilder->CreateConst(BfTypeCode_Int8, (uint64)val); } @@ -1504,7 +1549,7 @@ BfIRValue BfModule::GetDefaultValue(BfType* type) return mBfIRBuilder->CreateConst(BfTypeCode_Int64, 0); return GetDefaultValue(type->GetUnderlyingType()); } - + if (type->IsPointer() || type->IsObjectOrInterface() || type->IsGenericParam() || type->IsVar() || type->IsRef() || type->IsNull() || type->IsModifiedTypeType() || type->IsConcreteInterfaceType()) return mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(type)); @@ -1516,7 +1561,7 @@ BfIRValue BfModule::GetDefaultValue(BfType* type) if (type->IsFloat()) { auto primType = (BfPrimitiveType*)type; - return mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, 0.0); + return mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, 0.0); } return mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(type)); } @@ -1556,9 +1601,9 @@ BfTypedValue BfModule::GetDefaultTypedValue(BfType* type, bool allowRef, BfDefau } else { - typedValue = BfTypedValue(CreateAlloca(type), type, BfTypedValueKind_Addr); + typedValue = BfTypedValue(CreateAlloca(type), type, BfTypedValueKind_Addr); } - + if (!mBfIRBuilder->mIgnoreWrites) { mBfIRBuilder->CreateMemSet(typedValue.mValue, GetConstValue(0, GetPrimitiveType(BfTypeCode_Int8)), @@ -1572,7 +1617,7 @@ BfTypedValue BfModule::GetDefaultTypedValue(BfType* type, bool allowRef, BfDefau } if ((type->IsRef()) && (!allowRef)) - { + { BfRefType* refType = (BfRefType*)type; BfType* underlyingType = refType->GetUnderlyingType(); if (underlyingType->IsValuelessType()) @@ -1582,29 +1627,29 @@ BfTypedValue BfModule::GetDefaultTypedValue(BfType* type, bool allowRef, BfDefau } else { - typedValue = BfTypedValue(GetDefaultValue(type), type, (defaultValueKind == BfDefaultValueKind_Addr) ? BfTypedValueKind_Addr : BfTypedValueKind_Value); + typedValue = BfTypedValue(GetDefaultValue(type), type, (defaultValueKind == BfDefaultValueKind_Addr) ? BfTypedValueKind_Addr : BfTypedValueKind_Value); } return typedValue; } BfIRValue BfModule::CreateStringCharPtr(const StringImpl& str, int stringId, bool define) -{ +{ String stringDataName = StrFormat("__bfStrData%d", stringId); auto charType = GetPrimitiveType(BfTypeCode_Char8); BfIRType irStrCharType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->MapType(charType), (int)str.length() + 1); - + BfIRValue strConstant; if (define) - { - strConstant = mBfIRBuilder->CreateConstString(str); + { + strConstant = mBfIRBuilder->CreateConstString(str); } BfIRValue gv = mBfIRBuilder->CreateGlobalVariable(irStrCharType, true, BfIRLinkageType_External, strConstant, stringDataName); if (define) - mBfIRBuilder->GlobalVar_SetUnnamedAddr(gv, true); + mBfIRBuilder->GlobalVar_SetUnnamedAddr(gv, true); return mBfIRBuilder->CreateInBoundsGEP(gv, 0, 0); } @@ -1623,18 +1668,18 @@ void BfModule::FixConstValueParams(BfTypeInstance* typeInst, SizedArrayImplmFieldInstances.size(); fieldIdx++) { auto fieldInstance = &typeInst->mFieldInstances[fieldIdx]; if (fieldInstance->mDataIdx < 0) continue; - + BF_ASSERT(fieldInstance->mDataIdx > prevDataIdx); if (fillInPadding) { - for (int i = prevDataIdx + 1; i < fieldInstance->mDataIdx; i++) + for (int i = prevDataIdx + 1; i < fieldInstance->mDataIdx; i++) valueParams.Insert(valueParamIdx++, mBfIRBuilder->CreateConstArrayZero(0)); } @@ -1644,7 +1689,7 @@ void BfModule::FixConstValueParams(BfTypeInstance* typeInst, SizedArrayImplmResolvedType)); } } @@ -1662,11 +1707,11 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, if (define) { - BfIRValue stringCharsVal = CreateStringCharPtr(str, stringId, define); + BfIRValue stringCharsVal = CreateStringCharPtr(str, stringId, define); mStringCharPtrPool[stringId] = stringCharsVal; - + SizedArray typeValueParams; - GetConstClassValueParam(classVDataGlobal, typeValueParams); + GetConstClassValueParam(classVDataGlobal, typeValueParams); FixConstValueParams(stringTypeInst->mBaseType, typeValueParams); auto objData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst->mBaseType, BfIRPopulateType_Full), typeValueParams); @@ -1678,19 +1723,19 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, if (lenByteCount == 4) { typeValueParams.push_back(GetConstValue32((int)str.length())); // mLength - typeValueParams.push_back(GetConstValue32((int32)(0x40000000 + str.length() + 1))); // mAllocSizeAndFlags + typeValueParams.push_back(GetConstValue32((int32)(0x40000000 + str.length() + 1))); // mAllocSizeAndFlags } else { typeValueParams.push_back(GetConstValue64(str.length())); // mLength - typeValueParams.push_back(GetConstValue64(0x4000000000000000LL + str.length() + 1)); // mAllocSizeAndFlags + typeValueParams.push_back(GetConstValue64(0x4000000000000000LL + str.length() + 1)); // mAllocSizeAndFlags } typeValueParams.push_back(stringCharsVal); // mPtr FixConstValueParams(stringTypeInst, typeValueParams); - + stringValData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), typeValueParams); } - + mBfIRBuilder->PopulateType(stringTypeInst); auto stringValLiteral = mBfIRBuilder->CreateGlobalVariable( mBfIRBuilder->MapTypeInst(stringTypeInst, BfIRPopulateType_Full), @@ -1703,7 +1748,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, } int BfModule::GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder) -{ +{ BF_ASSERT(constantStr.IsConst()); if (constHolder == NULL) @@ -1720,24 +1765,24 @@ int BfModule::GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHold auto constBitCast = (BfConstantBitCast*)constant; constant = constHolder->GetConstantById(constBitCast->mTarget); } - + if (constant->mConstType == BfConstType_GEP32_2) { auto constGEP = (BfConstantGEP32_2*)constant; constant = constHolder->GetConstantById(constGEP->mTarget); } - + if (constant->mConstType == BfConstType_GlobalVar) { auto constGV = (BfGlobalVar*)constant; - const char* strDataPrefix = "__bfStrData"; + const char* strDataPrefix = "__bfStrData"; if (strncmp(constGV->mName, strDataPrefix, strlen(strDataPrefix)) == 0) return atoi(constGV->mName + strlen(strDataPrefix)); - const char* strObjPrefix = "__bfStrObj"; + const char* strObjPrefix = "__bfStrObj"; if (strncmp(constGV->mName, strObjPrefix, strlen(strObjPrefix)) == 0) return atoi(constGV->mName + strlen(strObjPrefix)); - } + } return -1; } @@ -1747,9 +1792,9 @@ String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * c int strId = GetStringPoolIdx(constantStr, constHolder); if (strId != -1) { - auto& entry = mContext->mStringObjectIdMap[strId]; + auto& entry = mContext->mStringObjectIdMap[strId]; return &entry.mString; - } + } return NULL; } @@ -1766,7 +1811,7 @@ BfIRValue BfModule::GetStringCharPtr(int stringId, bool force) { if ((mBfIRBuilder->mIgnoreWrites) && (!force)) { - mUnreifiedStringPoolRefs.Add(stringId); + mUnreifiedStringPoolRefs.Add(stringId); return mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId); } @@ -1780,7 +1825,7 @@ BfIRValue BfModule::GetStringCharPtr(int stringId, bool force) const StringImpl& str = mContext->mStringObjectIdMap[stringId].mString; BfIRValue strCharPtrConst = CreateStringCharPtr(str, stringId, false); - *irValue = strCharPtrConst; + *irValue = strCharPtrConst; return strCharPtrConst; } @@ -1793,8 +1838,8 @@ BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue, bool force) return GetStringCharPtr(stringId, force); } - BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1); - BfIRValue charPtr = mBfIRBuilder->CreateLoad(charPtrPtr); + BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1); + BfIRValue charPtr = mBfIRBuilder->CreateLoad(charPtrPtr); return charPtr; } @@ -1804,7 +1849,7 @@ BfIRValue BfModule::GetStringCharPtr(const StringImpl& str, bool force) } BfIRValue BfModule::GetStringObjectValue(int strId, bool define, bool force) -{ +{ BfIRValue* objValue; if (mStringObjectPool.TryGetValue(strId, &objValue)) return *objValue; @@ -1814,11 +1859,11 @@ BfIRValue BfModule::GetStringObjectValue(int strId, bool define, bool force) } BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define, bool force) -{ +{ auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration); mBfIRBuilder->PopulateType(stringType); - int strId = mContext->GetStringLiteralId(str); + int strId = mContext->GetStringLiteralId(str); if ((mBfIRBuilder->mIgnoreWrites) && (!force)) { @@ -1839,15 +1884,15 @@ BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define, boo BfIRValue strObject = CreateStringObjectValue(str, strId, define); mStringObjectPool[strId] = strObject; - + mStringPoolRefs.Add(strId); - + return strObject; } BfIRValue BfModule::CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external) { - auto newConst = mBfIRBuilder->CreateGlobalVariable( + auto newConst = mBfIRBuilder->CreateGlobalVariable( type, true, external ? BfIRLinkageType_External : BfIRLinkageType_Internal, @@ -1867,7 +1912,7 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope) curScope->mScopeLocalId = rootMethodState->mCurLocalVarId++; auto autoComplete = mCompiler->GetAutoComplete(); if (autoComplete != NULL) - autoComplete->CheckLabel(curScope->mLabelNode, NULL, curScope); + autoComplete->CheckLabel(curScope->mLabelNode, NULL, curScope); } if (!mCurMethodState->mCurScope->mLabel.IsEmpty()) @@ -1895,7 +1940,7 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope) else mBfIRBuilder->CreateValueScopeHardEnd(prevScope->mValueScopeStart); } - + mCurMethodState->mBlockNestLevel++; if ((createLexicalBlock) && (mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo)) { @@ -1903,7 +1948,7 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope) if (mCurMethodState->mCurScope->mDIScope) mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateLexicalBlock(mCurMethodState->mCurScope->mDIScope, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mCurFilePosition.mCurColumn); } - mCurMethodState->mCurScope->mLocalVarStart = (int)mCurMethodState->mLocals.size(); + mCurMethodState->mCurScope->mLocalVarStart = (int)mCurMethodState->mLocals.size(); mCurMethodState->mCurScope->mBlock = mBfIRBuilder->MaybeChainNewBlock((!mCurMethodState->mCurScope->mLabel.empty()) ? mCurMethodState->mCurScope->mLabel : "newScope"); mCurMethodState->mCurScope->mMixinState = mCurMethodState->mMixinState; } @@ -1937,16 +1982,16 @@ void BfModule::RestoreScoreState_LocalVariables() } void BfModule::RestoreScopeState() -{ +{ BfScopeData* prevScopeData = mCurMethodState->mCurScope->mPrevScope; mCurMethodState->mBlockNestLevel--; - + if (!mCurMethodState->mCurScope->mAtEndBlocks.empty()) { BfIRBlock afterEndBlock; if (!mCurMethodState->mLeftBlockUncond) - { - afterEndBlock = mBfIRBuilder->CreateBlock("scopeAfterEnd"); + { + afterEndBlock = mBfIRBuilder->CreateBlock("scopeAfterEnd"); mBfIRBuilder->CreateBr(afterEndBlock); mBfIRBuilder->ClearDebugLocation_Last(); } @@ -1989,11 +2034,11 @@ BfIRValue BfModule::CreateAlloca(BfType* type, bool addLifetime, const char* nam allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type), arraySize); else allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type)); - mBfIRBuilder->SetAllocaAlignment(allocaInst, type->mAlign); + mBfIRBuilder->SetAllocaAlignment(allocaInst, type->mAlign); mBfIRBuilder->ClearDebugLocation(allocaInst); if (name != NULL) mBfIRBuilder->SetName(allocaInst, name); - mBfIRBuilder->SetInsertPoint(prevInsertBlock); + mBfIRBuilder->SetInsertPoint(prevInsertBlock); if ((addLifetime) && (WantsLifetimes())) { auto lifetimeStart = mBfIRBuilder->CreateLifetimeStart(allocaInst); @@ -2013,7 +2058,7 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime, auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapTypeInst(typeInst)); - mBfIRBuilder->SetAllocaAlignment(allocaInst, typeInst->mInstAlign); + mBfIRBuilder->SetAllocaAlignment(allocaInst, typeInst->mInstAlign); mBfIRBuilder->ClearDebugLocation(allocaInst); if (name != NULL) mBfIRBuilder->SetName(allocaInst, name); @@ -2030,24 +2075,24 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime, BfDeferredCallEntry* BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape, BfIRBlock valBlock) { //This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack" - // 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling + // 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling /*if (mCurMethodState->mInHeadScope) isScopeAlloc = true;*/ if (scopeData == NULL) return NULL; - + auto checkBaseType = val.mType->ToTypeInstance(); if ((checkBaseType != NULL) && (checkBaseType->IsObject()) && (!arraySize)) - { + { bool hadDtorCall = false; while (checkBaseType != NULL) - { + { BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this"); if (dtorMethodDef != NULL) - { + { auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); - if (dtorMethodInstance) + if (dtorMethodInstance) { bool isDynAlloc = (scopeData != NULL) && (mCurMethodState->mCurScope->IsDyn(scopeData)); BfIRValue useVal = val.mValue; @@ -2055,7 +2100,7 @@ BfDeferredCallEntry* BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySi BfIRBlock prevBlock = mBfIRBuilder->GetInsertBlock(); if (valBlock) mBfIRBuilder->SetInsertPoint(valBlock); - useVal = mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType)); + useVal = mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType)); if (!useVal.IsConst()) mBfIRBuilder->ClearDebugLocation(useVal); if (valBlock) @@ -2094,17 +2139,17 @@ BfDeferredCallEntry* BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySi checkBaseType = checkBaseType->mBaseType; } return NULL; - } - - //TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this + } + + //TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this if (mayEscape) { if ((!IsOptimized()) && (!mIsComptimeModule) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly)) - { + { auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr); bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData); if (!isDyn) - { + { const char* methodName = arraySize ? "SetDeletedArray" : "SetDeleted"; BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName); BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL); @@ -2128,14 +2173,14 @@ BfDeferredCallEntry* BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySi llvmArgs.push_back(arraySize); return AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true); } - } + } else { if ((arraySize) && (!arraySize.IsConst()) && (val.mType->mSize < mSystem->mPtrSize)) { BfIRValue clearSize = arraySize; if (val.mType->GetStride() > 1) - clearSize = mBfIRBuilder->CreateMul(clearSize, GetConstValue(val.mType->GetStride())); + clearSize = mBfIRBuilder->CreateMul(clearSize, GetConstValue(val.mType->GetStride())); const char* methodName = "SetDeletedX"; BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName); @@ -2203,27 +2248,27 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar) { int64 checkMask = (int64)1 << fieldInstance.mMergedDataIdx; if ((localVar->mUnassignedFieldFlags & checkMask) != 0) - { + { // For fields added in extensions, we automatically initialize those if necessary auto fieldDef = fieldInstance.GetFieldDef(); if (!fieldDef->mDeclaringType->IsExtension()) - return false; - + return false; + if ((fieldInstance.mDataIdx != -1) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) - { - auto curInsertBlock = mBfIRBuilder->GetInsertBlock(); - + { + auto curInsertBlock = mBfIRBuilder->GetInsertBlock(); + mBfIRBuilder->SaveDebugLocation(); if (localVar->IsParam()) mBfIRBuilder->SetInsertPointAtStart(mCurMethodState->mIRInitBlock); - else + else { BF_ASSERT(localVar->mDeclBlock); mBfIRBuilder->SetInsertPointAtStart(localVar->mDeclBlock); - } - + } + mBfIRBuilder->ClearDebugLocation(); - + BfIRValue curVal; if (localVar->mIsThis) curVal = mBfIRBuilder->GetArgument(0); @@ -2239,7 +2284,7 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar) auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(curVal, 0, fieldInstance.mDataIdx); auto defVal = GetDefaultValue(fieldInstance.mResolvedType); auto storeInst = mBfIRBuilder->CreateStore(defVal, fieldPtr); - + mBfIRBuilder->SetInsertPoint(curInsertBlock); mBfIRBuilder->RestoreDebugLocation(); } @@ -2261,7 +2306,7 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit) BfAstNode* localNameNode = localVar->mNameNode; if (localVar->mIsThis) { - localNameNode = mCurMethodInstance->mMethodDef->GetRefNode(); + localNameNode = mCurMethodInstance->mMethodDef->GetRefNode(); } if (localNameNode != NULL) @@ -2286,10 +2331,10 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit) deferFullAnalysis = true; //bool deferFullAnalysis = true; - bool deferUsageWarning = deferFullAnalysis && (mCompiler->IsAutocomplete()) && + bool deferUsageWarning = deferFullAnalysis && (mCompiler->IsAutocomplete()) && (mCompiler->mResolvePassData->mAutoComplete->mResolveType != BfResolveType_GetFixits); - if (((localVar->mAssignedKind != BfLocalVarAssignKind_Unconditional) || (localVar->mHadExitBeforeAssign)) && + if (((localVar->mAssignedKind != BfLocalVarAssignKind_Unconditional) || (localVar->mHadExitBeforeAssign)) && (!localVar->mIsImplicitParam)) { if (deferUsageWarning) @@ -2327,9 +2372,9 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit) // This initializer was handled in CtorNoBody foundFields = true; continue; - } + } } - + if (auto propertyDeclaration = BfNodeDynCast(fieldDef->mFieldDeclaration)) { String propName; @@ -2382,7 +2427,7 @@ void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit) } else if ((localVar->mReadFromId == -1) && (!localVar->IsParam()) && (!deferUsageWarning)) Warn(BfWarning_CS0168_VariableDeclaredButNeverUsed, StrFormat("The variable '%s' is assigned but its value is never used", localVar->mName.c_str()), localNameNode, deferFullAnalysis); - } + } } } @@ -2394,7 +2439,7 @@ void BfModule::CreateRetValLocal() localDef->mName = "return"; localDef->mResolvedType = mCurMethodState->mRetVal.mType; localDef->mAddr = mCurMethodState->mRetVal.mValue; - localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; + localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; AddLocalVariableDef(localDef); } else if (mCurMethodState->mRetValAddr) @@ -2415,7 +2460,7 @@ void BfModule::MarkDynStack(BfScopeData* scopeData) { if (checkScope == scopeData) break; - + checkScope->mHadOuterDynStack = true; checkScope = checkScope->mPrevScope; } @@ -2431,14 +2476,14 @@ void BfModule::SaveStackState(BfScopeData* scopeData) if (checkScope == scopeData) { if ((!checkScope->mSavedStack) && (checkScope->mBlock) && (!checkScope->mIsScopeHead) && (!checkScope->mHadOuterDynStack)) - { + { if (mBfIRBuilder->mHasDebugInfo) mBfIRBuilder->SaveDebugLocation(); auto prevPos = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPointAtStart(checkScope->mBlock); checkScope->mSavedStack = mBfIRBuilder->CreateStackSave(); mBfIRBuilder->ClearDebugLocation(checkScope->mSavedStack); - mBfIRBuilder->SetInsertPoint(prevPos); + mBfIRBuilder->SetInsertPoint(prevPos); if (mBfIRBuilder->mHasDebugInfo) mBfIRBuilder->RestoreDebugLocation(); } @@ -2451,8 +2496,8 @@ void BfModule::SaveStackState(BfScopeData* scopeData) checkScope->mSavedStackUses.Clear(); mBfIRBuilder->EraseInstFromParent(checkScope->mSavedStack); - checkScope->mSavedStack = BfIRValue(); - } + checkScope->mSavedStack = BfIRValue(); + } checkScope = checkScope->mPrevScope; } } @@ -2474,7 +2519,7 @@ BfProjectSet* BfModule::GetVisibleProjectSet() { if (mCurMethodState == NULL) return NULL; - + if (mCurMethodState->mVisibleProjectSet.IsEmpty()) { HashSet seenTypes; @@ -2510,14 +2555,14 @@ BfProjectSet* BfModule::GetVisibleProjectSet() return; for (auto type : typeInstance->mGenericTypeInfo->mTypeGenericArguments) { - if (seenTypes.Add(type)) + if (seenTypes.Add(type)) _AddType(type); - } + } }; if (mCurTypeInstance != NULL) _AddType(mCurTypeInstance); - + auto methodState = mCurMethodState; while (methodState != NULL) { @@ -2527,11 +2572,11 @@ BfProjectSet* BfModule::GetVisibleProjectSet() if (methodState->mMethodInstance->mMethodInfoEx != NULL) { for (auto type : methodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments) - _AddType(type); + _AddType(type); } } - methodState = methodState->mPrevMethodState; + methodState = methodState->mPrevMethodState; } } @@ -2551,7 +2596,7 @@ BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode) return *fileInstancePtr; } else - { + { // It's possible two parsers have the same file name (ie: mNextRevision) BfFileInstance** namedFileInstancePtr = NULL; if (!mNamedFileInstanceMap.TryAdd(bfParser->mFileName, NULL, &namedFileInstancePtr)) @@ -2562,7 +2607,7 @@ BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode) } int slashPos = (int)bfParser->mFileName.LastIndexOf(DIR_SEP_CHAR); - + auto bfFileInstance = new BfFileInstance(); *fileInstancePtr = bfFileInstance; *namedFileInstancePtr = bfFileInstance; @@ -2584,7 +2629,7 @@ BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode) bfFileInstance->mDIFile = mBfIRBuilder->DbgCreateFile(fileName.Substring(slashPos + 1), fileName.Substring(0, BF_MAX(slashPos, 0)), bfParser->mMD5Hash); } - return bfFileInstance; + return bfFileInstance; } } @@ -2609,7 +2654,7 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo BF_ASSERT(mFileInstanceMap.GetCount() != 0); mCurFilePosition.mFileInstance->mPrevPosition = mCurFilePosition; } - + auto bfFileInstance = GetFileFromNode(astNode); if (bfFileInstance->mPrevPosition.mFileInstance != NULL) { @@ -2621,7 +2666,7 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo mCurFilePosition.mCurLine = 0; mCurFilePosition.mCurSrcPos = 0; } - } + } int srcPos = astNode->GetSrcStart() + debugLocOffset; @@ -2631,11 +2676,11 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo if (jumpEntry->mCharIdx > srcPos) jumpEntry--; mCurFilePosition.mCurLine = jumpEntry->mLineNum; - mCurFilePosition.mCurSrcPos = jumpEntry->mCharIdx; + mCurFilePosition.mCurSrcPos = jumpEntry->mCharIdx; mCurFilePosition.mCurColumn = 0; while (mCurFilePosition.mCurSrcPos < srcPos) - { + { if (bfParser->mSrc[mCurFilePosition.mCurSrcPos] == '\n') { mCurFilePosition.mCurLine++; @@ -2651,10 +2696,10 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo //TODO: if we bail on the "mCurMethodState == NULL" case then we don't get it set during type declarations if (((flags & BfSrcPosFlag_NoSetDebugLoc) == 0) && (mBfIRBuilder->DbgHasLineInfo()) && (mCurMethodState != NULL)) - { + { int column = mCurFilePosition.mCurColumn + 1; if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend)) - { + { // Set to illegal position column = 0; } @@ -2681,14 +2726,14 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo { mCurMethodState->mCurScope->mAltDIFile = BfIRMDNode(); mCurMethodState->mCurScope->mAltDIScope = BfIRMDNode(); - } + } } auto inlineAt = mCurMethodState->mCurScope->mDIInlinedAt; if (mCurMethodState->mCrossingMixin) inlineAt = BfIRMDNode(); - if ((!useDIScope) && (mIsComptimeModule)) + if ((!useDIScope) && (mIsComptimeModule)) useDIScope = wantDIFile; if (!useDIScope) @@ -2717,7 +2762,7 @@ void BfModule::SetIllegalSrcPos(BfSrcPosFlags flags) { if ((mBfIRBuilder->DbgHasInfo()) && (mCurMethodState != NULL)) { - auto curScope = mCurMethodState->mCurScope->mDIScope; + auto curScope = mCurMethodState->mCurScope->mDIScope; if (curScope) { if ((mCurMethodState->mCurScope->mDIInlinedAt) && (mCompiler->mOptions.IsCodeView())) @@ -2727,7 +2772,7 @@ void BfModule::SetIllegalSrcPos(BfSrcPosFlags flags) } else { - // Set to whatever it previously was but at column zero, which we will know to be illegal + // Set to whatever it previously was but at column zero, which we will know to be illegal mBfIRBuilder->SetCurrentDebugLocation(mCurFilePosition.mCurLine + 1, 0, curScope, mCurMethodState->mCurScope->mDIInlinedAt); } } @@ -2752,7 +2797,7 @@ bool BfModule::CheckProtection(BfProtection protection, BfTypeDef* checkType, bo if ((mAttributeState != NULL) && (mAttributeState->mCustomAttributes != NULL) && (mAttributeState->mCustomAttributes->Contains(mCompiler->mFriendAttributeTypeDef))) { mAttributeState->mUsed = true; - return true; + return true; } if (((protection == BfProtection_Internal) || (protection == BfProtection_ProtectedInternal)) && (checkType != NULL)) { @@ -2779,7 +2824,7 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me return false; if (memberProtection == BfProtection_Public) return true; - + if ((flags & BfProtectionCheckFlag_CheckedPrivate) == 0) { BfTypeInstance* curCheckType = mCurTypeInstance; @@ -2888,7 +2933,7 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me if (((memberProtection == BfProtection_Internal) || (memberProtection == BfProtection_ProtectedInternal)) && (memberOwner != NULL)) { if (CheckInternalProtection(memberOwner->mTypeDef)) - return true; + return true; } return false; @@ -2896,7 +2941,7 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me void BfModule::SetElementType(BfAstNode* astNode, BfSourceElementType elementType) { - if (mCompiler->mResolvePassData != NULL) + if (mCompiler->mResolvePassData != NULL) { if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(astNode)) sourceClassifier->SetElementType(astNode, elementType); @@ -2916,8 +2961,8 @@ void BfModule::SetFail() if (mIgnoreErrors) { if (mAttributeState != NULL) - mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError); - } + mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError); + } } void BfModule::VerifyOnDemandMethods() @@ -2929,7 +2974,7 @@ void BfModule::VerifyOnDemandMethods() // mParentModule->VerifyOnDemandMethods(); // return; // } -// +// // int onDemandCount = 0; // for (auto type : mOwnedTypeInstances) // { @@ -2943,7 +2988,7 @@ void BfModule::VerifyOnDemandMethods() // onDemandCount++; // } // } -// +// // BF_ASSERT(mOnDemandMethodCount == onDemandCount); #endif } @@ -3062,7 +3107,7 @@ bool BfModule::AddErrorContext(StringImpl& errorString, BfAstNode* refNode, BfWh errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str()); isWhileSpecializing = (BfWhileSpecializingFlags)(isWhileSpecializing | BfWhileSpecializingFlag_Type); } - + return true; } @@ -3071,8 +3116,8 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers BP_ZONE("BfModule::Fail"); if (mIgnoreErrors) - { - mHadIgnoredError = true; + { + mHadIgnoredError = true; if (mAttributeState != NULL) mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError); return NULL; @@ -3102,7 +3147,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers if ((mCompiler->mCeMachine->mCurContext != NULL) && (mCompiler->mCeMachine->mCurContext->mCurCallSource != NULL) && (mCompiler->mCeMachine->mCurContext->mCurCallSource->mRefNode != NULL)) { - BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", + BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCeMachine->mCurContext->mCurCallSource->mRefNode); if (bfError != NULL) mCompiler->mPassInstance->MoreInfo(error, refNode); @@ -3113,6 +3158,12 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers } } + if ((mCurMethodState != NULL) && (mCurMethodState->mConstResolveState != NULL) && (mCurMethodState->mConstResolveState->mInCalcAppend)) + { + mCurMethodState->mConstResolveState->mFailed = true; + return NULL; + } + if (mCurMethodInstance != NULL) mCurMethodInstance->mHasFailed = true; @@ -3130,12 +3181,12 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers AddFailType(mCurTypeInstance); BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str()); - - String errorString = error; + + String errorString = error; BfWhileSpecializingFlags isWhileSpecializing = BfWhileSpecializingFlag_None; if (!AddErrorContext(errorString, refNode, isWhileSpecializing, false)) return NULL; - + BfError* bfError = NULL; if (isWhileSpecializing) deferError = true; @@ -3156,13 +3207,13 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers bfError = mCompiler->mPassInstance->DeferFail(mixinErr, rootMixinState->mSource); else bfError = mCompiler->mPassInstance->Fail(mixinErr, rootMixinState->mSource); - + if (bfError == NULL) return NULL; - + bfError->mIsWhileSpecializing = isWhileSpecializing; mCompiler->mPassInstance->MoreInfo(errorString, refNode); - + auto mixinState = checkMethodState->mMixinState; while ((mixinState != NULL) && (mixinState->mPrevMixinState != NULL)) { @@ -3176,18 +3227,18 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers checkMethodState = checkMethodState->mPrevMethodState; } } - + if (deferError) - bfError = mCompiler->mPassInstance->Fail(errorString, refNode); - else if (refNode == NULL) - bfError = mCompiler->mPassInstance->Fail(errorString); - else - bfError = mCompiler->mPassInstance->Fail(errorString, refNode); + bfError = mCompiler->mPassInstance->Fail(errorString, refNode); + else if (refNode == NULL) + bfError = mCompiler->mPassInstance->Fail(errorString); + else + bfError = mCompiler->mPassInstance->Fail(errorString, refNode); if (bfError != NULL) { bfError->mIsWhileSpecializing = isWhileSpecializing; bfError->mProject = mProject; - bfError->mIsPersistent = isPersistent; + bfError->mIsPersistent = isPersistent; if ((mCurMethodState != NULL) && (mCurMethodState->mDeferredCallEmitState != NULL) && (mCurMethodState->mDeferredCallEmitState->mCloseNode != NULL)) mCompiler->mPassInstance->MoreInfo("Error during deferred statement handling", mCurMethodState->mDeferredCallEmitState->mCloseNode); @@ -3214,7 +3265,7 @@ BfError* BfModule::FailAfter(const StringImpl& error, BfAstNode* refNode) if (refNode != NULL) refNode = BfNodeToNonTemporary(refNode); - mHadBuildError = true; + mHadBuildError = true; BfError* bfError = mCompiler->mPassInstance->FailAfter(error, refNode); if (bfError != NULL) bfError->mProject = mProject; @@ -3243,19 +3294,19 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re unwarnNode = parentNodeEntry->mNode; parentNodeEntry = parentNodeEntry->mPrev; } - } + } auto parser = unwarnNode->GetSourceData()->ToParserData(); if ((parser != NULL) && (parser->IsUnwarnedAt(unwarnNode))) - { + { return NULL; } - + // Right now we're only warning on the unspecialized declarations, we may revisit this if (mCurMethodInstance != NULL) { if (mCurMethodInstance->IsSpecializedGenericMethodOrType()) { - if (!showInSpecialized) + if (!showInSpecialized) return NULL; } if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend) @@ -3263,7 +3314,7 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re } if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType())) { - if (!showInSpecialized) + if (!showInSpecialized) return NULL; } @@ -3315,10 +3366,10 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re if (warningNum != 0) { - mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("#pragma warning disable %d\t.pragma|%s|%d||#pragma warning disable %d", + mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", StrFormat("#pragma warning disable %d\t.pragma|%s|%d||#pragma warning disable %d", warningNum, parser->mFileName.c_str(), 0, warningNum).c_str())); } - } + } } } return bfError; @@ -3339,7 +3390,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan methodInstance->mMethodDef->GetRefNode()); } else - { + { mCompiler->mPassInstance->MoreInfo( StrFormat("See type declaration '%s'", TypeToString(typeInstance, BfTypeNameFlag_UseUnspecializedGenericParamNames).c_str()), typeInstance->mTypeDef->GetRefNode()); @@ -3425,8 +3476,6 @@ void BfModule::CheckRangeError(BfType* type, BfAstNode* refNode) Fail(StrFormat("Result out of range for type '%s'", TypeToString(type).c_str()), refNode); } - - void BfModule::FatalError(const StringImpl& error, const char* file, int line) { static bool sHadFatalError = false; @@ -3445,15 +3494,15 @@ void BfModule::FatalError(const StringImpl& error, const char* file, int line) fullError += StrFormat(" at %s:%d", file, line); fullError += StrFormat("\nModule: %s", mModuleName.c_str()); - + if (mCurTypeInstance != NULL) fullError += StrFormat("\nType: %s", TypeToString(mCurTypeInstance).c_str()); if (mCurMethodInstance != NULL) fullError += StrFormat("\nMethod: %s", MethodToString(mCurMethodInstance).c_str()); - if ((mCurFilePosition.mFileInstance != NULL) && (mCurFilePosition.mFileInstance->mParser != NULL)) - fullError += StrFormat("\nSource Location: %s:%d", mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), mCurFilePosition.mCurLine + 1); - + if ((mCurFilePosition.mFileInstance != NULL) && (mCurFilePosition.mFileInstance->mParser != NULL)) + fullError += StrFormat("\nSource Location: %s:%d", mCurFilePosition.mFileInstance->mParser->mFileName.c_str(), mCurFilePosition.mCurLine + 1); + if (sHadReentrancy) fullError += "\nError had reentrancy"; @@ -3492,7 +3541,7 @@ bool BfModule::CheckDefineMemberProtection(BfProtection protection, BfType* memb { auto underlyingType = memberType->GetUnderlyingType(); if (underlyingType != NULL) - return CheckDefineMemberProtection(protection, underlyingType); + return CheckDefineMemberProtection(protection, underlyingType); return true; } @@ -3516,7 +3565,7 @@ bool BfModule::CheckDefineMemberProtection(BfProtection protection, BfType* memb void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyFlags flags, BfDepContext* depContext) { if (usedType == userType) - return; + return; if (((flags & BfDependencyMap::DependencyFlag_ConstValue) != 0) && (mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_FieldType)) { @@ -3528,7 +3577,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap { if (userType->IsMethodRef()) { - // We cannot short-circuit dependencies because of method group ref counting + // We cannot short-circuit dependencies because of method group ref counting } else return; @@ -3571,7 +3620,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap if ((mCurMethodState != NULL) && (mCurMethodState->mHotDataReferenceBuilder != NULL) && (usedType != mCurTypeInstance) && (isDataAccess)) { bool addType = true; - auto checkType = usedType; + auto checkType = usedType; PopulateType(checkType, BfPopulateType_Data); if (checkType->IsValuelessType()) addType = false; @@ -3590,7 +3639,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap addType = false; } } - + if (addType) { auto checkTypeInst = checkType->ToTypeInstance(); @@ -3618,7 +3667,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap if ((!mCompiler->mIsResolveOnly) && (mIsReified)) { - auto usingModule = userType->GetModule(); + auto usingModule = userType->GetModule(); BfModule* usedModule; if (usedType->IsFunction()) { @@ -3644,7 +3693,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap } } } - + if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (flags != BfDependencyMap::DependencyFlag_MethodGenericArg)) { // When we are specializing a method, usage of that specialized type is already handled with DependencyFlag_MethodGenericArg @@ -3660,7 +3709,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap { // Cause a rebuild but not an outright deletion of the type // We can only do this if the 'usedType' can actually hold the dependency which can actually trigger a deletion chain - depFlag = BfDependencyMap::DependencyFlag_GenericArgRef; + depFlag = BfDependencyMap::DependencyFlag_GenericArgRef; } } @@ -3680,7 +3729,7 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap } AddDependency(underlyingType, userType, depFlag); - } + } } else if (!usedType->IsGenericTypeInstance()) { @@ -3752,7 +3801,7 @@ void BfModule::AddCallDependency(BfMethodInstance* methodInstance, bool devirtua if (devirtualized) mCurMethodState->mHotDataReferenceBuilder->mDevirtualizedCalledMethods.Add(methodInstance->mHotMethod); else - mCurMethodState->mHotDataReferenceBuilder->mCalledMethods.Add(methodInstance->mHotMethod); + mCurMethodState->mHotDataReferenceBuilder->mCalledMethods.Add(methodInstance->mHotMethod); } } @@ -3781,7 +3830,7 @@ void BfModule::PopulateGlobalContainersList(const BfGlobalLookup& globalLookup) userTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; if (userTypeDef == NULL) userTypeDef = mCurTypeInstance->mTypeDef; - + if (mContext->mCurTypeState->mGlobalContainerCurUserTypeDef != userTypeDef) { mContext->mCurTypeState->mGlobalContainers.Clear(); @@ -3875,14 +3924,14 @@ bool BfModule::CheckInternalProtection(BfTypeDef* usingTypeDef) { if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType())) return true; - if ((mCurMethodInstance != NULL) && + if ((mCurMethodInstance != NULL) && ((mCurMethodInstance->mIsUnspecializedVariation) || (mCurMethodInstance->IsSpecializedGenericMethod()))) return true; auto internalAccessSet = GetInternalAccessSet(); if (internalAccessSet == NULL) return false; - + for (auto& nameComposite : internalAccessSet->mNamespaces) { if (usingTypeDef->mNamespace.StartsWith(nameComposite)) @@ -3915,9 +3964,9 @@ BfModuleOptions BfModule::GetModuleOptions() moduleOptions.mEmitDebugInfo = mCompiler->mOptions.mEmitDebugInfo ? 1 : mCompiler->mOptions.mEmitLineInfo ? 2 : 0; if (mProject != NULL) { - moduleOptions.mSIMDSetting = mProject->mCodeGenOptions.mSIMDSetting; - moduleOptions.mOptLevel = mProject->mCodeGenOptions.mOptLevel; - } + moduleOptions.mSIMDSetting = mProject->mCodeGenOptions.mSIMDSetting; + moduleOptions.mOptLevel = mProject->mCodeGenOptions.mOptLevel; + } auto headModule = this; while (headModule->mParentModule != NULL) @@ -3934,7 +3983,7 @@ BfModuleOptions BfModule::GetModuleOptions() { auto typeOptions = mSystem->GetTypeOptions(typeInst->mTypeOptionsIdx); moduleOptions.mSIMDSetting = (BfSIMDSetting)BfTypeOptions::Apply((int)moduleOptions.mSIMDSetting, typeOptions->mSIMDSetting); - moduleOptions.mEmitDebugInfo = BfTypeOptions::Apply(moduleOptions.mEmitDebugInfo, typeOptions->mEmitDebugInfo); + moduleOptions.mEmitDebugInfo = BfTypeOptions::Apply(moduleOptions.mEmitDebugInfo, typeOptions->mEmitDebugInfo); moduleOptions.mOptLevel = (BfOptLevel)BfTypeOptions::Apply((int)moduleOptions.mOptLevel, (int)typeOptions->mOptimizationLevel); } } @@ -3958,7 +4007,7 @@ void BfModule::AddFailType(BfTypeInstance* typeInstance) if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_InFailTypes) != 0) return; typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_InFailTypes); - mContext->mFailTypes.Add(typeInstance); + mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal); } void BfModule::DeferRebuildType(BfTypeInstance* typeInstance) @@ -3987,7 +4036,7 @@ void BfModule::CheckAddFailType() // constantly warning-aware if ((mHadBuildError) || (mHadBuildWarning /*&& !mCompiler->mIsResolveOnly*/)) - { + { //mContext->mFailTypes.Add(mCurTypeInstance); } } @@ -3998,12 +4047,12 @@ void BfModule::MarkDerivedDirty(BfTypeInstance* typeInst) return; typeInst->mDirty = true; - + for (auto& dep : typeInst->mDependencyMap) { auto depType = dep.mKey; auto depFlags = dep.mValue.mFlags; - + if ((depFlags & BfDependencyMap::DependencyFlag_DerivedFrom) != 0) { MarkDerivedDirty(depType->ToTypeInstance()); @@ -4012,18 +4061,18 @@ void BfModule::MarkDerivedDirty(BfTypeInstance* typeInst) } void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal) -{ +{ auto fieldType = fieldInstance->GetResolvedType(); auto field = fieldInstance->GetFieldDef(); if (fieldType->IsVar()) return; - + BfIRValue initValue; if (field->mIsConst) { if (fieldType->IsPointer()) - fieldType = fieldType->GetUnderlyingType(); + fieldType = fieldType->GetUnderlyingType(); } BfIRStorageKind storageKind = BfIRStorageKind_Normal; @@ -4034,41 +4083,51 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo if ((!field->mIsExtern) && (storageKind != BfIRStorageKind_Import)) initValue = GetDefaultValue(fieldType); - + if (fieldInstance->mOwner->IsUnspecializedType()) { // Placeholder auto ptrVal = CreatePointerType(fieldType); mStaticFieldRefs[fieldInstance] = GetDefaultValue(ptrVal); } - else + else { BfLogSysM("Creating static field Module:%p Type:%p\n", this, fieldType); StringT<4096> staticVarName; BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance); if ((!fieldType->IsValuelessType()) && (!staticVarName.StartsWith("#"))) { - BfIRValue globalVar = mBfIRBuilder->CreateGlobalVariable( - mBfIRBuilder->MapType(fieldType, BfIRPopulateType_Eventually_Full), + BfIRType irType; + + if (fieldInstance->IsAppendedObject()) + { + irType = mBfIRBuilder->MapTypeInst(fieldType->ToTypeInstance(), BfIRPopulateType_Eventually_Full); + initValue = mBfIRBuilder->CreateConstAggZero(irType); + } + else + irType = mBfIRBuilder->MapType(fieldType, BfIRPopulateType_Eventually_Full); + + BfIRValue globalVar = mBfIRBuilder->CreateGlobalVariable( + irType, false, BfIRLinkageType_External, initValue, - staticVarName, + staticVarName, isThreadLocal); - mBfIRBuilder->GlobalVar_SetAlignment(globalVar, fieldType->mAlign); + mBfIRBuilder->GlobalVar_SetAlignment(globalVar, fieldType->mAlign); if (storageKind != BfIRStorageKind_Normal) mBfIRBuilder->GlobalVar_SetStorageKind(globalVar, storageKind); BF_ASSERT(globalVar); - mStaticFieldRefs[fieldInstance] = globalVar; + mStaticFieldRefs[fieldInstance] = globalVar; } - } + } } void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* fieldDef, bool forceResolve) { bool autoCompleteOnly = mCompiler->IsAutocomplete(); - + BfType* fieldType = NULL; if (fieldInstance != NULL) { @@ -4098,8 +4157,8 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* } if ((fieldInstance != NULL) && (fieldInstance->mConstIdx != -1) && (!forceResolve)) - return; - + return; + if (mContext->mFieldResolveReentrys.size() > 1) { if (mContext->mFieldResolveReentrys.IndexOf(fieldInstance, 1) != -1) @@ -4118,18 +4177,17 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* } } - - mContext->mFieldResolveReentrys.push_back(fieldInstance); + mContext->mFieldResolveReentrys.push_back(fieldInstance); AutoPopBackmFieldResolveReentrys)> popTypeResolveReentry(&mContext->mFieldResolveReentrys); if (fieldInstance == NULL) popTypeResolveReentry.Pop(); - + auto typeDef = typeInstance->mTypeDef; BfIRValue constValue; if (fieldDef->mIsExtern) - { + { if (!fieldDef->mTypeRef->IsA()) { SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); @@ -4184,12 +4242,12 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* } } else if (mBfIRBuilder != NULL) - { + { SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); - + BfMethodState methodState; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); methodState.mTempKind = BfMethodState::TempKind_Static; @@ -4259,7 +4317,7 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance* } BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfFieldDef* field) -{ +{ bool isDeclType = (field->mFieldDeclaration != NULL) && BfNodeDynCastExact(field->mTypeRef) != NULL; auto fieldType = fieldInstance->GetResolvedType(); @@ -4270,12 +4328,12 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta } bool staticOnly = (field->mIsStatic) && (!isDeclType); - + if (!fieldInstance->mIsInferredType) return fieldType; if ((!fieldType->IsVar()) && (!fieldType->IsUndefSizedArray())) - return fieldType; - + return fieldType; + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); @@ -4285,13 +4343,13 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta if ((!field->mIsStatic) && (typeDef->mIsStatic)) { - AssertErrorState(); + AssertErrorState(); return fieldType; } - + bool hadInferenceCycle = false; if (mContext->mFieldResolveReentrys.size() > 1) - { + { if (mContext->mFieldResolveReentrys.IndexOf(fieldInstance, 1) != -1) { for (int i = 1; i < (int)mContext->mFieldResolveReentrys.size(); i++) @@ -4302,28 +4360,28 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta auto fieldModule = fieldOwner->mModule; SetAndRestoreValue prevIgnoreError(fieldModule->mIgnoreErrors, false); - fieldModule->Fail(StrFormat("Field '%s.%s' creates a type inference cycle", TypeToString(fieldOwner).c_str(), fieldDef->mName.c_str()), fieldDef->mTypeRef, true); + fieldModule->Fail(StrFormat("Field '%s.%s' creates a type inference cycle", TypeToString(fieldOwner).c_str(), fieldDef->mName.c_str()), fieldDef->mTypeRef, true); } - + return fieldType; } } mContext->mFieldResolveReentrys.push_back(fieldInstance); AutoPopBackmFieldResolveReentrys)> popTypeResolveReentry(&mContext->mFieldResolveReentrys); - SetAndRestoreValue prevResolvingVar(typeInstance->mResolvingVarField, true); - SetAndRestoreValue prevCtxResolvingVar(mContext->mResolvingVarField, true); - + SetAndRestoreValue prevResolvingVar(typeInstance->mResolvingVarField, true); + SetAndRestoreValue prevCtxResolvingVar(mContext->mResolvingVarField, true); + if ((field->GetInitializer() == NULL) && (!isDeclType)) { if ((field->mTypeRef->IsA()) || (field->mTypeRef->IsA())) - Fail("Implicitly-typed fields must be initialized", field->GetRefNode()); + Fail("Implicitly-typed fields must be initialized", field->GetRefNode()); return fieldType; } BfType* resolvedType = NULL; if (!hadInferenceCycle) - { + { BfTypeState typeState; typeState.mPrevState = mContext->mCurTypeState; typeState.mType = typeInstance; @@ -4331,9 +4389,9 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta typeState.mResolveKind = BfTypeState::ResolveKind_ResolvingVarType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - SetAndRestoreValue prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true); + SetAndRestoreValue prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL/*ctorMethod.mMethodInstance*/); - + auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); BfMethodState methodState; @@ -4341,14 +4399,14 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta methodState.mTempKind = staticOnly ? BfMethodState::TempKind_Static : BfMethodState::TempKind_NonStatic; if (!staticOnly) { - //BfLocalVariable localVar; + //BfLocalVariable localVar; //methodState.mLocals.push_back(localVar); } - + if (isDeclType) { auto fieldDef = fieldInstance->GetFieldDef(); - resolvedType = ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity); + resolvedType = ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity); } else { @@ -4370,22 +4428,20 @@ BfType* BfModule::ResolveVarFieldType(BfTypeInstance* typeInstance, BfFieldInsta if (resolvedType == NULL) return fieldType; - + fieldInstance->SetResolvedType(resolvedType); if (field->mIsStatic) { - } else if (fieldInstance->mDataIdx >= 0) { - } else { BF_ASSERT(typeInstance->IsIncomplete()); } - + return resolvedType; } @@ -4404,7 +4460,7 @@ void BfModule::MarkFieldInitialized(BfFieldInstance* fieldInstance) int count = fieldCount; if (fieldIdx == -1) count = 1; - + //TODO: Under what circumstances could 'thisVariable' be NULL? auto thisVariable = GetThisVariable(); if (thisVariable != NULL) @@ -4429,14 +4485,14 @@ bool BfModule::IsThreadLocal(BfFieldInstance * fieldInstance) for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes) { if (customAttr.mType->ToTypeInstance()->IsInstanceOf(mCompiler->mThreadStaticAttributeTypeDef)) - return true; + return true; } } return false; } BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer, BfFieldDef* fieldDef, BfType* fieldType, bool doStore) -{ +{ if (fieldDef == NULL) fieldDef = fieldInstance->GetFieldDef(); if (fieldType == NULL) @@ -4482,13 +4538,13 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, int ceExecuteId = -1; if (mCompiler->mCeMachine != NULL) ceExecuteId = mCompiler->mCeMachine->mExecuteId; - - BfTypeState typeState; + + BfTypeState typeState; typeState.mType = mCurTypeInstance; typeState.mCurTypeDef = fieldDef->mDeclaringType; typeState.mCurFieldDef = fieldDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - + BfConstResolver constResolver(this); if (fieldType->IsVar()) return constResolver.Resolve(initializer); @@ -4510,9 +4566,9 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, fieldInstance->mHadConstEval = true; } return result; - } + } } - + BfExprEvaluator exprEvaluator(this); if (doStore) { @@ -4532,7 +4588,7 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, if (fieldInstance != NULL) MarkFieldInitialized(fieldInstance); - + if ((doStore) && (result)) { if (fieldInstance->mResolvedType->IsUndefSizedArray()) @@ -4551,9 +4607,87 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, return result; } +void BfModule::AppendedObjectInit(BfFieldInstance* fieldInst) +{ + BfExprEvaluator exprEvaluator(this); + + bool failed = false; + + auto fieldDef = fieldInst->GetFieldDef(); + auto initializer = fieldDef->GetInitializer(); + + BfResolvedArgs resolvedArgs; + if (auto invocationExpr = BfNodeDynCast(initializer)) + { + bool isDot = false; + + if (auto memberRefExpr = BfNodeDynCast(invocationExpr->mTarget)) + isDot = (memberRefExpr->mTarget == NULL) && (memberRefExpr->mMemberName == NULL); + + if (!isDot) + { + auto resolvedType = ResolveTypeRef(invocationExpr->mTarget, {}); + if ((resolvedType == NULL) || (resolvedType != fieldInst->mResolvedType)) + failed = true; + } + + SetAndRestoreValue prevExpectingType(exprEvaluator.mExpectingType, fieldInst->mResolvedType); + + resolvedArgs.Init(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen); + exprEvaluator.ResolveArgValues(resolvedArgs, BfResolveArgsFlag_DeferParamEval); + } + else if (initializer != NULL) + { + GetFieldInitializerValue(fieldInst); + failed = true; + } + + if (failed) + Fail("Append fields can only be initialized with a call to their constructor", initializer); + + auto intType = GetPrimitiveType(BfTypeCode_IntPtr); + auto int8Type = mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8); + auto ptrType = mBfIRBuilder->GetPointerTo(int8Type); + auto ptrPtrType = mBfIRBuilder->GetPointerTo(ptrType); + + auto fieldTypeInst = fieldInst->mResolvedType->ToTypeInstance(); + + BfIRValue fieldAddr; + if (fieldDef->mIsStatic) + { + fieldAddr = ReferenceStaticField(fieldInst).mValue; + } + else + fieldAddr = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, fieldInst->mDataIdx); + auto thisValue = BfTypedValue(mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(fieldInst->mResolvedType)), fieldInst->mResolvedType); + + auto indexVal = BfTypedValue(CreateAlloca(intType), CreateRefType(intType)); + auto intThisVal = mBfIRBuilder->CreatePtrToInt(thisValue.mValue, (intType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64); + auto curValPtr = mBfIRBuilder->CreateAdd(intThisVal, GetConstValue(fieldTypeInst->mInstSize, intType)); + mBfIRBuilder->CreateStore(curValPtr, indexVal.mValue); + + auto vObjectAddr = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, 0); + + auto vDataRef = CreateClassVDataGlobal(fieldInst->mResolvedType->ToTypeInstance()); + + auto destAddr = mBfIRBuilder->CreateBitCast(vObjectAddr, ptrPtrType); + auto srcVal = mBfIRBuilder->CreateBitCast(vDataRef, ptrType); + mBfIRBuilder->CreateStore(srcVal, destAddr); + + if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) + { + auto int8Type = mBfIRBuilder->GetPrimitiveType(BfTypeCode_Int8); + auto ptrType = mBfIRBuilder->GetPointerTo(int8Type); + + auto thisFlagsPtr = mBfIRBuilder->CreateBitCast(thisValue.mValue, ptrType); + mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_AppendAlloc), thisFlagsPtr); + } + + exprEvaluator.MatchConstructor(fieldDef->GetNameNode(), NULL, thisValue, fieldInst->mResolvedType->ToTypeInstance(), resolvedArgs, false, true, &indexVal); +} + void BfModule::CheckInterfaceMethod(BfMethodInstance* methodInstance) -{ - +{ } void BfModule::FindSubTypes(BfTypeInstance* classType, SizedArrayImpl* outVals, SizedArrayImpl* exChecks, bool isInterfacePass) @@ -4568,7 +4702,7 @@ void BfModule::FindSubTypes(BfTypeInstance* classType, SizedArrayImpl* outV continue; if (outVals->Contains(ifaceInst.mInterfaceType->mTypeId)) continue; - + if (ifaceInst.mDeclaringType->IsExtension()) { bool needsExCheck = false; @@ -4585,14 +4719,14 @@ void BfModule::FindSubTypes(BfTypeInstance* classType, SizedArrayImpl* outV // We can only do an 'exCheck' if we're actually going to slot this interface } } - } + } outVals->push_back(ifaceInst.mInterfaceType->mTypeId); } } else { - outVals->push_back(classType->mTypeId); + outVals->push_back(classType->mTypeId); } if (classType->mBaseType != NULL) @@ -4609,18 +4743,18 @@ void BfModule::CreateDynamicCastMethod() { // The main reason to punt on this method for ResolveOnly is because types can be created // and destroyed quickly during autocomplete and the typeId creep can generate lots of - // entries in the LLVM ConstantInt pool, primarily from the FindSubTypes call. We can + // entries in the LLVM ConstantInt pool, primarily from the FindSubTypes call. We can // remove this punt when we recycle typeId's mBfIRBuilder->CreateRet(mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapTypeInstPtr(objType))); - mCurMethodState->mHadReturn = true; + mCurMethodState->mHadReturn = true; return; } bool isInterfacePass = mCurMethodInstance->mMethodDef->mName == BF_METHODNAME_DYNAMICCAST_INTERFACE; - - auto func = mCurMethodState->mIRFunction; - auto thisValue = mBfIRBuilder->GetArgument(0); - auto typeIdValue = mBfIRBuilder->GetArgument(1); + + auto func = mCurMethodState->mIRFunction; + auto thisValue = mBfIRBuilder->GetArgument(0); + auto typeIdValue = mBfIRBuilder->GetArgument(1); auto intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); auto int32Type = GetPrimitiveType(BfTypeCode_Int32); @@ -4631,7 +4765,7 @@ void BfModule::CreateDynamicCastMethod() auto trueBB = mBfIRBuilder->CreateBlock("check.true"); //auto falseBB = mBfIRBuilder->CreateBlock("check.false"); auto exitBB = mBfIRBuilder->CreateBlock("exit"); - + SizedArray typeMatches; SizedArray exChecks; FindSubTypes(mCurTypeInstance, &typeMatches, &exChecks, isInterfacePass); @@ -4651,7 +4785,7 @@ void BfModule::CreateDynamicCastMethod() { BfBoxedType* boxedType = (BfBoxedType*)mCurTypeInstance; BfTypeInstance* innerType = boxedType->mElementType->ToTypeInstance(); - + FindSubTypes(innerType, &typeMatches, &exChecks, isInterfacePass); if (innerType->IsTypedPrimitive()) @@ -4685,27 +4819,27 @@ void BfModule::CreateDynamicCastMethod() auto switchStatement = mBfIRBuilder->CreateSwitch(typeIdValue, exitBB, (int)typeMatches.size() + (int)exChecks.size()); for (auto typeMatch : typeMatches) mBfIRBuilder->AddSwitchCase(switchStatement, GetConstValue32(typeMatch), trueBB); - + Array incomingFalses; for (auto ifaceTypeInst : exChecks) - { + { BfIRBlock nextBB = mBfIRBuilder->CreateBlock("exCheck", true); mBfIRBuilder->AddSwitchCase(switchStatement, GetConstValue32(ifaceTypeInst->mTypeId), nextBB); - mBfIRBuilder->SetInsertPoint(nextBB); + mBfIRBuilder->SetInsertPoint(nextBB); BfIRValue slotOfs = GetInterfaceSlotNum(ifaceTypeInst); auto ifacePtrPtr = mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/); - auto ifacePtr = mBfIRBuilder->CreateLoad(ifacePtrPtr); + auto ifacePtr = mBfIRBuilder->CreateLoad(ifacePtrPtr); auto cmpResult = mBfIRBuilder->CreateCmpNE(ifacePtr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0)); - mBfIRBuilder->CreateCondBr(cmpResult, trueBB, exitBB); + mBfIRBuilder->CreateCondBr(cmpResult, trueBB, exitBB); incomingFalses.push_back(nextBB); - } + } - mBfIRBuilder->AddBlock(trueBB); - mBfIRBuilder->SetInsertPoint(trueBB); + mBfIRBuilder->AddBlock(trueBB); + mBfIRBuilder->SetInsertPoint(trueBB); mBfIRBuilder->CreateBr(exitBB); mBfIRBuilder->AddBlock(exitBB); @@ -4715,9 +4849,9 @@ void BfModule::CreateDynamicCastMethod() auto nullValue = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapTypeInstPtr(objType)); for (auto incomingFalseBlock : incomingFalses) mBfIRBuilder->AddPhiIncoming(phi, nullValue, incomingFalseBlock); - mBfIRBuilder->AddPhiIncoming(phi, nullValue, curBlock); + mBfIRBuilder->AddPhiIncoming(phi, nullValue, curBlock); mBfIRBuilder->CreateRet(phi); - mCurMethodState->mHadReturn = true; + mCurMethodState->mHadReturn = true; } void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRBlock exitBB, bool strictEquals) @@ -4725,7 +4859,7 @@ void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRB BfExprEvaluator exprEvaluator(this); exprEvaluator.mExpectingType = mCurMethodInstance->mReturnType; - auto typeInst = rightValue.mType->ToTypeInstance(); + auto typeInst = rightValue.mType->ToTypeInstance(); exprEvaluator.PerformBinaryOperation((BfAstNode*)NULL, (BfAstNode*)NULL, strictEquals ? BfBinaryOp_StrictEquality : BfBinaryOp_Equality, NULL, BfBinOpFlag_IgnoreOperatorWithWrongResult, leftValue, rightValue); BfTypedValue result = exprEvaluator.GetResult(); if (result.mType != GetPrimitiveType(BfTypeCode_Boolean)) @@ -4742,23 +4876,23 @@ void BfModule::EmitEquals(BfTypedValue leftValue, BfTypedValue rightValue, BfIRB } void BfModule::CreateFakeCallerMethod(const String& funcName) -{ +{ if (mCurMethodInstance->mHasFailed) return; if (mCurMethodInstance->mMethodDef->mIsSkipCall) return; BF_ASSERT(mCurMethodInstance->mIRFunction); - + auto voidType = mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_None)); SizedArray paramTypes; BfIRFunctionType funcType = mBfIRBuilder->CreateFunctionType(voidType, paramTypes); - BfIRFunction func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_Internal, "FORCELINK_" + funcName); + BfIRFunction func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_Internal, "FORCELINK_" + funcName); mBfIRBuilder->SetActiveFunction(func); auto entryBlock = mBfIRBuilder->CreateBlock("main", true); mBfIRBuilder->SetInsertPoint(entryBlock); - - BfMethodState methodState; + + BfMethodState methodState; methodState.mIRHeadBlock = entryBlock; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); @@ -4767,7 +4901,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName) if (mCurMethodInstance->GetStructRetIdx() == 0) { - auto retPtrType = CreatePointerType(mCurMethodInstance->mReturnType); + auto retPtrType = CreatePointerType(mCurMethodInstance->mReturnType); exprEvaluator.PushArg(GetDefaultTypedValue(retPtrType, true, BfDefaultValueKind_Const), args); } @@ -4787,7 +4921,7 @@ void BfModule::CreateFakeCallerMethod(const String& funcName) { auto paramType = mCurMethodInstance->GetParamType(paramIdx); if (paramType->IsValuelessType()) - continue; + continue; exprEvaluator.PushArg(GetDefaultTypedValue(paramType, true, paramType->IsComposite() ? BfDefaultValueKind_Addr : BfDefaultValueKind_Const), args); } @@ -4822,7 +4956,7 @@ void BfModule::CreateDelegateEqualsMethod() BfTypedValue rhsDelegate = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); rhsDelegate = LoadValue(rhsDelegate); BfTypedValue rightTypedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(rhsDelegate.mValue, mBfIRBuilder->MapType(mCurTypeInstance)), mCurTypeInstance); - + auto& targetFieldInstance = delegateType->mFieldInstances[0]; BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(lhsDelegate.mValue, 0, targetFieldInstance.mDataIdx), targetFieldInstance.mResolvedType, true); @@ -4840,15 +4974,15 @@ void BfModule::CreateDelegateEqualsMethod() auto fieldType = fieldInstance->mResolvedType; if (fieldType->IsValuelessType()) - continue; + continue; if (fieldType->IsVar()) continue; if (fieldType->IsMethodRef()) continue; - + if (fieldType->IsRef()) fieldType = CreatePointerType(fieldType->GetUnderlyingType()); - + BfTypedValue leftValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(leftTypedVal.mValue, 0, fieldInstance->mDataIdx), fieldType, true); BfTypedValue rightValue = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(rightTypedVal.mValue, 0, fieldInstance->mDataIdx), fieldType, true); @@ -4863,30 +4997,30 @@ void BfModule::CreateDelegateEqualsMethod() mBfIRBuilder->CreateStore(GetConstValue(1, boolType), resultVal); mBfIRBuilder->CreateBr(exitBB); - + mBfIRBuilder->AddBlock(exitBB); mBfIRBuilder->SetInsertPoint(exitBB); - + auto loadedResult = mBfIRBuilder->CreateLoad(resultVal); ClearLifetimeEnds(); mBfIRBuilder->CreateRet(loadedResult); - mCurMethodState->mHadReturn = true; + mCurMethodState->mHadReturn = true; } void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) -{ +{ if (mCurMethodInstance->mIsUnspecialized) return; - + if (mBfIRBuilder->mIgnoreWrites) return; - + BF_ASSERT(!mCurTypeInstance->IsBoxed()); - auto compareType = mCurMethodInstance->mParams[0].mResolvedType; + auto compareType = mCurMethodInstance->mParams[0].mResolvedType; bool isValid = true; auto boolType = GetPrimitiveType(BfTypeCode_Boolean); @@ -4895,7 +5029,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) mBfIRBuilder->CreateRet(GetDefaultValue(boolType)); return; } - + if (compareType->IsTypedPrimitive()) { BfExprEvaluator exprEvaluator(this); @@ -4909,7 +5043,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) auto compareDType = compareType->ToDependedType(); BfTypeInstance* compareTypeInst = compareType->ToTypeInstance(); if (compareTypeInst != NULL) - { + { if (compareType->IsPrimitiveType()) compareTypeInst = GetWrappedStructType(compareType); if ((compareTypeInst == NULL) || (!compareTypeInst->IsValueType())) @@ -4918,7 +5052,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) } mBfIRBuilder->PopulateType(compareTypeInst); } - + if (!isValid) { ClearLifetimeEnds(); @@ -4931,7 +5065,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) auto refNode = mCurTypeInstance->mTypeDef->GetRefNode(); if (refNode == NULL) refNode = mCompiler->mValueTypeTypeDef->GetRefNode(); - UpdateSrcPos(refNode); + UpdateSrcPos(refNode); SetIllegalSrcPos(); auto resultVal = CreateAlloca(boolType); @@ -4946,7 +5080,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) else if (compareType->IsSizedArray()) { auto sizedArrayType = (BfSizedArrayType*)compareType; - + auto _SizedIndex = [&](BfIRValue target, BfIRValue index) { BfTypedValue result; @@ -4989,9 +5123,9 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) else { for (int dataIdx = 0; dataIdx < sizedArrayType->mElementCount; dataIdx++) - { + { BfTypedValue leftValue = _SizedIndex(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataIdx)); - BfTypedValue rightValue = _SizedIndex(mCurMethodState->mLocals[1]->mValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataIdx)); + BfTypedValue rightValue = _SizedIndex(mCurMethodState->mLocals[1]->mValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataIdx)); EmitEquals(leftValue, rightValue, exitBB, strictEquals); } } @@ -5008,8 +5142,8 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) // We only need to compare the 'this' capture. The rationale is that it's impossible to capture any other non-matching // values for the same method reference -- they will always refer back to the same local variables. int dataIdx = methodRefType->GetDataIdxFromParamIdx(-1); - if (dataIdx != -1) - { + if (dataIdx != -1) + { bool failed = false; BfTypedValue leftValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, leftTypedVal); BfTypedValue rightValue = exprEvaluator.DoImplicitArgCapture(NULL, methodInstance, methodRefType->GetParamIdxFromDataIdx(dataIdx), failed, BfImplicitParamKind_General, rightTypedVal); @@ -5026,7 +5160,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) BfTypedValue rightTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); auto dscrType = compareTypeInst->GetDiscriminatorType(); - + BfTypedValue leftValue = ExtractValue(leftTypedVal, NULL, 2); leftValue = LoadValue(leftValue); BfTypedValue rightValue = ExtractValue(rightTypedVal, NULL, 2); @@ -5036,7 +5170,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) BfTypedValue rightPayload = ExtractValue(rightTypedVal, NULL, 1); EmitEquals(leftValue, rightValue, exitBB, strictEquals); - + int enumCount = 0; for (auto& fieldRef : compareTypeInst->mFieldInstances) { @@ -5047,7 +5181,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) enumCount = -fieldInstance->mDataIdx; } } - + if (enumCount > 0) { BfIRBlock matchedBlock = mBfIRBuilder->CreateBlock("matched"); @@ -5083,7 +5217,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) leftTuple = Cast(NULL, leftPayload, fieldInstance->mResolvedType, BfCastFlags_Force); rightTuple = Cast(NULL, rightPayload, fieldInstance->mResolvedType, BfCastFlags_Force); } - + EmitEquals(leftTuple, rightTuple, exitBB, strictEquals); mBfIRBuilder->CreateBr(matchedBlock); @@ -5095,7 +5229,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) mBfIRBuilder->AddBlock(matchedBlock); mBfIRBuilder->SetInsertPoint(matchedBlock); } - } + } else if (compareTypeInst->IsUnion()) { auto innerType = compareTypeInst->GetUnionInnerType(); @@ -5115,7 +5249,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) } } else - { + { BfExprEvaluator exprEvaluator(this); BfTypedValue leftTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[0]); BfTypedValue rightTypedVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); @@ -5129,11 +5263,11 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) if (fieldInstance->mResolvedType->IsValuelessType()) continue; - + if (fieldInstance->mResolvedType->IsVar()) continue; - BfTypedValue leftValue = ExtractValue(leftTypedVal, fieldInstance, fieldInstance->mDataIdx); + BfTypedValue leftValue = ExtractValue(leftTypedVal, fieldInstance, fieldInstance->mDataIdx); BfTypedValue rightValue = ExtractValue(rightTypedVal, fieldInstance, fieldInstance->mDataIdx); if (!fieldInstance->mResolvedType->IsComposite()) @@ -5147,7 +5281,7 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) auto baseTypeInst = compareTypeInst->mBaseType; if ((baseTypeInst != NULL) && (baseTypeInst->mTypeDef != mCompiler->mValueTypeTypeDef)) - { + { BfTypedValue leftValue = Cast(NULL, leftTypedVal, baseTypeInst); BfTypedValue rightValue = Cast(NULL, rightTypedVal, baseTypeInst); EmitEquals(leftValue, rightValue, exitBB, strictEquals); @@ -5156,21 +5290,21 @@ void BfModule::CreateValueTypeEqualsMethod(bool strictEquals) mBfIRBuilder->CreateStore(GetConstValue(1, boolType), resultVal); mBfIRBuilder->CreateBr(exitBB); - + mBfIRBuilder->AddBlock(exitBB); mBfIRBuilder->SetInsertPoint(exitBB); - + auto loadedResult = mBfIRBuilder->CreateLoad(resultVal); ClearLifetimeEnds(); mBfIRBuilder->CreateRet(loadedResult); - mCurMethodState->mHadReturn = true; + mCurMethodState->mHadReturn = true; } BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* outNumElements, String* outMangledName) -{ +{ if (mBfIRBuilder->mIgnoreWrites) return mBfIRBuilder->GetFakeVal(); @@ -5182,8 +5316,8 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou { auto idVal = mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, typeInstance->mTypeId); return mBfIRBuilder->CreateIntToPtr(idVal, mBfIRBuilder->MapType(CreatePointerType(classVDataType))); - } - + } + BfIRValue* globalVariablePtr = NULL; mClassVDataRefs.TryGetValue(typeInstance, &globalVariablePtr); @@ -5196,17 +5330,17 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou auto maxIFaceVirtIdx = 0; if (!typeInstance->IsInterface()) - { + { int dynCastDataElems = 1 + mCompiler->mMaxInterfaceSlots; numElements += ((dynCastDataElems * 4) + mSystem->mPtrSize - 1) / mSystem->mPtrSize; - numElements += typeInstance->GetOrigVTableSize(); + numElements += typeInstance->GetOrigVTableSize(); int ifaceMethodLen = typeInstance->GetIFaceVMethodSize(); if (typeInstance->mHotTypeData != NULL) - { + { if (typeInstance->mHotTypeData->mOrigInterfaceMethodsLength != -1) ifaceMethodLen = typeInstance->mHotTypeData->mOrigInterfaceMethodsLength; - } + } numElements += ifaceMethodLen; } @@ -5218,7 +5352,7 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou String memberName = "sBfClassVData"; if ((typeInstance->mHotTypeData != NULL) && ((typeInstance->mHotTypeData->mHadDataChange) || (typeInstance->mHotTypeData->mPendingDataChange))) - { + { auto curVersion = typeInstance->mHotTypeData->GetLatestVersion(); memberName += "_"; memberName += BfTypeUtils::HashEncode64(curVersion->mDataHash.mLow); @@ -5243,14 +5377,14 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou { BfLogSysM("Creating VData %s\n", classVDataName.c_str()); auto arrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr), numElements); - globalVariable = mBfIRBuilder->CreateGlobalVariable( + globalVariable = mBfIRBuilder->CreateGlobalVariable( arrayType, true, BfIRLinkageType_External, BfIRValue(), - classVDataName); + classVDataName); - mClassVDataRefs[typeInstance] = globalVariable; + mClassVDataRefs[typeInstance] = globalVariable; } return globalVariable; } @@ -5264,7 +5398,7 @@ BfIRValue BfModule::GetClassVDataPtr(BfTypeInstance* typeInstance) } BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTypeInstance* implTypeInst, int startVirtIdx) -{ +{ if (mBfIRBuilder->mIgnoreWrites) return mBfIRBuilder->GetFakeVal(); @@ -5280,7 +5414,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy BF_ASSERT(declTypeInst == implTypeInst); else BF_ASSERT(implTypeInst->mInheritDepth > declTypeInst->mInheritDepth); - + if (declTypeInst != implTypeInst) { BfTypeInstance* highestImpl = declTypeInst; @@ -5292,7 +5426,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy auto checkImplTypeInst = implTypeInst->mVirtualMethodTable[virtIdx].mImplementingMethod.mTypeInstance; if ((checkImplTypeInst != NULL) && (checkImplTypeInst->mInheritDepth > highestImpl->mInheritDepth)) - highestImpl = checkImplTypeInst; + highestImpl = checkImplTypeInst; } if (highestImpl != implTypeInst) @@ -5305,7 +5439,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy BfIRValue* irValuePtr = NULL; if (mClassVDataExtRefs.TryGetValue(mapEntry, &irValuePtr)) - return *irValuePtr; + return *irValuePtr; PopulateType(declTypeInst, BfPopulateType_DataAndMethods); PopulateType(implTypeInst, BfPopulateType_DataAndMethods); @@ -5314,8 +5448,8 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy if (declTypeInst != implTypeInst) { classVDataName += StrFormat("_%d", implTypeInst->mInheritDepth - declTypeInst->mInheritDepth); - } - + } + auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); auto voidPtrIRType = mBfIRBuilder->MapType(voidPtrType); @@ -5327,7 +5461,6 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy if (implTypeInst->mVirtualMethodTable[virtIdx].mDeclaringMethod.mMethodNum == -1) break; // Start of an ext entry for another type - BfIRValue vValue; auto& entry = implTypeInst->mVirtualMethodTable[virtIdx]; BfMethodInstance* declaringMethodInstance = (BfMethodInstance*)entry.mDeclaringMethod; @@ -5355,7 +5488,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy auto arrayType = mBfIRBuilder->GetSizedArrayType(mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr), numElements); auto globalVariable = mBfIRBuilder->CreateGlobalVariable(arrayType, true, - BfIRLinkageType_External, BfIRValue(), classVDataName); + BfIRLinkageType_External, BfIRValue(), classVDataName); BfIRType extVTableType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size()); BfIRValue extVTableConst = mBfIRBuilder->CreateConstAgg_Value(extVTableType, vData); @@ -5366,7 +5499,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy } BfIRValue BfModule::CreateTypeDataRef(BfType* type) -{ +{ if (mBfIRBuilder->mIgnoreWrites) { return mBfIRBuilder->CreateTypeOf(type); @@ -5378,18 +5511,18 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type) auto typeTypeInst = typeTypeDef->ToTypeInstance(); return mBfIRBuilder->Comptime_GetReflectType(type->mTypeId, mBfIRBuilder->MapType(typeTypeInst)); } - + PopulateType(type); BfIRValue globalVariable; - + BfIRValue* globalVariablePtr = NULL; if (mTypeDataRefs.TryGetValue(type, &globalVariablePtr)) { if (*globalVariablePtr) return mBfIRBuilder->CreateTypeOf(type, *globalVariablePtr); } - + auto typeTypeDef = ResolveTypeDef(mCompiler->mTypeTypeDef); auto typeTypeInst = typeTypeDef->ToTypeInstance(); auto typeInstance = type->ToTypeInstance(); @@ -5402,11 +5535,11 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type) else { typeDataName += "sBfTypeData."; - BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, this); + BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, this); } BfLogSysM("Creating TypeData %s\n", typeDataName.c_str()); - + globalVariable = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(typeTypeInst, BfIRPopulateType_Full), true, BfIRLinkageType_External, BfIRValue(), typeDataName); mBfIRBuilder->SetReflectTypeData(mBfIRBuilder->MapType(type), globalVariable); @@ -5526,7 +5659,7 @@ void BfModule::EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType else { Fail(StrFormat("Unhandled attribute constant data in '%s'", TypeToString(typeInstance).c_str())); - } + } } BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx) @@ -5535,14 +5668,14 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt BfFieldDef* fieldDef = fieldInstance->GetFieldDef(); auto typeInstance = fieldInstance->mOwner; - + BfType* intType = GetPrimitiveType(BfTypeCode_Int32); BfType* intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); BfType* shortType = GetPrimitiveType(BfTypeCode_Int16); BfType* typeIdType = intType; BfTypeInstance* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef)->ToTypeInstance(); - BfIRValue emptyValueType = mBfIRBuilder->mIgnoreWrites ? + BfIRValue emptyValueType = mBfIRBuilder->mIgnoreWrites ? mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapTypeInst(reflectFieldDataType->mBaseType), SizedArray()) : mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->mBaseType), SizedArray()); BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, !mIsComptimeModule); @@ -5552,7 +5685,7 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt auto fieldType = fieldInstance->GetResolvedType(); if (fieldType->IsGenericParam()) { - //TODO: + //TODO: } else typeId = fieldType->mTypeId; @@ -5570,8 +5703,10 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt if (fieldDef->IsEnumCaseEntry()) fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_EnumCase); if (fieldDef->mIsReadOnly) - fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_ReadOnly); - + fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_ReadOnly); + if (fieldInstance->IsAppendedObject()) + fieldFlags = (BfFieldFlags)(fieldFlags | BfFieldFlags_Appended); + BfIRValue constValue; BfIRValue constValue2; if (fieldInstance->GetFieldDef()->mIsConst) @@ -5608,8 +5743,13 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt } } - if ((refVal.IsAddr()) && (!isComptimeArg)) - constValue = mBfIRBuilder->CreatePtrToInt(refVal.mValue, BfTypeCode_IntPtr); + if (!isComptimeArg) + { + if (refVal.IsAddr()) + constValue = mBfIRBuilder->CreatePtrToInt(refVal.mValue, BfTypeCode_IntPtr); + else if ((fieldInstance->IsAppendedObject()) && (refVal)) + constValue = mBfIRBuilder->CreatePtrToInt(refVal.mValue, BfTypeCode_IntPtr); + } } if (!constValue) @@ -5624,29 +5764,29 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt SizedArray fieldVals = { emptyValueType, - fieldNameConst, // mName - GetConstValue(typeId, typeIdType), // mFieldTypeId + fieldNameConst, // mName + GetConstValue(typeId, typeIdType), // mFieldTypeId constValue, // mData constValue2, // mDataHi GetConstValue(fieldFlags, shortType), // mFlags GetConstValue((isComptimeArg || mIsComptimeModule) ? fieldInstance->mFieldIdx : customAttrIdx, intType), // mCustomAttributesIdx - }; + }; FixConstValueParams(reflectFieldDataType, fieldVals, isComptimeArg); result = isComptimeArg ? mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals) : - mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals); + mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals); } else { SizedArray fieldVals = { emptyValueType, - fieldNameConst, // mName - GetConstValue(typeId, typeIdType), // mFieldTypeId + fieldNameConst, // mName + GetConstValue(typeId, typeIdType), // mFieldTypeId constValue, // mData GetConstValue(fieldFlags, shortType), // mFlags GetConstValue((isComptimeArg || mIsComptimeModule) ? fieldInstance->mFieldIdx : customAttrIdx, intType), // mCustomAttributesIdx - }; + }; FixConstValueParams(reflectFieldDataType, fieldVals, isComptimeArg); result = isComptimeArg ? mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapTypeInst(reflectFieldDataType, BfIRPopulateType_Full), fieldVals) : @@ -5659,14 +5799,14 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData) { if ((IsHotCompile()) && (!type->mDirty)) - return BfIRValue(); + return BfIRValue(); BfIRValue* irValuePtr = NULL; if (mTypeDataRefs.TryGetValue(type, &irValuePtr)) - { + { return *irValuePtr; } - + BfTypeInstance* typeInstance = type->ToTypeInstance(); BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef); mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition); @@ -5676,9 +5816,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin AssertErrorState(); return BfIRValue(); } - + BfIRValue typeTypeData; - int typeFlags = 0; + int typeFlags = 0; if (needsTypeData) { BfTypeInstance* typeInstanceTypeInstance = typeInstanceType->ToTypeInstance(); @@ -5719,15 +5859,15 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeDataSource = ResolveTypeDef(mCompiler->mReflectGenericParamType)->ToTypeInstance(); } else - typeDataSource = mContext->mBfTypeType; - + typeDataSource = mContext->mBfTypeType; + if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type) && (!mIsComptimeModule)) { CreateTypeData(typeDataSource, usedStringIdMap, false, true, needsTypeNames, true); - } + } typeTypeData = CreateClassVDataGlobal(typeDataSource); - } + } else typeTypeData = CreateClassVDataGlobal(typeInstanceType->ToTypeInstance()); @@ -5735,7 +5875,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfType* intType = GetPrimitiveType(BfTypeCode_Int32); BfType* intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); BfType* shortType = GetPrimitiveType(BfTypeCode_Int16); - BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); + BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); BfType* typeIdType = intType; @@ -5744,9 +5884,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto voidPtrPtrIRType = mBfIRBuilder->GetPointerTo(voidPtrIRType); auto voidPtrNull = GetDefaultValue(voidPtrType); - SizedArray typeValueParams; + SizedArray typeValueParams; GetConstClassValueParam(typeTypeData, typeValueParams); - + FixConstValueParams(mContext->mBfObjectType, typeValueParams); BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams); @@ -5763,8 +5903,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfMangler::Mangle(typeDataName, mCompiler->GetMangleKind(), type, mContext->mScratchModule); } - int typeCode = BfTypeCode_None; - + int typeCode = BfTypeCode_None; + if (typeInstance != NULL) { BF_ASSERT((type->mDefineState >= BfTypeDefineState_DefinedAndMethodsSlotted) || mIsComptimeModule); @@ -5785,7 +5925,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeCode = BfTypeCode_Pointer; typeFlags |= BfTypeFlags_Pointer; } - + if (type->IsObject()) { typeFlags |= BfTypeFlags_Object; @@ -5796,7 +5936,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeFlags |= BfTypeFlags_HasDestructor; } } - if (type->IsStruct()) + if (type->IsStruct()) typeFlags |= BfTypeFlags_Struct; if (type->IsInterface()) typeFlags |= BfTypeFlags_Interface; @@ -5806,14 +5946,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (((BfBoxedType*)type)->IsBoxedStructPtr()) typeFlags |= BfTypeFlags_Pointer; } - if (type->IsPrimitiveType()) + if (type->IsPrimitiveType()) typeFlags |= BfTypeFlags_Primitive; if (type->IsTypedPrimitive()) typeFlags |= BfTypeFlags_TypedPrimitive; if (type->IsTuple()) typeFlags |= BfTypeFlags_Tuple; if (type->IsNullable()) - typeFlags |= BfTypeFlags_Nullable; + typeFlags |= BfTypeFlags_Nullable; if (type->IsSizedArray()) typeFlags |= BfTypeFlags_SizedArray; if (type->IsConstExprValue()) @@ -5870,18 +6010,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(type->mTypeId, typeIdType), // mTypeId GetConstValue(boxedTypeId, typeIdType), // mBoxedType GetConstValue(typeFlags, intType), // mTypeFlags - GetConstValue(memberDataOffset, intType), // mMemberDataOffset + GetConstValue(memberDataOffset, intType), // mMemberDataOffset GetConstValue(typeCode, byteType), // mTypeCode GetConstValue(type->mAlign, byteType), // mAlign GetConstValue(stackCount, byteType), // mAllocStackCountOverride }; FixConstValueParams(mContext->mBfTypeType, typeDataParams); auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType, BfIRPopulateType_Full), typeDataParams); - + if (typeInstance == NULL) { BfIRValue typeDataVar; - + if (needsTypeData) { if (type->IsPointer()) @@ -5890,14 +6030,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin SizedArray pointerTypeDataParms = { typeData, - GetConstValue(pointerType->mElementType->mTypeId, typeIdType), + GetConstValue(pointerType->mElementType->mTypeId, typeIdType), }; auto reflectPointerType = ResolveTypeDef(mCompiler->mReflectPointerType)->ToTypeInstance(); FixConstValueParams(reflectPointerType, pointerTypeDataParms); auto pointerTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectPointerType, BfIRPopulateType_Full), pointerTypeDataParms); typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectPointerType), true, - BfIRLinkageType_External, pointerTypeData, typeDataName); + BfIRLinkageType_External, pointerTypeData, typeDataName); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); } @@ -5906,7 +6046,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto refType = (BfRefType*)type; SizedArray refTypeDataParms = { - typeData, + typeData, GetConstValue(refType->mElementType->mTypeId, typeIdType), GetConstValue((int8)refType->mRefKind, byteType), }; @@ -5922,7 +6062,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else if (type->IsSizedArray()) { auto sizedArrayType = (BfSizedArrayType*)type; - SizedArray sizedArrayTypeDataParms = + SizedArray sizedArrayTypeDataParms = { typeData, GetConstValue(sizedArrayType->mElementType->mTypeId, typeIdType), @@ -5980,21 +6120,21 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } else typeDataVar = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(mContext->mBfTypeType)); - + mTypeDataRefs[type] = typeDataVar; return typeDataVar; } - + // Reserve position mTypeDataRefs[typeInstance] = BfIRValue(); - + if ((typeInstance->IsReified()) && (!mIsComptimeModule)) PopulateType(typeInstance, BfPopulateType_DataAndMethods); - + BfTypeDef* typeDef = typeInstance->mTypeDef; StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), typeInstance, typeInstance->mModule); - + if (!mIsComptimeModule) { for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) @@ -6022,13 +6162,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } } } - + SizedArray vData; BfIRValue classVDataVar; String classVDataName; if (typeInstance->mSlotNum >= 0) { - // For interfaces we ONLY emit the slot num + // For interfaces we ONLY emit the slot num StringT<512> slotVarName; BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs"); auto intType = GetPrimitiveType(BfTypeCode_Int32); @@ -6036,28 +6176,28 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue32(virtSlotIdx), slotVarName); } else if ((typeInstance->IsObject()) && (!typeInstance->IsUnspecializedType()) && (needsVData)) - { + { int dynCastDataElems = 0; int numElements = 1; int vDataOfs = 1; // The number of intptrs before the iface slot map - numElements += mCompiler->mMaxInterfaceSlots; + numElements += mCompiler->mMaxInterfaceSlots; if (!typeInstance->IsInterface()) { dynCastDataElems = 1 + mCompiler->mMaxInterfaceSlots; numElements += mCompiler->GetDynCastVDataCount(); numElements += typeInstance->mVirtualMethodTableSize; } - + int expectNumElements = 0; if (!typeDef->mIsStatic) { - classVDataVar = CreateClassVDataGlobal(typeInstance, &expectNumElements, &classVDataName); + classVDataVar = CreateClassVDataGlobal(typeInstance, &expectNumElements, &classVDataName); } - - vData.push_back(BfIRValue()); // Type* - + + vData.push_back(BfIRValue()); // Type* + SizedArray extVTableData; - + SizedArrayImpl* vFuncDataExt = &extVTableData; if (!typeInstance->IsInterface()) @@ -6069,11 +6209,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin dynCastData.Add(underlyingType->mInheritanceId); } else - dynCastData.Add(typeInstance->mInheritanceId); + dynCastData.Add(typeInstance->mInheritanceId); for (int i = 0; i < mCompiler->mMaxInterfaceSlots; i++) dynCastData.Add(0); dynCastData.Add(0); - + auto checkTypeInst = typeInstance; while (checkTypeInst != NULL) { @@ -6087,7 +6227,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } checkTypeInst = checkTypeInst->GetImplBaseType(); } - + if (mSystem->mPtrSize == 8) { int intPtrCount = (dynCastDataElems + 1) / 2; @@ -6180,13 +6320,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin isBetter = true; isWorse = false; } - if (isBetter == isWorse) - CompareDeclTypes(interfaceEntry.mDeclaringType, prevEntry->mDeclaringType, isBetter, isWorse); + if (isBetter == isWorse) + CompareDeclTypes(checkTypeInst, interfaceEntry.mDeclaringType, prevEntry->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { if (matchEntry->mAmbiguousEntries.empty()) matchEntry->mAmbiguousEntries.push_back(prevEntry); - matchEntry->mAmbiguousEntries.push_back(&interfaceEntry); + matchEntry->mAmbiguousEntries.push_back(&interfaceEntry); continue; } else if (isBetter) @@ -6208,7 +6348,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } checkTypeInst = checkTypeInst->GetImplBaseType(); - } + } for (auto interfacePair : interfaceMap) { @@ -6219,7 +6359,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (error != NULL) { for (auto ambiguiousEntry : interfaceMatchEntry.mAmbiguousEntries) - mCompiler->mPassInstance->MoreInfo("See other declaration", ambiguiousEntry->mDeclaringType->GetRefNode()); + mCompiler->mPassInstance->MoreInfo("See other declaration", ambiguiousEntry->mDeclaringType->GetRefNode()); } } } @@ -6227,7 +6367,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if ((!mIsComptimeModule) && (!typeInstance->IsInterface()) && (typeInstance->mVirtualMethodTableSize > 0) && (needsVData)) { int startTabIdx = (int)vData.size(); - + SizedArray origVirtTypeStack; BfTypeInstance* checkTypeInst = typeInstance; while (checkTypeInst != NULL) @@ -6238,17 +6378,17 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin Array origVTable; - int origVirtIdx = 0; + int origVirtIdx = 0; if (typeInstance->mTypeDef->mIsCombinedPartial) { - HashSet reslotNames; + HashSet reslotNames; for (int virtIdx = 0; virtIdx < (int)typeInstance->mVirtualMethodTable.size(); virtIdx++) { auto& entry = typeInstance->mVirtualMethodTable[virtIdx]; if (entry.mDeclaringMethod.mMethodNum == -1) continue; BfMethodInstance* methodInstance = (BfMethodInstance*)entry.mImplementingMethod; - if ((methodInstance == NULL) || + if ((methodInstance == NULL) || ((!mIsComptimeModule) && (!typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject)))) { if (origVTable.empty()) @@ -6292,7 +6432,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if ((methodInstance->mChainType != BfMethodChainType_None) && (methodInstance->mChainType != BfMethodChainType_ChainHead)) continue; SlotVirtualMethod(methodInstance, &ambiguityContext); - } + } ambiguityContext.Finish(); } @@ -6316,7 +6456,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else { BfMethodInstance* declaringMethodInstance = (BfMethodInstance*)entry.mDeclaringMethod; - if ((declaringMethodInstance != NULL) && (declaringMethodInstance->mMethodInstanceGroup->IsImplemented()) && (declaringMethodInstance->mIsReified)) + if ((declaringMethodInstance != NULL) && (declaringMethodInstance->mMethodInstanceGroup->IsImplemented()) && (declaringMethodInstance->mIsReified)) { BF_ASSERT(entry.mImplementingMethod.mTypeInstance->mMethodInstanceGroups[entry.mImplementingMethod.mMethodNum].IsImplemented()); BF_ASSERT(entry.mImplementingMethod.mTypeInstance->mMethodInstanceGroups[entry.mImplementingMethod.mMethodNum].mDefault->mIsReified); @@ -6345,7 +6485,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin { // We are within the original vtable size int idx = startTabIdx + origVirtIdx; - origVirtIdx++; + origVirtIdx++; vData.push_back(vValue); } else @@ -6354,7 +6494,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BF_ASSERT(isInExts); } break; - } + } } if (!origVTable.empty()) @@ -6363,13 +6503,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin int ifaceMethodExtStart = (int)typeInstance->GetIFaceVMethodSize(); if (typeInstance->mHotTypeData != NULL) - { + { if (typeInstance->mHotTypeData->mOrigInterfaceMethodsLength != -1) ifaceMethodExtStart = typeInstance->mHotTypeData->mOrigInterfaceMethodsLength; } SizedArray ifaceMethodExtData; - + int iFaceMethodStartIdx = (int)vData.size(); vData.resize(iFaceMethodStartIdx + ifaceMethodExtStart); for (int i = iFaceMethodStartIdx; i < iFaceMethodStartIdx + ifaceMethodExtStart; i++) @@ -6382,7 +6522,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin // for (int i = 0; i < (int)typeInstance->mInterfaceMethodTable.size() - ifaceMethodExtStart; i++) // ifaceMethodExtData.Add(voidPtrNull); - + int ifaceEntryIdx = iFaceMethodStartIdx; for (auto& interfacePair : interfaceMap) { @@ -6397,14 +6537,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin bool makeEmpty = false; if ((!mIsComptimeModule) && (!typeInstance->IsTypeMemberAccessible(interfaceEntry->mDeclaringType, mProject))) makeEmpty = true; - + int endVirtualIdx = interfaceEntry->mStartVirtualIdx + interfaceEntry->mInterfaceType->mVirtualMethodTableSize; bool useExt = endVirtualIdx > ifaceMethodExtStart; for (int methodIdx = 0; methodIdx < (int)interfaceEntry->mInterfaceType->mMethodInstanceGroups.size(); methodIdx++) - { + { BfIRValue pushValue; - + BfMethodInstance* ifaceMethodInstance = interfaceEntry->mInterfaceType->mMethodInstanceGroups[methodIdx].mDefault; if ((ifaceMethodInstance == NULL) || (ifaceMethodInstance->mVirtualTableIdx == -1)) continue; @@ -6425,7 +6565,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BF_ASSERT(methodInstance->mIsReified); // This doesn't work because we may have FOREIGN methods from implicit interface methods - //auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum); + //auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum); auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance, BfGetMethodInstanceFlag_NoInline); auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType); pushValue = funcPtr; @@ -6451,7 +6591,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin ifaceMethodExtData[extIdx] = pushValue; } } - } + } if (typeInstance->IsBoxed()) { @@ -6460,7 +6600,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin { // Force override of GetHashCode so we use the pointer address as the hash code checkTypeInst = CreateBoxedType(ResolveTypeDef(mCompiler->mPointerTypeDef)); - + // Force override of GetHashCode so we use the pointer address as the hash code for (auto& checkIFace : checkTypeInst->mInterfaces) { @@ -6476,22 +6616,21 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin continue; auto& methodRef = checkTypeInst->mInterfaceMethodTable[checkIFace.mStartInterfaceTableIdx + methodIdx].mMethodRef; - + auto methodInstance = (BfMethodInstance*)methodRef; BF_ASSERT(methodInstance->mIsReified); // This doesn't work because we may have FOREIGN methods from implicit interface methods - //auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum); + //auto moduleMethodInst = GetMethodInstanceAtIdx(methodRef.mTypeInstance, methodRef.mMethodNum); auto moduleMethodInst = ReferenceExternalMethodInstance(methodInstance, BfGetMethodInstanceFlag_NoInline); auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType); int idx = checkIFace.mStartVirtualIdx + ifaceMethodInstance->mVirtualTableIdx; vData[iFaceMethodStartIdx + idx] = funcPtr; } - } } } - + if ((needsVData) && (!typeInstance->mTypeDef->mIsStatic) && (!mIsComptimeModule)) { BfIRValue ifaceMethodExtVar; @@ -6509,7 +6648,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } for (auto& ifaceInstPair : interfaceMap) - { + { auto interfaceEntry = ifaceInstPair.mValue.mEntry; int slotNum = interfaceEntry->mInterfaceType->mSlotNum; if (slotNum >= 0) @@ -6533,7 +6672,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (mCompiler->IsHotCompile()) Fail("Interface slot collision error. Restart program or undo interface changes.", typeDef->GetRefNode()); else - Fail("Interface slot collision error", typeDef->GetRefNode()); + Fail("Interface slot collision error", typeDef->GetRefNode()); } } } @@ -6555,12 +6694,12 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin namespaceConst = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(stringType)); } - int baseTypeId = 0; + int baseTypeId = 0; if (typeInstance->mBaseType != NULL) - { + { baseTypeId = typeInstance->mBaseType->mTypeId; - } - + } + BfTypeOptions* typeOptions = NULL; if (typeInstance->mTypeOptionsIdx >= 0) typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx); @@ -6568,7 +6707,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin SizedArray customAttrs; BfTypeInstance* attributeType = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance(); - + BfIRValue castedClassVData; if (classVDataVar) castedClassVData = mBfIRBuilder->CreateBitCast(classVDataVar, mBfIRBuilder->MapType(mContext->mBfClassVDataPtrType)); @@ -6577,8 +6716,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin bool freflectIncludeTypeData = false; bool reflectIncludeAllFields = false; - bool reflectIncludeAllMethods = false; - + bool reflectIncludeAllMethods = false; + if (TypeIsSubTypeOf(typeInstance, attributeType)) { reflectIncludeAllFields = true; @@ -6603,9 +6742,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin }; reflectKind = GetReflectKind(reflectKind, typeInstance); - + // Fields - BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); + BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef); BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray()); auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes) @@ -6650,11 +6789,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin SizedArray data; int customAttrIdx = (int)customAttrs.size(); - + data.push_back((uint8)reflectAttributes.size()); for (auto attr : reflectAttributes) - { + { // Size prefix int sizeIdx = (int)data.size(); PUSH_INT16(0); // mSize @@ -6664,7 +6803,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin int ctorIdx = -1; int ctorCount = 0; - attr->mType->mTypeDef->PopulateMemberSets(); + attr->mType->mTypeDef->PopulateMemberSets(); BfMemberSetEntry* entry; if (attr->mType->mTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry)) { @@ -6685,14 +6824,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto ctorMethodInstance = GetRawMethodInstanceAtIdx(attr->mType, attr->mCtor->mIdx); int argIdx = 0; - + for (auto arg : attr->mCtorArgs) { auto argType = ctorMethodInstance->GetParamType(argIdx); EncodeAttributeData(typeInstance, argType, arg, data, usedStringIdMap); argIdx++; } - + int size = (int)data.size() - sizeIdx; *((uint16*)&data[sizeIdx]) = size; } @@ -6755,7 +6894,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin includeField = true; if ((fieldDef->mIsStatic) && ((fieldReflectKind & BfReflectKind_StaticFields) != 0)) includeField = true; - + if ((!fieldDef->mIsStatic) && (typeOptions != NULL)) includeField = typeOptions->Apply(includeField, BfOptionFlags_ReflectNonStaticFields); if ((fieldDef->mIsStatic) && (typeOptions != NULL)) @@ -6773,26 +6912,26 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } // For a splattable type, we need to either include all fields or zero fields. This is to allow us to correctly splat - // params for reflected method calls even if we don't have reflection field info for the splatted type. This is + // params for reflected method calls even if we don't have reflection field info for the splatted type. This is // possible because we write out a SplatData structure containing just TypeIds in that case if (pass == 0) { if (!typeInstance->IsSplattable()) - break; + break; if (!skippedField) break; if (reflectFieldIndices.size() == 0) break; - } + } } - - SizedArray fieldTypes; + + SizedArray fieldTypes; bool is32Bit = mCompiler->mSystem->mPtrSize == 4; if ((typeInstance->IsPayloadEnum()) && (!typeInstance->IsBoxed())) - { - BfType* payloadType = typeInstance->GetUnionInnerType(); + { + BfType* payloadType = typeInstance->GetUnionInnerType(); if (!payloadType->IsValuelessType()) { BfIRValue payloadNameConst = GetStringObjectValue("$payload", !mIsComptimeModule); @@ -6817,7 +6956,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin emptyValueType, payloadNameConst, // mName GetConstValue(payloadType->mTypeId, typeIdType), // mFieldTypeId - GetConstValue(0, intPtrType), // mData + GetConstValue(0, intPtrType), // mData GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumPayload, shortType), // mFlags GetConstValue(-1, intType), // mCustomAttributesIdx }; @@ -6835,7 +6974,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin dscrFieldVals = { emptyValueType, - dscrNameConst, // mName + dscrNameConst, // mName GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), intPtrType), // mData GetConstValue(0, intPtrType), // mDataHi @@ -6848,7 +6987,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin dscrFieldVals = { emptyValueType, - dscrNameConst, // mName + dscrNameConst, // mName GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), intPtrType), // mData GetConstValue(BfFieldFlags_SpecialName | BfFieldFlags_EnumDiscriminator, shortType), // mFlags @@ -6857,7 +6996,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } auto dscrFieldData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance(), BfIRPopulateType_Full), dscrFieldVals); fieldTypes.push_back(dscrFieldData); - } + } for (auto fieldIdx : reflectFieldIndices) { @@ -6866,7 +7005,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances[fieldIdx]; fieldTypes.push_back(CreateFieldData(fieldInstance, _HandleCustomAttrs(fieldInstance->mCustomAttributes))); - } + } auto reflectFieldDataIRType = mBfIRBuilder->MapType(reflectFieldDataType); BfIRValue fieldDataPtr; @@ -6876,10 +7015,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if ((type->IsSplattable()) && (type->IsStruct()) && (!type->IsValuelessType()) && (!typeInstance->mIsCRepr)) { BfTypeInstance* reflectFieldSplatDataType = ResolveTypeDef(mCompiler->mReflectFieldSplatDataDef)->ToTypeInstance(); - + SizedArray splatTypes; SizedArray splatOffsets; - + std::function _CheckSplat = [&](BfType* checkType, int offset) { auto checkTypeInstance = checkType->ToTypeInstance(); @@ -6944,7 +7083,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin { splatTypes.Add(GetConstValue(0, typeIdType)); splatOffsets.Add(GetConstValue(0, intType)); - } + } BfIRValue splatTypesConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[0].mResolvedType), splatTypes); BfIRValue splatOffsetsConst = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectFieldSplatDataType->mFieldInstances[1].mResolvedType), splatOffsets); @@ -6974,19 +7113,19 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin /// Methods - BfType* reflectMethodDataType = ResolveTypeDef(mCompiler->mReflectMethodDataDef); + BfType* reflectMethodDataType = ResolveTypeDef(mCompiler->mReflectMethodDataDef); BfType* reflectParamDataType = ResolveTypeDef(mCompiler->mReflectParamDataDef); BfType* reflectParamDataPtrType = CreatePointerType(reflectParamDataType); struct _SortedMethodInfo { BfMethodDef* mMethodDef; - BfMethodCustomAttributes* mMethodCustomAttributes; + BfMethodCustomAttributes* mMethodCustomAttributes; }; Array<_SortedMethodInfo> sortedMethodList; - SizedArray methodTypes; + SizedArray methodTypes; for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) { if (!needsTypeData) @@ -7022,10 +7161,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin bool includeMethod = reflectIncludeAllMethods; - BfMethodCustomAttributes* methodCustomAttributes = NULL; + BfMethodCustomAttributes* methodCustomAttributes = NULL; if ((defaultMethod->mMethodInfoEx != NULL) && (defaultMethod->mMethodInfoEx->mMethodCustomAttributes != NULL) && (defaultMethod->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL)) { - methodCustomAttributes = defaultMethod->mMethodInfoEx->mMethodCustomAttributes; + methodCustomAttributes = defaultMethod->mMethodInfoEx->mMethodCustomAttributes; for (auto& customAttr : defaultMethod->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->mAttributes) { if (customAttr.mType->mTypeDef->mName->ToString() == "ReflectAttribute") @@ -7060,14 +7199,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin includeMethod = true; if ((methodDef->mIsStatic) && ((methodReflectKind & BfReflectKind_StaticMethods) != 0)) includeMethod = true; - + if ((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend)) { if ((methodReflectKind & BfReflectKind_Constructors) != 0) includeMethod = true; if ((methodDef->IsDefaultCtor()) && ((methodReflectKind & BfReflectKind_DefaultConstructor) != 0)) includeMethod = true; - } + } if ((!includeMethod) && (typeOptions != NULL)) includeMethod = ApplyTypeOptionMethodFilters(includeMethod, methodDef, typeOptions); @@ -7089,7 +7228,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin { int lhsKind = _GetMethodKind(lhs.mMethodDef); int rhsKind = _GetMethodKind(rhs.mMethodDef); - + if (lhsKind != rhsKind) return lhsKind < rhsKind; if (lhs.mMethodDef->mName != rhs.mMethodDef->mName) @@ -7106,7 +7245,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfModuleMethodInstance moduleMethodInstance; BfIRValue funcVal = voidPtrNull; - + if (((!typeInstance->IsBoxed()) || (!methodDef->mIsStatic)) && (!typeInstance->IsUnspecializedType()) && (methodDef->mMethodType != BfMethodType_Ignore) && @@ -7118,12 +7257,12 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (moduleMethodInstance.mFunc) funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType); } - + BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, !mIsComptimeModule); - + BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); - - int customAttrIdx = -1; + + int customAttrIdx = -1; int returnCustomAttrIdx = -1; if (methodInfo.mMethodCustomAttributes != NULL) { @@ -7136,7 +7275,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin ParamFlag_None = 0, ParamFlag_Splat = 1, ParamFlag_Implicit = 2, - ParamFlag_AppendIdx = 4 + ParamFlag_AppendIdx = 4, + ParamFlag_Params = 8 }; SizedArray paramVals; @@ -7150,7 +7290,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat); if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_AppendIdx) paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx); - + if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_Params) + paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params); + BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule); int paramCustomAttrIdx = -1; @@ -7169,7 +7311,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin auto paramData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapType(reflectParamDataType, BfIRPopulateType_Full), paramDataVals); paramVals.Add(paramData); } - + BfIRValue paramsVal; if (paramVals.size() > 0) { @@ -7183,7 +7325,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else paramsVal = mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapType(reflectParamDataPtrType)); - int vDataVal = -1; + int vDataVal = -1; if (defaultMethod->mVirtualTableIdx != -1) { int vDataIdx = -1; @@ -7220,11 +7362,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (vDataVal == -1) vDataVal = vDataIdx * mSystem->mPtrSize; } - + SizedArray methodDataVals = { emptyValueType, - methodNameConst, // mName + methodNameConst, // mName funcVal, // mFuncPtr paramsVal, GetConstValue(defaultMethod->mReturnType->mTypeId, typeIdType), @@ -7251,7 +7393,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin methodDataConst, "methods." + typeDataName); methodDataPtr = mBfIRBuilder->CreateBitCast(methodDataArray, methodDataPtrType); } - + ///// int interfaceCount = 0; @@ -7302,17 +7444,17 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin interfaceDataPtr = mBfIRBuilder->CreateBitCast(interfaceDataArray, interfaceDataPtrType); interfaceCount = (int)interfaces.size(); } - + BfIRValue interfaceMethodTable; int ifaceMethodTableSize = 0; - if ((wantsIfaceMethods) && (!typeInstance->IsInterface()) && (typeInstance->mIsReified) && (!typeInstance->IsUnspecializedType()) - && (!typeInstance->mInterfaceMethodTable.IsEmpty())) - { + if ((wantsIfaceMethods) && (!typeInstance->IsInterface()) && (typeInstance->mIsReified) && (!typeInstance->IsUnspecializedType()) + && (!typeInstance->mInterfaceMethodTable.IsEmpty())) + { SizedArray methods; - for (int tableIdx = 0; tableIdx < (int)typeInstance->mInterfaceMethodTable.size(); tableIdx++) + for (int tableIdx = 0; tableIdx < (int)typeInstance->mInterfaceMethodTable.size(); tableIdx++) { BfIRValue funcVal = voidPtrNull; - if ((tableIdx < (int)wantsIfaceMethod.size()) && (wantsIfaceMethod[tableIdx])) + if ((tableIdx < (int)wantsIfaceMethod.size()) && (wantsIfaceMethod[tableIdx])) { auto methodEntry = typeInstance->mInterfaceMethodTable[tableIdx]; if (!methodEntry.mMethodRef.IsNull()) @@ -7342,25 +7484,25 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin interfaceMethodTable = mBfIRBuilder->CreateBitCast(methodDataArray, voidPtrPtrIRType); ifaceMethodTableSize = (int)methods.size(); } - } + } if (!interfaceMethodTable) interfaceMethodTable = mBfIRBuilder->CreateConstNull(voidPtrPtrIRType); ///// - int underlyingType = 0; + int underlyingType = 0; if ((typeInstance->IsTypedPrimitive()) || (typeInstance->IsBoxed())) - { + { underlyingType = typeInstance->GetUnderlyingType()->mTypeId; - } + } int outerTypeId = 0; auto outerType = mContext->mUnreifiedModule->GetOuterType(typeInstance); if (outerType != NULL) - { + { outerTypeId = outerType->mTypeId; - } - + } + // BfIRValue customAttrDataPtr; @@ -7385,11 +7527,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeNameConst, // mName namespaceConst, // mNamespace GetConstValue(typeInstance->mInstSize, intType), // mInstSize - GetConstValue(typeInstance->mInstAlign, intType), // mInstAlign + GetConstValue(typeInstance->mInstAlign, intType), // mInstAlign GetConstValue(typeCustomAttrIdx, intType), // mCustomAttributes GetConstValue(baseTypeId, typeIdType), // mBaseType - GetConstValue(underlyingType, typeIdType), // mUnderlyingType - GetConstValue(outerTypeId, typeIdType), // mOuterType + GetConstValue(underlyingType, typeIdType), // mUnderlyingType + GetConstValue(outerTypeId, typeIdType), // mOuterType GetConstValue(typeInstance->mInheritanceId, intType), // mInheritanceId GetConstValue(typeInstance->mInheritanceCount, intType), // mInheritanceCount @@ -7398,13 +7540,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin GetConstValue(ifaceMethodTableSize, shortType), // mInterfaceMethodCount GetConstValue((int)methodTypes.size(), shortType), // mMethodDataCount GetConstValue(0, shortType), // mPropertyDataCount - GetConstValue((int)fieldTypes.size(), shortType), // mFieldDataCount + GetConstValue((int)fieldTypes.size(), shortType), // mFieldDataCount interfaceDataPtr, // mInterfaceDataPtr interfaceMethodTable, // mInterfaceMethodTable methodDataPtr, // mMethodDataPtr voidPtrNull, // mPropertyDataPtr - fieldDataPtr, // mFieldDataPtr + fieldDataPtr, // mFieldDataPtr customAttrDataPtr, // mCustomAttrDataPtr }; @@ -7412,7 +7554,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin BfIRType typeInstanceDataType = mBfIRBuilder->MapTypeInst(typeInstanceType->ToTypeInstance(), BfIRPopulateType_Full); FixConstValueParams(typeInstanceType->ToTypeInstance(), typeDataVals); auto typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, typeDataVals); - + if (!needsTypeData) { // No need for anything beyond typeInstanceData @@ -7420,11 +7562,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin else if ((typeInstance->IsGenericTypeInstance()) && (typeInstance->IsUnspecializedType())) { auto genericTypeInstance = typeInstance->ToGenericTypeInstance(); - + SizedArray unspecializedData = { - typeInstanceData, - GetConstValue((int)genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments.size(), byteType), // mGenericParamCount + typeInstanceData, + GetConstValue((int)genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments.size(), byteType), // mGenericParamCount }; auto reflectUnspecializedGenericType = ResolveTypeDef(mCompiler->mReflectUnspecializedGenericType); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectUnspecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); @@ -7450,14 +7592,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin SizedArray specGenericData = { - typeInstanceData, - GetConstValue(unspecializedType->mTypeId, typeIdType), // mUnspecialziedType + typeInstanceData, + GetConstValue(unspecializedType->mTypeId, typeIdType), // mUnspecialziedType resovledTypesPtr, // mFieldDataPtr }; typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectSpecializedGenericType->ToTypeInstance(), BfIRPopulateType_Full); typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, specGenericData); - + if (typeInstance->IsArray()) { auto arrayType = (BfArrayType*)typeInstance; @@ -7470,14 +7612,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeInstanceData, GetConstValue(elementType->mSize, intType), // mElementSize GetConstValue(1, byteType), // mRank - GetConstValue(elementFieldInstance->mDataOffset, byteType), // mElementsDataOffset + GetConstValue(elementFieldInstance->mDataOffset, byteType), // mElementsDataOffset }; auto reflectArrayType = ResolveTypeDef(mCompiler->mReflectArrayType); typeInstanceDataType = mBfIRBuilder->MapTypeInst(reflectArrayType->ToTypeInstance(), BfIRPopulateType_Full); typeInstanceData = mBfIRBuilder->CreateConstAgg_Value(typeInstanceDataType, arrayData); } } - + BfIRValue typeDataVar; if (needsTypeData) { @@ -7496,40 +7638,40 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin } typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); - mTypeDataRefs[typeInstance] = typeDataVar; + mTypeDataRefs[typeInstance] = typeDataVar; if ((!mIsComptimeModule) && (classVDataVar)) - { + { BF_ASSERT(!classVDataName.IsEmpty()); vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType); auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size()); auto classVDataConstData = mBfIRBuilder->CreateConstAgg_Value(classVDataConstDataType, vData); - mBfIRBuilder->GlobalVar_SetInitializer(classVDataVar, classVDataConstData); + mBfIRBuilder->GlobalVar_SetInitializer(classVDataVar, classVDataConstData); if (mCompiler->mOptions.mObjectHasDebugFlags) mBfIRBuilder->GlobalVar_SetAlignment(classVDataVar, 256); else mBfIRBuilder->GlobalVar_SetAlignment(classVDataVar, mContext->mBfClassVDataPtrType->mAlign); - + if (mBfIRBuilder->DbgHasInfo()) { BfType* voidType = GetPrimitiveType(BfTypeCode_None); BfType* voidPtrType = CreatePointerType(voidType); - + BfType* classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); BfIRMDNode arrayType = mBfIRBuilder->DbgCreateArrayType(vData.size() * mSystem->mPtrSize * 8, mSystem->mPtrSize * 8, mBfIRBuilder->DbgGetType(voidPtrType), vData.size()); mBfIRBuilder->DbgCreateGlobalVariable(mDICompileUnit, classVDataName, classVDataName, BfIRMDNode(), 0, arrayType, false, classVDataVar); } } - + return typeDataVar; } BfIRValue BfModule::FixClassVData(BfIRValue value) { if ((!mCompiler->mOptions.mObjectHasDebugFlags) || (mIsComptimeModule)) - return value; + return value; auto intptrValue = mBfIRBuilder->CreatePtrToInt(value, BfTypeCode_IntPtr); auto maskedValue = mBfIRBuilder->CreateAnd(intptrValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL)); return mBfIRBuilder->CreateIntToPtr(maskedValue, mBfIRBuilder->GetType(value)); @@ -7556,7 +7698,7 @@ void BfModule::CheckStaticAccess(BfTypeInstance* typeInstance) return; if (mCurMethodInstance->mMethodInstanceGroup->mOwner == typeInstance) return; - + auto checkTypeDef = typeInstance->mTypeDef; checkTypeDef->PopulateMemberSets(); BfMethodDef* nextMethodDef = NULL; @@ -7566,8 +7708,8 @@ void BfModule::CheckStaticAccess(BfTypeInstance* typeInstance) while (nextMethodDef != NULL) { auto checkMethod = nextMethodDef; - nextMethodDef = nextMethodDef->mNextWithSameName; - auto methodModule = GetMethodInstance(typeInstance, checkMethod, BfTypeVector()); + nextMethodDef = nextMethodDef->mNextWithSameName; + auto methodModule = GetMethodInstance(typeInstance, checkMethod, BfTypeVector()); if (methodModule) { auto methodInstance = methodModule.mMethodInstance; @@ -7588,13 +7730,13 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor auto methodOwner = methodInstance->GetOwner(); auto methodDef = methodInstance->mMethodDef; auto methodDeclaration = methodDef->GetMethodDeclaration(); - + if (!methodDef->mIsExtern) return BfIRFunction(); - + if (methodInstance->GetCustomAttributes() == NULL) return BfIRFunction(); - + for (auto& customAttribute : methodInstance->GetCustomAttributes()->mAttributes) { String typeName = TypeToString(customAttribute.mType); @@ -7602,15 +7744,15 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor { methodInstance->mIsIntrinsic = true; - auto constant = methodOwner->mConstHolder->GetConstant(customAttribute.mCtorArgs[0]); + auto constant = methodOwner->mConstHolder->GetConstant(customAttribute.mCtorArgs[0]); String error; - + if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_StringId)) { int stringId = constant->mInt32; auto entry = mContext->mStringObjectIdMap[stringId]; String intrinName = entry.mString; - + // if (intrinName.StartsWith(":")) // { // SizedArray paramTypes; @@ -7645,10 +7787,10 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor error = "Intrinsic name must be a constant string"; if (reportFailure) - { + { Fail(error, customAttribute.mRef); - } - } + } + } } return BfIRFunction(); @@ -7660,7 +7802,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) return mBfIRBuilder->GetFakeFunction(); if (!mBuiltInFuncs[(int)funcTypeId]) - { + { SizedArray paramTypes; auto nullPtrType = mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_NullPtr)); auto intType = mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_IntPtr)); @@ -7680,7 +7822,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) funcType = mBfIRBuilder->CreateFunctionType(int32Type, paramTypes, true); func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, "PrintF"); break; - case BfBuiltInFuncType_Malloc: + case BfBuiltInFuncType_Malloc: { if ((mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule)) { @@ -7695,7 +7837,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) if (!func) { paramTypes.clear(); - paramTypes.push_back(intType); + paramTypes.push_back(intType); funcType = mBfIRBuilder->CreateFunctionType(nullPtrType, paramTypes); func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, funcName); mBfIRBuilder->Func_SetParamName(func, 1, "size"); @@ -7703,8 +7845,8 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) } } break; - case BfBuiltInFuncType_Free: - { + case BfBuiltInFuncType_Free: + { if ((mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule)) { func = GetInternalMethod("Dbg_RawFree").mFunc; @@ -7725,9 +7867,9 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) } } } - break; + break; case BfBuiltInFuncType_LoadSharedLibraries: - paramTypes.clear(); + paramTypes.clear(); funcType = mBfIRBuilder->CreateFunctionType(voidType, paramTypes); func = mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, "BfLoadSharedLibraries"); break; @@ -7742,8 +7884,8 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId) } void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized, Array* deferredResolveTypes) -{ - BfGenericParamDef* genericParamDef = genericParamInstance->GetGenericParamDef(); +{ + BfGenericParamDef* genericParamDef = genericParamInstance->GetGenericParamDef(); BfExternalConstraintDef* externConstraintDef = genericParamInstance->GetExternConstraintDef(); BfConstraintDef* constraintDef = genericParamInstance->GetConstraintDef(); @@ -7751,11 +7893,11 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar BfAutoComplete* bfAutocomplete = NULL; if ((mCompiler->mResolvePassData != NULL) && (isUnspecialized)) - bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete; + bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete; if ((bfAutocomplete != NULL) && (genericParamDef != NULL)) - { - for (int nameIdx = 0; nameIdx < (int)genericParamDef->mNameNodes.size(); nameIdx++) + { + for (int nameIdx = 0; nameIdx < (int)genericParamDef->mNameNodes.size(); nameIdx++) { auto nameNode = genericParamDef->mNameNodes[nameIdx]; if (bfAutocomplete->IsAutocompleteNode(nameNode)) @@ -7765,11 +7907,11 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar bfAutocomplete->mInsertEndIdx = nameNode->GetSrcEnd(); if (nameIdx != 0) - { + { bfAutocomplete->AddEntry(AutoCompleteEntry("generic", nameNode->ToString().c_str()), filter); } } - } + } } for (auto constraint : constraintDef->mConstraints) @@ -7777,7 +7919,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar if (auto opConstraint = BfNodeDynCast(constraint)) { BfGenericOperatorConstraintInstance opConstraintInstance; - + if (opConstraint->mLeftType != NULL) { if (bfAutocomplete != NULL) @@ -7803,7 +7945,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar } if (opConstraint->mOpToken == NULL) - { + { FailAfter("Missing operator", (opConstraint->mLeftType != NULL) ? (BfAstNode*)opConstraint->mLeftType : (BfAstNode*)opConstraint->mOperatorToken); continue; } @@ -7836,7 +7978,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar continue; } } - + genericParamInstance->mOperatorConstraints.Add(opConstraintInstance); continue; @@ -7856,7 +7998,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar // `where T : Dictionay and TElem : IHashable` and we don't want to throw the error on `T` before we build `TElem` auto constraintType = ResolveTypeRef(constraintTypeRef, (deferredResolveTypes != NULL) ? BfPopulateType_Identity : BfPopulateType_Declaration, resolveFlags); if (constraintType != NULL) - { + { if (deferredResolveTypes != NULL) { PopulateType(constraintType, BfPopulateType_Declaration); @@ -7866,11 +8008,11 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar if ((constraintDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) { - bool isValidTypeCode = false; + bool isValidTypeCode = false; BfTypeCode typeCode = BfTypeCode_None; if (constraintType->IsTypedPrimitive()) - { + { auto underlyingType = constraintType->GetUnderlyingType(); if (underlyingType->IsPrimitiveType()) typeCode = ((BfPrimitiveType*)underlyingType)->mTypeDef->mTypeCode; @@ -7906,7 +8048,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar break; default: break; } - + if (isValidTypeCode) { genericParamInstance->mTypeConstraint = constraintType; @@ -7919,7 +8061,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar else { bool checkEquality = false; - + if (constraintType->IsVar()) { // From a `comptype` generic undef resolution. Ignore. @@ -7928,18 +8070,18 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar continue; } else if (constraintType->IsPrimitiveType()) - { + { if (isUnspecialized) { Fail("Primitive constraints are not allowed unless preceded with 'const'", constraintTypeRef); continue; - } + } checkEquality = true; } if (constraintType->IsArray()) { - if (isUnspecialized) + if (isUnspecialized) { Fail("Array constraints are not allowed. If a constant-sized array was intended, an type parameterized by a const generic param can be used (ie: where T : int[T2] where T2 : const int)", constraintTypeRef); continue; @@ -7960,13 +8102,13 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar } checkEquality = true; } - + if (checkEquality) { genericParamInstance->mTypeConstraint = constraintType; } else if (constraintType->IsInterface()) - { + { genericParamInstance->mInterfaceConstraints.push_back(constraintType->ToTypeInstance()); } else @@ -8009,7 +8151,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar String BfModule::GenericParamSourceToString(const BfGenericParamSource & genericParamSource) { if (genericParamSource.mMethodInstance != NULL) - { + { //auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false); //SetAndRestoreValue prevMethodInst(mCurMethodInstance, methodInst); return MethodToString(genericParamSource.mMethodInstance); @@ -8049,7 +8191,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS origCheckArgType = origCheckArgType->GetUnderlyingType(); bool argIsReferenceType = false; - + int checkGenericParamFlags = 0; if (checkArgType->IsGenericParam()) { @@ -8057,7 +8199,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS checkGenericParamFlags = checkGenericParamInst->mGenericParamFlags; if (checkGenericParamInst->mTypeConstraint != NULL) checkArgType = checkGenericParamInst->mTypeConstraint; - + // if ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0) // { // argMayBeReferenceType = false; @@ -8074,8 +8216,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS BfTypeInstance* typeConstraintInst = NULL; if (genericParamInst->mTypeConstraint != NULL) typeConstraintInst = genericParamInst->mTypeConstraint->ToTypeInstance(); - - if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Struct) && + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Struct) && ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_Enum | BfGenericParamFlag_Var)) == 0) && (!checkArgType->IsValueType())) { if ((!ignoreErrors) && (PreFail())) @@ -8083,8 +8225,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef); return false; } - - if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) && + + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) && ((checkGenericParamFlags & (BfGenericParamFlag_StructPtr | BfGenericParamFlag_Var)) == 0) && (!checkArgType->IsPointer())) { if ((!ignoreErrors) && (PreFail())) @@ -8093,7 +8235,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS return false; } - if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) && + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) && ((checkGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Var)) == 0) && (!argIsReferenceType)) { if ((!ignoreErrors) && (PreFail())) @@ -8182,7 +8324,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (checkArgType->IsPointer()) { - auto ptrType = (BfPointerType*)checkArgType; + auto ptrType = (BfPointerType*)checkArgType; checkArgType = ptrType->mElementType; } @@ -8240,7 +8382,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS // Any primitive types and stuff can be allocated canAlloc = true; } - + if (!canAlloc) { if ((!ignoreErrors) && (PreFail())) @@ -8257,7 +8399,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS } if ((genericParamInst->mInterfaceConstraints.IsEmpty()) && (genericParamInst->mOperatorConstraints.IsEmpty()) && (genericParamInst->mTypeConstraint == NULL)) - return true; + return true; if (genericParamInst->mTypeConstraint != NULL) { @@ -8272,7 +8414,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (genericParamInst->mTypeConstraint->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)genericParamInst->mTypeConstraint; - + // Let either an exact typematch or an undef pass through. Eventually instead of undefs we may want to do // actual expression comparisons, but we are overly permissive now and then we may fail on specialization if ((constExprValueType->mValue.mTypeCode != primType->mTypeDef->mTypeCode) && @@ -8319,32 +8461,43 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS convCheckConstraint = ResolveGenericType(convCheckConstraint, NULL, methodGenericArgs, mCurTypeInstance); if (convCheckConstraint == NULL) return false; - if (((checkArgType->IsMethodRef()) || (checkArgType->IsFunction())) && (convCheckConstraint->IsDelegate())) + if ((checkArgType->IsMethodRef()) || (checkArgType->IsFunction())) { - BfMethodInstance* checkMethodInstance; - if (checkArgType->IsMethodRef()) + if (convCheckConstraint->IsDelegate()) { - auto methodRefType = (BfMethodRefType*)checkArgType; - checkMethodInstance = methodRefType->mMethodRef; - } - else - { - checkMethodInstance = GetRawMethodInstanceAtIdx(checkArgType->ToTypeInstance(), 0, "Invoke"); - } - - auto invokeMethod = GetRawMethodInstanceAtIdx(convCheckConstraint->ToTypeInstance(), 0, "Invoke"); + BfMethodInstance* checkMethodInstance; + if (checkArgType->IsMethodRef()) + { + auto methodRefType = (BfMethodRefType*)checkArgType; + checkMethodInstance = methodRefType->mMethodRef; + } + else + { + checkMethodInstance = GetRawMethodInstanceAtIdx(checkArgType->ToTypeInstance(), 0, "Invoke"); + } - BfExprEvaluator exprEvaluator(this); - if (exprEvaluator.IsExactMethodMatch(checkMethodInstance, invokeMethod)) + auto invokeMethod = GetRawMethodInstanceAtIdx(convCheckConstraint->ToTypeInstance(), 0, "Invoke"); + + if (checkMethodInstance->HasExplicitThis() != 0) + { + // Don't allow functions with explicit 'this' + } + else + { + BfExprEvaluator exprEvaluator(this); + if (exprEvaluator.IsExactMethodMatch(checkMethodInstance, invokeMethod)) + constraintMatched = true; + } + } + else if (convCheckConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) constraintMatched = true; - } else if (CanCast(GetFakeTypedValue(checkArgType), convCheckConstraint)) { constraintMatched = true; } else if (origCheckArgType->IsWrappableType()) - { + { if (origCheckArgType->IsSizedArray()) { auto sizedArrayType = (BfSizedArrayType*)origCheckArgType; @@ -8358,7 +8511,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS auto constExprValueType = (BfConstExprValueType*)convCheckConstraintInst->mGenericTypeInfo->mTypeGenericArguments[1]; if (sizedArrayType->mElementCount == constExprValueType->mValue.mInt64) constraintMatched = true; - } + } } } } @@ -8390,8 +8543,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (convCheckConstraint == NULL) return false; - BfTypeInstance* typeConstraintInst = convCheckConstraint->ToTypeInstance(); - + BfTypeInstance* typeConstraintInst = convCheckConstraint->ToTypeInstance(); + bool implementsInterface = false; if (origCheckArgType != checkArgType) { @@ -8402,7 +8555,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS implementsInterface = CanCast(BfTypedValue(BfIRValue::sValueless, checkArgType), convCheckConstraint); if ((!implementsInterface) && (origCheckArgType->IsWrappableType())) - { + { BfTypeInstance* wrappedStructType = GetWrappedStructType(origCheckArgType, false); if (TypeIsSubTypeOf(wrappedStructType, typeConstraintInst)) implementsInterface = true; @@ -8415,11 +8568,11 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (TypeIsSubTypeOf(wrappedStructType, typeConstraintInst)) implementsInterface = true; } - + if (!implementsInterface) { if ((!ignoreErrors) && (PreFail())) - *errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must implement '%s'", genericParamInst->GetName().c_str(), + *errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must implement '%s'", genericParamInst->GetName().c_str(), TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(), TypeToString(checkConstraint).c_str()), checkArgTypeRef); return false; } @@ -8431,8 +8584,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if ((leftType != NULL) && (leftType->IsUnspecializedType())) leftType = ResolveGenericType(leftType, NULL, methodGenericArgs, mCurTypeInstance); if (leftType != NULL) - leftType = FixIntUnknown(leftType); - + leftType = FixIntUnknown(leftType); + auto rightType = checkOpConstraint.mRightType; if ((rightType != NULL) && (rightType->IsUnspecializedType())) rightType = ResolveGenericType(rightType, NULL, methodGenericArgs, mCurTypeInstance); @@ -8449,8 +8602,8 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS return false; if (checkOpConstraint.mBinaryOp != BfBinaryOp_None) - { - BfExprEvaluator exprEvaluator(this); + { + BfExprEvaluator exprEvaluator(this); BfTypedValue leftValue(mBfIRBuilder->GetFakeVal(), leftType); BfTypedValue rightValue(mBfIRBuilder->GetFakeVal(), rightType); @@ -8462,7 +8615,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS exprEvaluator.PerformBinaryOperation(NULL, NULL, checkOpConstraint.mBinaryOp, NULL, (BfBinOpFlags)(BfBinOpFlag_NoClassify | BfBinOpFlag_IsConstraintCheck), leftValue, rightValue); } - if ((!exprEvaluator.mResult) || + if ((!exprEvaluator.mResult) || (!CanCast(exprEvaluator.mResult, origCheckArgType, BfCastFlags_NoConversionOperator))) { if ((!ignoreErrors) && (PreFail())) @@ -8480,12 +8633,11 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS } return false; } - } else { BfTypedValue rightValue(mBfIRBuilder->GetFakeVal(), rightType); - + StringT<128> failedOpName; if (checkOpConstraint.mCastToken == BfToken_Implicit) @@ -8501,7 +8653,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS if (checkOpConstraint.mCastToken == BfToken_Explicit) { if (!CastToValue(NULL, rightValue, origCheckArgType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail | BfCastFlags_IsConstraintCheck))) - failedOpName = "explicit conversion from '"; + failedOpName = "explicit conversion from '"; } else { @@ -8527,7 +8679,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS ), checkArgTypeRef); return false; } - } + } } return true; @@ -8537,18 +8689,18 @@ BfGenericParamType* BfModule::GetGenericParamType(BfGenericParamKind paramKind, { if (paramIdx < (int)mContext->mGenericParamTypes[paramKind].size()) { - auto genericParamType = mContext->mGenericParamTypes[paramKind][paramIdx]; + auto genericParamType = mContext->mGenericParamTypes[paramKind][paramIdx]; return genericParamType; } auto genericParamType = new BfGenericParamType(); - + genericParamType->mContext = mContext; genericParamType->mGenericParamKind = paramKind; - genericParamType->mGenericParamIdx = paramIdx; + genericParamType->mGenericParamIdx = paramIdx; PopulateType(genericParamType); - + BF_ASSERT(paramIdx == (int)mContext->mGenericParamTypes[paramKind].size()); mContext->mGenericParamTypes[paramKind].push_back(genericParamType); @@ -8575,7 +8727,7 @@ BfTypedValue BfModule::FlushNullConditional(BfTypedValue result, bool ignoreNull auto notNullBB = mBfIRBuilder->GetInsertBlock(); - //TODO: Make this work, needed for 'void' and such + //TODO: Make this work, needed for 'void' and such BfType* nullableType = NULL; if ((result.mType->IsValueType()) && (!result.mType->IsNullable())) { @@ -8607,9 +8759,9 @@ BfTypedValue BfModule::FlushNullConditional(BfTypedValue result, bool ignoreNull // Do nothing } else if (elementType->IsValuelessType()) - { + { BfIRValue ptrValue = mBfIRBuilder->CreateInBoundsGEP(nullableTypedValue.mValue, 0, 1); // mHasValue - mBfIRBuilder->CreateStore(GetConstValue(1, GetPrimitiveType(BfTypeCode_Boolean)), ptrValue); + mBfIRBuilder->CreateStore(GetConstValue(1, GetPrimitiveType(BfTypeCode_Boolean)), ptrValue); } else { @@ -8617,7 +8769,7 @@ BfTypedValue BfModule::FlushNullConditional(BfTypedValue result, bool ignoreNull mBfIRBuilder->CreateAlignedStore(result.mValue, ptrValue, result.mType->mAlign); ptrValue = mBfIRBuilder->CreateInBoundsGEP(nullableTypedValue.mValue, 0, 2); // mHasValue mBfIRBuilder->CreateAlignedStore(GetConstValue(1, GetPrimitiveType(BfTypeCode_Boolean)), ptrValue, 1); - } + } result = nullableTypedValue; } mBfIRBuilder->CreateBr(pendingNullCond->mDoneBB); @@ -8636,10 +8788,10 @@ BfTypedValue BfModule::FlushNullConditional(BfTypedValue result, bool ignoreNull } result.mValue = phi; - } + } } else - { + { mBfIRBuilder->CreateBr(pendingNullCond->mDoneBB); mBfIRBuilder->SetInsertPoint(pendingNullCond->mPrevBB); @@ -8666,7 +8818,7 @@ BF_NOINLINE void BfModule::EvaluateWithNewConditionalScope(BfExprEvaluator& expr deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; mCurMethodState->mDeferredLocalAssignData = &deferredLocalAssignData; } - + BfScopeData newScope; newScope.mOuterIsConditional = true; newScope.mAllowTargeting = false; @@ -8674,7 +8826,7 @@ BF_NOINLINE void BfModule::EvaluateWithNewConditionalScope(BfExprEvaluator& expr { mCurMethodState->AddScope(&newScope); NewScopeState(true, false); - } + } exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | flags); exprEvaluator.Evaluate(expr, (flags & BfEvalExprFlags_PropogateNullConditional) != 0, (flags & BfEvalExprFlags_IgnoreNullConditional) != 0, (flags & BfEvalExprFlags_AllowSplat) != 0); @@ -8708,7 +8860,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, if (outOrigType != NULL) *outOrigType = NULL; - + exprEvaluator.mExpectingType = wantTypeRef; exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | flags); exprEvaluator.mExplicitCast = (flags & BfEvalExprFlags_ExplicitCast) != 0; @@ -8748,13 +8900,13 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, bool handled = false; if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) - { + { auto genericTypeConstraint = genericParamDef->mTypeConstraint; if (genericTypeConstraint != NULL) { auto underlyingConstraint = genericTypeConstraint; if ((underlyingConstraint != NULL) && (underlyingConstraint->IsBoxed())) - underlyingConstraint = underlyingConstraint->GetUnderlyingType(); + underlyingConstraint = underlyingConstraint->GetUnderlyingType(); if (underlyingConstraint != NULL) { BfTypedValue result; @@ -8763,8 +8915,8 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, result.mValue = mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(underlyingConstraint)); typedVal = result; handled = true; - } - } + } + } } if (!handled) @@ -8787,22 +8939,35 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, { // Only allow a 'ref' type if we have an explicit 'ref' operator bool allowRef = false; - BfExpression* checkExpr = expr; - while (auto parenExpr = BfNodeDynCast(checkExpr)) - checkExpr = parenExpr->mExpression; - if (auto unaryOp = BfNodeDynCast(checkExpr)) + BfAstNode* checkExpr = expr; + + while (checkExpr != NULL) { - if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut)) - allowRef = true; + if (auto parenExpr = BfNodeDynCast(checkExpr)) + checkExpr = parenExpr->mExpression; + else if (auto unaryOp = BfNodeDynCast(checkExpr)) + { + if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut)) + allowRef = true; + break; + } + if (auto block = BfNodeDynCast(checkExpr)) + { + if (block->mChildArr.mSize == 0) + break; + checkExpr = block->mChildArr.back(); + } + else + break; } if (!allowRef) typedVal = RemoveRef(typedVal); } - } + } if ((!typedVal.mType->IsComposite()) && (!typedVal.mType->IsGenericParam())) // Load non-structs by default { - if ((!mBfIRBuilder->mIgnoreWrites) && (!typedVal.mType->IsValuelessType()) && (!typedVal.mType->IsVar())) + if ((!mBfIRBuilder->mIgnoreWrites) && (!typedVal.mType->IsDataIncomplete()) && (!typedVal.mType->IsValuelessType()) && (!typedVal.mType->IsVar())) { BF_ASSERT(!typedVal.mValue.IsFake()); } @@ -8830,13 +8995,13 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, } if ((typedVal.mType->IsValueType()) && ((flags & BfEvalExprFlags_NoValueAddr) != 0)) - typedVal = LoadValue(typedVal, 0, exprEvaluator.mIsVolatileReference); + typedVal = LoadValue(typedVal, 0, exprEvaluator.mIsVolatileReference); return typedVal; } BfTypedValue BfModule::CreateValueFromExpression(BfExpression* expr, BfType* wantTypeRef, BfEvalExprFlags flags, BfType** outOrigType) -{ +{ BfExprEvaluator exprEvaluator(this); return CreateValueFromExpression(exprEvaluator, expr, wantTypeRef, flags, outOrigType); } @@ -8844,7 +9009,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExpression* expr, BfType* wan BfTypedValue BfModule::GetOrCreateVarAddr(BfExpression* expr) { BfExprEvaluator exprEvaluator(this); - exprEvaluator.Evaluate(expr); + exprEvaluator.Evaluate(expr); if (!exprEvaluator.mResult) { Fail("Invalid expression type", expr); @@ -8871,14 +9036,14 @@ void BfModule::InitTypeInst(BfTypedValue typedValue, BfScopeData* scopeData, boo } if (!typedValue.mType->IsObject()) - { + { return; } if ((scopeData == NULL) && (mCurMethodState != NULL)) return; // Handled in heap alloc funcs - - auto typeDef = typeInstance->mTypeDef; + + auto typeDef = typeInstance->mTypeDef; mBfIRBuilder->PopulateType(typedValue.mType); auto vObjectAddr = mBfIRBuilder->CreateInBoundsGEP(typedValue.mValue, 0, 0); @@ -8898,28 +9063,35 @@ void BfModule::InitTypeInst(BfTypedValue typedValue, BfScopeData* scopeData, boo PopulateType(ptrType, BfPopulateType_Declaration); auto destAddr = mBfIRBuilder->CreateBitCast(vObjectAddr, mBfIRBuilder->MapType(ptrPtrType)); if (!isAutocomplete) - { + { if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) { auto objectPtr = mBfIRBuilder->CreateBitCast(destAddr, mBfIRBuilder->MapType(mContext->mBfObjectType)); SizedArray llvmArgs; - llvmArgs.push_back(objectPtr); - llvmArgs.push_back(vDataRef); + llvmArgs.push_back(objectPtr); + llvmArgs.push_back(vDataRef); auto objectStackInitMethod = GetInternalMethod("Dbg_ObjectStackInit"); if (objectStackInitMethod) mBfIRBuilder->CreateCall(objectStackInitMethod.mFunc, llvmArgs); } else - { + { auto srcVal = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapType(ptrType)); auto objectPtr = mBfIRBuilder->CreateBitCast(destAddr, mBfIRBuilder->MapType(ptrType)); - mBfIRBuilder->CreateStore(srcVal, destAddr); + mBfIRBuilder->CreateStore(srcVal, destAddr); } } } +bool BfModule::IsAllocatorAligned() +{ + if (mCompiler->mOptions.mMallocLinkName == "StompAlloc") + return false; + return true; +} + BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTarget, BfType* type, BfIRValue sizeValue, BfIRValue alignValue, BfAllocFlags allocFlags/*, bool zeroMemory, bool defaultToMalloc*/) { BfIRValue result; @@ -8949,13 +9121,13 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar BfTypedValue allocResult; if (allocTarget.mScopedInvocationTarget != NULL) - { + { SizedArray genericArgs; exprEvaluator.DoInvocation(allocTarget.mScopedInvocationTarget, NULL, argExprs, BfMethodGenericArguments()); allocResult = LoadValue(exprEvaluator.mResult); } else if (allocTarget.mCustomAllocator) - { + { auto customTypeInst = allocTarget.mCustomAllocator.mType->ToTypeInstance(); if (customTypeInst == NULL) { @@ -8976,7 +9148,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar allocMethodName = "AllocTyped"; auto typeType = ResolveTypeDef(mCompiler->mTypeTypeDef); auto typeRefVal = CreateTypeDataRef(type); - + typeValueExpr.Init(BfTypedValue(typeRefVal, typeType)); typeValueExpr.mRefNode = refNode; argExprs.Insert(0, &typeValueExpr); @@ -8999,7 +9171,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar SetAndRestoreValue prevNoBind(mCurMethodState->mNoBind, true); allocResult = exprEvaluator.MatchMethod(refNode, NULL, allocTarget.mCustomAllocator, false, false, allocMethodName, argValues, BfMethodGenericArguments()); } - } + } } if (allocResult) @@ -9014,12 +9186,12 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar if ((allocFlags & BfAllocFlags_NoDefaultToMalloc) != 0) return result; - + if ((mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule)) { BfIRValue allocData = GetDbgRawAllocData(type); BfModuleMethodInstance allocMethod = GetInternalMethod("Dbg_RawAlloc", 2); - + SizedArray llvmArgs; llvmArgs.push_back(sizeValue); llvmArgs.push_back(allocData); @@ -9029,10 +9201,10 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar BfModuleMethodInstance moduleMethodInstance; moduleMethodInstance = GetInternalMethod("Malloc"); - + SizedArray llvmArgs; llvmArgs.push_back(sizeValue); - + auto func = moduleMethodInstance.mFunc; if ((!func) || (func.IsFake())) @@ -9040,7 +9212,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar BF_ASSERT((mCompiler->mIsResolveOnly) || (mBfIRBuilder->mIgnoreWrites)); return mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(ptrType)); } - BfIRValue bitData = mBfIRBuilder->CreateCall(func, llvmArgs); + BfIRValue bitData = mBfIRBuilder->CreateCall(func, llvmArgs); if ((allocFlags & BfAllocFlags_ZeroMemory) != 0) mBfIRBuilder->CreateMemSet(bitData, GetConstValue8(0), sizeValue, alignValue); result = mBfIRBuilder->CreateBitCast(bitData, mBfIRBuilder->MapType(ptrType)); @@ -9059,15 +9231,15 @@ BfIRValue BfModule::GetMarkFuncPtr(BfType* type) else if (type->IsObjectOrInterface()) { auto gcType = ResolveTypeDef(mCompiler->mGCTypeDef)->ToTypeInstance(); - BfModuleMethodInstance moduleMethodInst = GetMethodByName(gcType, "MarkDerefedObject"); + BfModuleMethodInstance moduleMethodInst = GetMethodByName(gcType, "MarkDerefedObject"); BF_ASSERT(moduleMethodInst.mFunc); return mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_NullPtr))); } else { auto gcType = ResolveTypeDef(mCompiler->mGCTypeDef)->ToTypeInstance(); - - BfExprEvaluator exprEvaluator(this); + + BfExprEvaluator exprEvaluator(this); SizedArray resolvedArgs; BfResolvedArg resolvedArg; resolvedArg.mTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), type, type->IsComposite()); @@ -9088,7 +9260,7 @@ BfIRValue BfModule::GetDbgRawAllocData(BfType* type) BfIRValue allocDataValue; if (mDbgRawAllocDataRefs.TryGetValue(type, &allocDataValue)) return allocDataValue; - + BfIRValue markFuncPtr; if (type->WantsGCMarking()) markFuncPtr = GetMarkFuncPtr(type); @@ -9135,7 +9307,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget BF_ASSERT(!type->IsVar()); - auto typeInstance = type->ToTypeInstance(); + auto typeInstance = type->ToTypeInstance(); if ((typeInstance == NULL) && (type->IsGenericParam())) typeInstance = mContext->mBfObjectType; @@ -9150,9 +9322,9 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget if ((type->IsValuelessType()) && ((!arraySize) || (isRawArrayAlloc))) { - BfPointerType* ptrType = CreatePointerType(type); + BfPointerType* ptrType = CreatePointerType(type); auto val = mBfIRBuilder->CreateIntToPtr(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mBfIRBuilder->MapType(ptrType)); - return val; + return val; } if (typeInstance != NULL) @@ -9172,8 +9344,8 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget int allocSize = type->mSize; int allocAlign = type->mAlign; if (typeInstance != NULL) - { - if (!mBfIRBuilder->mIgnoreWrites) + { + if ((!mBfIRBuilder->mIgnoreWrites) && (!mIsComptimeModule)) typeInstance->mHasBeenInstantiated = true; allocSize = typeInstance->mInstSize; allocAlign = typeInstance->mInstAlign; @@ -9181,7 +9353,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget //if (typeInstance->IsEnum()) //allocType = typeInstance->mIRType; allocType = mBfIRBuilder->MapTypeInst(typeInstance); - } + } if (alignOverride != -1) allocAlign = alignOverride; @@ -9190,7 +9362,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget // If we are not dyn, but we are a variable size and could be looped over multiple times then we attempt to reuse // the last stack space. We won't use StackSave and StackRestore because a scoped alloc that occurs after this but // needs to be retained after the current scopeData (ie: scopeData::), then it would cause these allocs to accumulate even - // though we'd expect their stack space to be released + // though we'd expect their stack space to be released auto _CreateDynAlloc = [&](const BfIRValue& sizeValue, int align) { MarkDynStack(scopeData); @@ -9211,7 +9383,6 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget mBfIRBuilder->SetInsertPoint(prevInsertBlock); } - auto byteType = GetPrimitiveType(BfTypeCode_Int8); auto bytePtrType = CreatePointerType(byteType); @@ -9235,7 +9406,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget mBfIRBuilder->SetAllocaForceMem(dynSizeAllocaInst); mBfIRBuilder->SetAllocaForceMem(dynPtrAllocaInst); } - + auto resizeBB = mBfIRBuilder->CreateBlock("dynAlloc.resize"); auto endBB = mBfIRBuilder->CreateBlock("dynAlloc.end"); auto verCheckBB = mBfIRBuilder->CreateBlock("dynAlloc.verCheck"); @@ -9253,7 +9424,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget mBfIRBuilder->CreateCondBr(dynStackChanged, resizeBB, endBB); mBfIRBuilder->AddBlock(resizeBB); - mBfIRBuilder->SetInsertPoint(resizeBB); + mBfIRBuilder->SetInsertPoint(resizeBB); auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(byteType), sizeValue); mBfIRBuilder->SetAllocaAlignment(allocaInst, align); mBfIRBuilder->CreateStore(allocaInst, dynPtrAllocaInst); @@ -9270,12 +9441,12 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget { if (arraySize) { - bool isConstantArraySize = arraySize.IsConst(); + bool isConstantArraySize = arraySize.IsConst(); if (isRawArrayAlloc) { BfPointerType* ptrType = CreatePointerType(type); if ((!isDynAlloc) && (!isConstantArraySize) && (mCurMethodState->mCurScope->IsLooped(NULL))) - { + { BfIRValue sizeValue = mBfIRBuilder->CreateMul(GetConstValue(type->GetStride()), arraySize); auto loadedPtr = _CreateDynAlloc(sizeValue, type->mAlign); InitTypeInst(BfTypedValue(loadedPtr, ptrType), scopeData, zeroMemory, sizeValue); @@ -9283,23 +9454,23 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } else { - auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); + auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); isDynAlloc = (isDynAlloc) || (!arraySize.IsConst()); if (!isDynAlloc) - mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); + mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); else { MarkDynStack(scopeData); SaveStackState(scopeData); } - + int typeSize = type->GetStride(); BfIRValue allocaInst; BfIRValue result; if ((typeInstance == NULL) || (typeInstance->mIsCRepr)) - { - allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type), arraySize); + { + allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type), arraySize); result = allocaInst; } else @@ -9316,7 +9487,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } if (!isDynAlloc) mBfIRBuilder->ClearDebugLocation(allocaInst); - mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign); + mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign); if (!isDynAlloc) mBfIRBuilder->SetInsertPoint(prevInsertBlock); auto typedVal = BfTypedValue(result, type, BfTypedValueKind_Addr); @@ -9333,7 +9504,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget bool isConstSize = arraySize.IsConst(); BfIRBlock clearBlock; BfIRBlock contBlock; - + bool wantsDeinit = ((!IsOptimized()) && (!mIsComptimeModule) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly)); if (wantsDeinit) @@ -9345,7 +9516,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget clearBlock = mBfIRBuilder->CreateBlock("clear"); contBlock = mBfIRBuilder->CreateBlock("clearCont"); - prevBlock = mBfIRBuilder->GetInsertBlock(); + prevBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->AddBlock(clearBlock); mBfIRBuilder->SetInsertPoint(clearBlock); @@ -9374,15 +9545,15 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget mBfIRBuilder->SetInsertPoint(contBlock); } } - } + } return result; } } else - { + { if ((!isDynAlloc) && (!arraySize.IsConst()) && (mCurMethodState->mCurScope->IsLooped(NULL))) - { + { // Generate and check new size BfArrayType* arrayType = CreateArrayType(type, arrayDim); auto firstElementField = &arrayType->mFieldInstances.back(); @@ -9401,7 +9572,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget else { BfArrayType* arrayType = CreateArrayType(type, arrayDim); - auto firstElementField = &arrayType->mFieldInstances.back(); + auto firstElementField = &arrayType->mFieldInstances.back(); if (!type->IsValuelessType()) { @@ -9412,7 +9583,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } else sizeValue = GetConstValue(arrayType->mInstSize); - + auto prevBlock = mBfIRBuilder->GetInsertBlock(); isDynAlloc = (isDynAlloc) || (!sizeValue.IsConst()); if (!isDynAlloc) @@ -9422,15 +9593,15 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget MarkDynStack(scopeData); SaveStackState(scopeData); } - + BfType* byteType = GetPrimitiveType(BfTypeCode_Int8); auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(byteType), sizeValue); if (!isDynAlloc) mBfIRBuilder->ClearDebugLocation(allocaInst); auto allocaBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign); - - BfTypedValue typedVal; + + BfTypedValue typedVal; if (!isDynAlloc) { mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRInitBlock); @@ -9440,7 +9611,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget allocaBlock = mCurMethodState->mIRInitBlock; } else - typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType); + typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(arrayType)), arrayType); if (!noDtorCall) AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true, allocaBlock); @@ -9456,19 +9627,19 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget // use the "dynSize" version conservatively if ((!isDynAlloc) && (!appendSizeValue.IsConst()) && (mCurMethodState->mCurScope->IsLooped(NULL))) { - // Generate and check new size + // Generate and check new size sizeValue = GetConstValue(typeInstance->mInstSize); sizeValue = mBfIRBuilder->CreateAdd(sizeValue, appendSizeValue); auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign); - auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance); + auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance); if (!noDtorCall) AddStackAlloc(typedVal, arraySize, NULL, scopeData, mCurMethodState->mInConditionalBlock, true); InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); return typedVal.mValue; } else // stack alloc, unlooped, with append - { + { sizeValue = GetConstValue(typeInstance->mInstSize); sizeValue = mBfIRBuilder->CreateAdd(sizeValue, appendSizeValue); auto prevBlock = mBfIRBuilder->GetInsertBlock(); @@ -9485,17 +9656,17 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget auto allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(sbyteType), sizeValue); if (!isDynAlloc) { - mBfIRBuilder->ClearDebugLocation(allocaInst); + mBfIRBuilder->ClearDebugLocation(allocaInst); } mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign); - - bool mayBeLarge = false; + + bool mayBeLarge = false; if (sizeValue.IsConst()) { auto constantInt = mBfIRBuilder->GetConstant(sizeValue); if (constantInt->mInt64 >= 4096) mayBeLarge = true; - } + } else mayBeLarge = true; @@ -9523,7 +9694,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget { castedVal = mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapTypeInstPtr(typeInstance)); } - + auto typedVal = BfTypedValue(castedVal, typeInstance); if (!noDtorCall) { @@ -9532,15 +9703,15 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock; AddStackAlloc(typedVal, arraySize, NULL, scopeData, doCondAlloca, true); } - InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); - + InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue); + return typedVal.mValue; } } else // "Normal" stack alloc { BF_ASSERT(!sizeValue); - //TODO: If sizeValue is a constant then do this in the head IR builder + //TODO: If sizeValue is a constant then do this in the head IR builder auto prevBlock = mBfIRBuilder->GetInsertBlock(); if (!isLoopedAlloc) mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); @@ -9549,7 +9720,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget MarkDynStack(scopeData); SaveStackState(scopeData); } - auto allocaInst = mBfIRBuilder->CreateAlloca(allocType); + auto allocaInst = mBfIRBuilder->CreateAlloca(allocType); if (!isLoopedAlloc) mBfIRBuilder->ClearDebugLocation(allocaInst); mBfIRBuilder->SetAllocaAlignment(allocaInst, allocAlign); @@ -9558,7 +9729,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget // If we create a memset that can fill in backwards (or at least 4k chunked backward) then we can remove the '!mayBeLarge' cond ((zeroMemory) && (!mayBeLarge))) { - // With an object, we know we will at least set the vdata pointer which will probe the start of the new address, + // With an object, we know we will at least set the vdata pointer which will probe the start of the new address, // and memset is always safe mBfIRBuilder->SetAllocaNoChkStkHint(allocaInst); } @@ -9583,35 +9754,35 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget { mBfIRBuilder->CreateMemSet(allocaInst, GetConstValue8(0), GetConstValue(allocSize), allocAlign); } - return allocaInst; - } + return allocaInst; + } } else if (arraySize) - { + { if (isRawArrayAlloc) - { + { sizeValue = mBfIRBuilder->CreateMul(GetConstValue(type->GetStride()), arraySize); return AllocBytes(allocTarget.mRefNode, allocTarget, type, sizeValue, GetConstValue(allocAlign), allocFlags); } else - { + { BfArrayType* arrayType = CreateArrayType(type, arrayDim); typeInstance = arrayType; BfIRValue arraySizeMinusOne = mBfIRBuilder->CreateSub(arraySize, GetConstValue(1)); BfIRValue elementDataSize = mBfIRBuilder->CreateMul(GetConstValue(type->GetStride()), arraySizeMinusOne); appendSizeValue = elementDataSize; - + if (!type->IsSizeAligned()) { appendSizeValue = mBfIRBuilder->CreateAdd(appendSizeValue, GetConstValue(type->GetStride() - type->mSize)); - } + } } } - + if ((typeInstance != NULL) && (typeInstance->IsObject())) { - auto vDataRef = GetClassVDataPtr(typeInstance); - BfIRValue result; + auto vDataRef = GetClassVDataPtr(typeInstance); + BfIRValue result; bool isResultInitialized = false; int stackCount = mCompiler->mOptions.mAllocStackCount; @@ -9642,7 +9813,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget auto addlBytes = mBfIRBuilder->CreateCall(prepareStackTraceMethod.mFunc, irArgs); sizeValue = mBfIRBuilder->CreateAdd(sizeValue, addlBytes); } - } + } if (allocTarget.mCustomAllocator) { @@ -9658,10 +9829,10 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget auto typePtr = mBfIRBuilder->CreateLoad(typePtrPtr); auto typeInstPtr = mBfIRBuilder->CreateBitCast(typePtr, mBfIRBuilder->MapTypeInstPtr(typeInstType)); - BfTypedValueExpression typedValueExpr; + BfTypedValueExpression typedValueExpr; typedValueExpr.Init(BfTypedValue(typeInstPtr, typeInstType)); typedValueExpr.mRefNode = allocTarget.mRefNode; - + BfExprEvaluator exprEvaluator(this); SizedArray argExprs; argExprs.push_back(&typedValueExpr); @@ -9677,7 +9848,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget exprEvaluator.mNoBind = true; BfTypedValue allocResult = exprEvaluator.MatchMethod(allocTarget.mRefNode, NULL, allocTarget.mCustomAllocator, false, false, "AllocObject", argValues, BfMethodGenericArguments()); if (allocResult) - { + { if ((allocResult.mType->IsVoidPtr()) || (allocResult.mType == mContext->mBfObjectType)) result = mBfIRBuilder->CreateBitCast(allocResult.mValue, mBfIRBuilder->MapType(typeInstance)); else @@ -9685,13 +9856,13 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget isResultInitialized = true; } } - } + } bool wasAllocated = false; if (!result) - { + { if (hasCustomAllocator) - result = AllocBytes(allocTarget.mRefNode, allocTarget, typeInstance, sizeValue, GetConstValue(typeInstance->mInstAlign), (BfAllocFlags)(BfAllocFlags_ZeroMemory | BfAllocFlags_NoDefaultToMalloc)); + result = AllocBytes(allocTarget.mRefNode, allocTarget, typeInstance, sizeValue, GetConstValue(typeInstance->mInstAlign), (BfAllocFlags)(BfAllocFlags_ZeroMemory | BfAllocFlags_NoDefaultToMalloc)); else if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mCompiler->mOptions.mDebugAlloc) && (!mIsComptimeModule)) { SizedArray llvmArgs; @@ -9704,7 +9875,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } if (result) - { + { if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) { auto objectPtr = mBfIRBuilder->CreateBitCast(result, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType)); @@ -9712,8 +9883,8 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget llvmArgs.push_back(objectPtr); llvmArgs.push_back(origSizeValue); llvmArgs.push_back(vDataRef); - auto objectCreatedMethod = GetInternalMethod(isAllocEx ? - (isResultInitialized ? "Dbg_ObjectCreatedEx" : "Dbg_ObjectAllocatedEx") : + auto objectCreatedMethod = GetInternalMethod(isAllocEx ? + (isResultInitialized ? "Dbg_ObjectCreatedEx" : "Dbg_ObjectAllocatedEx") : (isResultInitialized ? "Dbg_ObjectCreated" : "Dbg_ObjectAllocated")); mBfIRBuilder->CreateCall(objectCreatedMethod.mFunc, llvmArgs); @@ -9728,21 +9899,21 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } } else - { + { auto ptrType = mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr); auto vDataPtr = mBfIRBuilder->CreateBitCast(vDataRef, ptrType); - auto vDataMemberPtr = mBfIRBuilder->CreateBitCast(result, mBfIRBuilder->GetPointerTo(ptrType)); + auto vDataMemberPtr = mBfIRBuilder->CreateBitCast(result, mBfIRBuilder->GetPointerTo(ptrType)); mBfIRBuilder->CreateStore(vDataPtr, vDataMemberPtr); } - } + } else - { - if ((mBfIRBuilder->mIgnoreWrites) || + { + if ((mBfIRBuilder->mIgnoreWrites) || ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule))) return GetDefaultValue(typeInstance); - auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); - auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())); + auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); + auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())); if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) { @@ -9766,18 +9937,18 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget irFunc = moduleMethodInstance.mFunc; } if (!irFunc) - irFunc = GetBuiltInFunc(BfBuiltInFuncType_Malloc); + irFunc = GetBuiltInFunc(BfBuiltInFuncType_Malloc); BfIRValue objectVal = mBfIRBuilder->CreateCall(irFunc, llvmArgs); auto objResult = mBfIRBuilder->CreateBitCast(objectVal, mBfIRBuilder->MapType(mContext->mBfObjectType, BfIRPopulateType_Full)); auto vdataPtr = mBfIRBuilder->CreateInBoundsGEP(objResult, 0, 0); if (mIsComptimeModule) - { + { vdataPtr = mBfIRBuilder->CreateBitCast(vdataPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance()))); } mBfIRBuilder->CreateStore(vData, vdataPtr); - result = mBfIRBuilder->CreateBitCast(objectVal, mBfIRBuilder->MapType(typeInstance)); + result = mBfIRBuilder->CreateBitCast(objectVal, mBfIRBuilder->MapType(typeInstance)); } } @@ -9788,7 +9959,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget auto firstElementField = &arrayType->mFieldInstances.back(); int arrayClassSize = firstElementField->mDataOffset; - BfIRValue elementDataSize; + BfIRValue elementDataSize; bool skipZero = false; if (arraySize.IsConst()) { @@ -9817,13 +9988,13 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget } } - return result; - } + return result; + } else - { + { if (!sizeValue) sizeValue = GetConstValue(allocSize); - return AllocBytes(allocTarget.mRefNode, allocTarget, type, sizeValue, GetConstValue(allocAlign), zeroMemory ? BfAllocFlags_ZeroMemory : BfAllocFlags_None); + return AllocBytes(allocTarget.mRefNode, allocTarget, type, sizeValue, GetConstValue(allocAlign), zeroMemory ? BfAllocFlags_ZeroMemory : BfAllocFlags_None); } } @@ -9836,23 +10007,21 @@ void BfModule::ValidateAllocation(BfType* type, BfAstNode* refNode) Fail(StrFormat("Unable to allocate opaque type '%s'", TypeToString(type).c_str()), refNode); } -void BfModule::EmitAlign(BfIRValue& appendCurIdx, int align) -{ - appendCurIdx = mBfIRBuilder->CreateAdd(appendCurIdx, GetConstValue(align - 1)); - appendCurIdx = mBfIRBuilder->CreateAnd(appendCurIdx, GetConstValue(~(align - 1))); -} - void BfModule::EmitAppendAlign(int align, int sizeMultiple) -{ +{ if (sizeMultiple == 0) sizeMultiple = align; if ((mCurMethodState->mCurAppendAlign != 0) && (mCurMethodState->mCurAppendAlign % align != 0)) { - if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) + if (!IsAllocatorAligned()) + { + // Don't align + } + else if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor) { auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1]; BF_ASSERT(localVar->mName == "appendIdx"); - auto appendIdxVal = BfTypedValue(localVar->mValue, localVar->mResolvedType, true); + auto appendIdxVal = BfTypedValue(localVar->mValue, localVar->mResolvedType, true); BfIRValue appendCurIdx = mBfIRBuilder->CreateLoad(appendIdxVal.mValue); if (align > 1) { @@ -9865,15 +10034,15 @@ void BfModule::EmitAppendAlign(int align, int sizeMultiple) { BF_ASSERT(mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend); BfIRValue appendCurIdxPtr = mCurMethodState->mRetVal.mValue; - BfIRValue appendCurIdx = mBfIRBuilder->CreateLoad(appendCurIdxPtr); + BfIRValue appendCurIdx = mBfIRBuilder->CreateLoad(appendCurIdxPtr); appendCurIdx = mBfIRBuilder->CreateAdd(appendCurIdx, GetConstValue(align - 1)); appendCurIdx = mBfIRBuilder->CreateAnd(appendCurIdx, GetConstValue(~(align - 1))); mBfIRBuilder->CreateStore(appendCurIdx, appendCurIdxPtr); - } + } } - if (mCurMethodState->mCurAppendAlign == 0) - mCurMethodState->mCurAppendAlign = sizeMultiple; + if (mCurMethodState->mCurAppendAlign == 0) + mCurMethodState->mCurAppendAlign = sizeMultiple; else { if (sizeMultiple % align == 0) @@ -9884,9 +10053,9 @@ void BfModule::EmitAppendAlign(int align, int sizeMultiple) } BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, int appendAllocAlign, BfIRValue arraySize, int arrayDim, bool isRawArrayAlloc, bool zeroMemory) -{ +{ auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1]; - BF_ASSERT(localVar->mName == "appendIdx"); + BF_ASSERT(localVar->mName == "appendIdx"); BfTypedValue appendIdxVal(localVar->mValue, localVar->mResolvedType, true); BfIRValue retValue; @@ -9895,7 +10064,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); if (arraySize) - { + { if (isRawArrayAlloc) { EmitAppendAlign(type->mAlign); @@ -9906,7 +10075,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, sizeValue = mBfIRBuilder->CreateNumericCast(sizeValue, true, (intPtrType->mSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64); auto newIdxVal = mBfIRBuilder->CreateAdd(curIdxVal, sizeValue); mBfIRBuilder->CreateStore(newIdxVal, appendIdxVal.mValue); - + if (zeroMemory) { auto ptr = mBfIRBuilder->CreateIntToPtr(curIdxVal, mBfIRBuilder->MapType(voidPtrType)); @@ -9922,7 +10091,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, auto firstElementField = &arrayType->mFieldInstances.back(); int arrayClassSize = arrayType->mInstSize - firstElementField->mDataSize; - + BfIRValue sizeValue = GetConstValue(arrayClassSize); BfIRValue elementDataSize = mBfIRBuilder->CreateMul(GetConstValue(type->mSize), arraySize); sizeValue = mBfIRBuilder->CreateAdd(sizeValue, elementDataSize); @@ -9957,11 +10126,11 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, EmitAppendAlign(typeInst->mInstAlign, typeInst->mInstSize); sizeValue = GetConstValue(typeInst->mInstSize); toType = mBfIRBuilder->MapTypeInstPtr(typeInst); - } + } else { EmitAppendAlign(type->mAlign, type->mSize); - sizeValue = GetConstValue(type->mSize); + sizeValue = GetConstValue(type->mSize); auto toPtrType = CreatePointerType(type); toType = mBfIRBuilder->MapType(toPtrType); } @@ -9995,7 +10164,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, auto vObjectAddr = mBfIRBuilder->CreateInBoundsGEP(retValue, 0, 0); auto vDataRef = CreateClassVDataGlobal(retTypeInstance); - + auto destAddr = mBfIRBuilder->CreateBitCast(vObjectAddr, ptrPtrType); auto srcVal = mBfIRBuilder->CreateBitCast(vDataRef, ptrType); mBfIRBuilder->CreateStore(srcVal, destAddr); @@ -10019,7 +10188,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, } bool BfModule::IsOptimized() -{ +{ if (mProject == NULL) return false; if (mIsComptimeModule) @@ -10066,7 +10235,7 @@ void BfModule::SkipObjectAccessCheck(BfTypedValue typedVal) if ((!mCompiler->mOptions.mObjectHasDebugFlags) || (mIsComptimeModule)) return; - + if ((typedVal.mValue.mFlags & BfIRValueFlags_Value) == 0) return; @@ -10098,13 +10267,13 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal) if (typeOptions != NULL) emitObjectAccessCheck = typeOptions->Apply(emitObjectAccessCheck, BfOptionFlags_EmitObjectAccessCheck); if (!emitObjectAccessCheck) - return; + return; if ((typedVal.mValue.mFlags & BfIRValueFlags_Value) != 0) - { + { if (mCurMethodState->mSkipObjectAccessChecks.Contains(typedVal.mValue.mId)) return; - } + } if (typedVal.IsAddr()) typedVal = LoadValue(typedVal); @@ -10128,10 +10297,10 @@ void BfModule::EmitEnsureInstructionAt() } void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds) -{ +{ if (mBfIRBuilder->mIgnoreWrites) return; // Nothing needed here - + auto irb = mBfIRBuilder; auto checkBB = irb->CreateBlock("as.check"); @@ -10145,7 +10314,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult, GetDefaultValue(mContext->mBfObjectType)); irb->CreateCondBr(cmpResult, trueBlock, falseBlock); return; - } + } auto intType = GetPrimitiveType(BfTypeCode_IntPtr); auto intPtrType = CreatePointerType(intType); @@ -10154,9 +10323,9 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar auto int32PtrType = CreatePointerType(int32Type); auto typeTypeInstance = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef)->ToTypeInstance(); - + if (mCompiler->mOptions.mAllowHotSwapping) - { + { BfExprEvaluator exprEvaluator(this); AddBasicBlock(checkBB); @@ -10176,7 +10345,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar vDataPtr = irb->CreateLoad(vDataPtr); if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) vDataPtr = irb->CreateAnd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL)); - + if (targetType->IsInterface()) { auto targetTypeInst = targetType->ToTypeInstance(); @@ -10234,7 +10403,7 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al emitDynamicCastCheck = typeOptions->Apply(emitDynamicCastCheck, BfOptionFlags_EmitDynamicCastCheck); if (emitDynamicCastCheck) - { + { int wantTypeId = 0; if (!type->IsGenericParam()) wantTypeId = type->mTypeId; @@ -10274,7 +10443,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { bool callDtor = (castFlags & BfCastFlags_NoBoxDtor) == 0; bool wantConst = ((castFlags & BfCastFlags_WantsConst) != 0) && (typedVal.mValue.IsConst()); - + if ((mBfIRBuilder->mIgnoreWrites) && (!wantConst)) { if (toType == mContext->mBfObjectType) @@ -10296,7 +10465,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance(); if (typedVal.mType->IsNullable()) - { + { typedVal = MakeAddressable(typedVal); auto innerType = typedVal.mType->GetUnderlyingType(); @@ -10306,7 +10475,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp Fail("Only value types can be boxed", srcNode); return BfTypedValue(); } - + auto boxedType = CreateBoxedType(innerType); auto resultType = toType; if (resultType == NULL) @@ -10324,16 +10493,16 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto hasValue = mBfIRBuilder->CreateLoad(hasValueAddr); mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB); - + AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); - + mBfIRBuilder->AddBlock(boxBB); mBfIRBuilder->SetInsertPoint(boxBB); BfScopeData newScope; newScope.mOuterIsConditional = true; mCurMethodState->AddScope(&newScope); NewScopeState(); - + BfIRValue nullableValueAddr; BfIRValue loadedVal; if (innerType->IsValuelessType()) @@ -10345,11 +10514,11 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp nullableValueAddr = mBfIRBuilder->CreateInBoundsGEP(typedVal.mValue, 0, 1); // value loadedVal = mBfIRBuilder->CreateLoad(nullableValueAddr); } - + auto boxedVal = BoxValue(srcNode, BfTypedValue(loadedVal, fromStructTypeInstance->GetUnderlyingType()), resultType, allocTarget, callDtor ? BfCastFlags_None : BfCastFlags_NoBoxDtor); RestoreScopeState(); if (!boxedVal) - return BfTypedValue(); + return BfTypedValue(); mBfIRBuilder->CreateBr(endBB); auto boxBBEnd = mBfIRBuilder->GetInsertBlock(); @@ -10358,10 +10527,10 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto phi = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(resultType), 2); mBfIRBuilder->AddPhiIncoming(phi, boxedVal.mValue, boxBBEnd); mBfIRBuilder->AddPhiIncoming(phi, GetDefaultValue(resultType), prevBB); - - return BfTypedValue(phi, resultType); - } - + + return BfTypedValue(phi, resultType); + } + bool alreadyCheckedCast = false; BfTypeInstance* toTypeInstance = NULL; @@ -10369,10 +10538,10 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp toTypeInstance = toType->ToTypeInstance(); bool isStructPtr = typedVal.mType->IsStructPtr(); - if (fromStructTypeInstance == NULL) - { - auto primType = (BfPrimitiveType*)typedVal.mType; - + if (fromStructTypeInstance == NULL) + { + auto primType = (BfPrimitiveType*)typedVal.mType; + if ((typedVal.mType->IsPointer()) && (toTypeInstance->IsInstanceOf(mCompiler->mIHashableTypeDef))) { // Can always do IHashable @@ -10394,23 +10563,23 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp alreadyCheckedCast = true; fromStructTypeInstance = typedVal.mType->GetUnderlyingType()->ToTypeInstance(); - } - + } + if ((fromStructTypeInstance == NULL) && (alreadyCheckedCast)) fromStructTypeInstance = GetWrappedStructType(typedVal.mType); } if (fromStructTypeInstance == NULL) - return BfTypedValue(); + return BfTypedValue(); - // Need to box it + // Need to box it bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()); - + if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) { if ((mBfIRBuilder->mIgnoreWrites) && (!wantConst)) return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType)); - auto boxedType = CreateBoxedType(typedVal.mType); + auto boxedType = CreateBoxedType(typedVal.mType); mBfIRBuilder->PopulateType(boxedType); if (wantConst) @@ -10418,10 +10587,10 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall); - - BfTypedValue boxedTypedValue(allocaInst, boxedType); + + BfTypedValue boxedTypedValue(allocaInst, boxedType); mBfIRBuilder->SetName(allocaInst, "boxed." + fromStructTypeInstance->mTypeDef->mName->ToString()); - + if (boxedType->IsUnspecializedType()) { BF_ASSERT((srcNode == NULL) || (mCurMethodInstance->mIsUnspecialized)); @@ -10444,9 +10613,9 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { AggregateSplatIntoAddr(typedVal, valPtr); } - else + else mBfIRBuilder->CreateStore(typedVal.mValue, valPtr, typedVal.mType->mAlign); - } + } } if (toType == NULL) @@ -10457,14 +10626,14 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { auto castedValue = mBfIRBuilder->CreateBitCast(allocaInst, mBfIRBuilder->MapType(toType)); return BfTypedValue(castedValue, toType); - } + } } return BfTypedValue(); } bool BfModule::GetBasePropertyDef(BfPropertyDef*& propDef, BfTypeInstance*& typeInst) -{ +{ BfTypeInstance* checkTypeInst = typeInst; while (checkTypeInst != NULL) { @@ -10474,14 +10643,14 @@ bool BfModule::GetBasePropertyDef(BfPropertyDef*& propDef, BfTypeInstance*& type { auto checkPropDeclaration = BfNodeDynCast(checkProp->mFieldDeclaration); if ((checkPropDeclaration == NULL) || (checkPropDeclaration->mVirtualSpecifier == NULL) || (checkPropDeclaration->mVirtualSpecifier->GetToken() == BfToken_Virtual)) - { + { propDef = checkProp; typeInst = checkTypeInst; return true; } } } - + checkTypeInst = checkTypeInst->mBaseType; } return false; @@ -10507,7 +10676,7 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan { BF_ASSERT(typeInstance->mTypeDef->mMethods[methodIdx]->mName == assertName); } - + if (methodIdx >= typeInstance->mMethodInstanceGroups.mSize) { if (mCompiler->EnsureCeUnpaused(typeInstance)) @@ -10520,7 +10689,7 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx]; if (methodGroup.mDefault == NULL) { - if (!mCompiler->mIsResolveOnly) + if (!mCompiler->mIsResolveOnly) { // Get it from the owning module so we don't create a reference prematurely... auto declModule = typeInstance->mModule; @@ -10532,11 +10701,11 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan declModule->mOnDemandMethodCount++; } - BF_ASSERT((methodGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) || + BF_ASSERT((methodGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) || (typeInstance->mTypeFailed) || (typeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)); if ((methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) || (methodGroup.mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl)) methodGroup.mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; - + BfGetMethodInstanceFlags useFlags = (BfGetMethodInstanceFlags)(BfGetMethodInstanceFlag_MethodInstanceOnly | BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_Unreified); return declModule->GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), useFlags).mMethodInstance; } @@ -10549,7 +10718,7 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan } auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault; - //TODO: Why did we have this adding methods to the work list? This should only happen if we actually attempt to USE the method, which should + //TODO: Why did we have this adding methods to the work list? This should only happen if we actually attempt to USE the method, which should // be from a call to the NON-raw version // if (!methodInstance->mMethodInstanceGroup->IsImplemented()) // { @@ -10571,7 +10740,7 @@ BfMethodInstance* BfModule::GetRawMethodInstance(BfTypeInstance* typeInstance, B } BfMethodInstance* BfModule::GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount, bool checkBase, bool allowMixin) -{ +{ PopulateType(typeInstance, BfPopulateType_DataAndMethods); while (typeInstance != NULL) @@ -10599,14 +10768,14 @@ BfMethodInstance* BfModule::GetRawMethodByName(BfTypeInstance* typeInstance, con } BfMethodInstance* BfModule::GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType) -{ +{ if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0)) methodInstance = methodInstance->mMethodInstanceGroup->mDefault; - + auto owner = methodInstance->mMethodInstanceGroup->mOwner; - if (!useUnspecializedType) - return methodInstance; + if (!useUnspecializedType) + return methodInstance; if (!owner->IsGenericTypeInstance()) return methodInstance; @@ -10621,29 +10790,29 @@ BfMethodInstance* BfModule::GetUnspecializedMethodInstance(BfMethodInstance* met auto genericType = (BfTypeInstance*)owner; if ((genericType->IsUnspecializedType()) && (!genericType->IsUnspecializedTypeVariation())) return methodInstance; - + if (methodInstance->mMethodDef->mIsLocalMethod) return methodInstance; if (methodInstance->mMethodDef->mDeclaringType->IsEmitted()) return methodInstance; - auto unspecializedType = ResolveTypeDef(genericType->mTypeDef->GetDefinition()); + auto unspecializedType = ResolveTypeDef(genericType->mTypeDef->GetDefinition()); if (unspecializedType == NULL) { AssertErrorState(); return methodInstance; - } + } if (unspecializedType == NULL) return methodInstance; auto unspecializedTypeInst = unspecializedType->ToTypeInstance(); - return GetRawMethodInstanceAtIdx(unspecializedTypeInst, methodInstance->mMethodDef->mIdx); + return GetRawMethodInstanceAtIdx(unspecializedTypeInst, methodInstance->mMethodDef->mIdx); } int BfModule::GetGenericParamAndReturnCount(BfMethodInstance* methodInstance) { int genericCount = 0; auto unspecializedMethodInstance = GetUnspecializedMethodInstance(methodInstance); - for (int paramIdx = 0; paramIdx < unspecializedMethodInstance->GetParamCount(); paramIdx++) + for (int paramIdx = 0; paramIdx < unspecializedMethodInstance->GetParamCount(); paramIdx++) { auto param = unspecializedMethodInstance->GetParamType(paramIdx); if (param->IsGenericParam()) @@ -10663,17 +10832,17 @@ BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl& if (mParentModule != NULL) mainModule = mParentModule; - BfModule* specModule = NULL; + BfModule* specModule = NULL; BfModule** specModulePtr = NULL; if (mainModule->mSpecializedMethodModules.TryGetValueWith(projectList, &specModulePtr)) { return *specModulePtr; } else - { + { String specModuleName = mModuleName; for (auto bfProject : projectList) - { + { specModuleName += StrFormat("@%s", bfProject->mSafeName.c_str()); } specModule = new BfModule(mContext, specModuleName); @@ -10691,7 +10860,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl& } BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined) -{ +{ if (IsSkippingExtraResolveChecks()) return BfIRValue(); @@ -10722,7 +10891,7 @@ BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tr auto intrinsic = GetIntrinsic(methodInstance); if (intrinsic) return intrinsic; - + if (methodInstance->GetImportCallKind() != BfImportCallKind_None) { return CreateDllImportGlobalVar(methodInstance, false); @@ -10747,17 +10916,17 @@ BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tr // mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_DllImport); // } // } - + return func; } BfModuleMethodInstance BfModule::GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName, BfGetMethodInstanceFlags flags) -{ +{ if (assertName != NULL) { BF_ASSERT(typeInstance->mTypeDef->mMethods[methodIdx]->mName == assertName); - } - + } + PopulateType(typeInstance, BfPopulateType_DataAndMethods); auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault; @@ -10783,10 +10952,10 @@ BfModuleMethodInstance BfModule::GetMethodInstanceAtIdx(BfTypeInstance* typeInst BfIRFunction func(mBfIRBuilder->GetFakeVal()); return BfModuleMethodInstance(methodInstance, func); } - + if (foreignType != NULL) return GetMethodInstance(typeInstance, methodDef, BfTypeVector(), (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ForeignMethodDef), foreignType); - return GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), flags); + return GetMethodInstance(typeInstance, typeInstance->mTypeDef->mMethods[methodIdx], BfTypeVector(), flags); } BfModuleMethodInstance BfModule::GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount, bool checkBase) @@ -10795,7 +10964,7 @@ BfModuleMethodInstance BfModule::GetMethodByName(BfTypeInstance* typeInstance, c while (typeInstance != NULL) { - typeInstance->mTypeDef->PopulateMemberSets(); + typeInstance->mTypeDef->PopulateMemberSets(); BfMemberSetEntry* entry = NULL; BfMethodDef* methodDef = NULL; if (typeInstance->mTypeDef->mMethodSet.TryGetWith(methodName, &entry)) @@ -10803,14 +10972,17 @@ BfModuleMethodInstance BfModule::GetMethodByName(BfTypeInstance* typeInstance, c while (methodDef != NULL) { - if ((methodDef->mMethodType != BfMethodType_Mixin) && + if ((methodDef->mMethodType != BfMethodType_Mixin) && (methodDef->mGenericParams.size() == 0) && - ((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) - return GetMethodInstanceAtIdx(typeInstance, methodDef->mIdx); + ((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) + { + auto moduleMethodInstance = GetMethodInstanceAtIdx(typeInstance, methodDef->mIdx); + if (moduleMethodInstance) + return moduleMethodInstance; + } methodDef = methodDef->mNextWithSameName; } - if (!checkBase) break; typeInstance = typeInstance->mBaseType; @@ -10831,11 +11003,11 @@ BfModuleMethodInstance BfModule::GetMethodByName(BfTypeInstance* typeInstance, c methodDef = (BfMethodDef*)entry->mMemberDef; while (methodDef != NULL) - { + { if ((methodDef->mMethodType != BfMethodType_Mixin) && (methodDef->mGenericParams.size() == 0) && (paramTypes.size() == methodDef->mParams.size())) - { + { auto moduleMethodInstance = GetMethodInstanceAtIdx(typeInstance, methodDef->mIdx); if (moduleMethodInstance.mMethodInstance != NULL) { @@ -10876,14 +11048,14 @@ BfOperatorInfo* BfModule::GetOperatorInfo(BfTypeInstance* typeInstance, BfOperat { while (operatorDef->mIdx >= typeInstance->mOperatorInfo.size()) typeInstance->mOperatorInfo.Add(NULL); - + if (typeInstance->mOperatorInfo[operatorDef->mIdx] == NULL) { SetAndRestoreValue ignoreErrors(mIgnoreErrors, true); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); - BfTypeState typeState; + BfTypeState typeState; typeState.mType = typeInstance; typeState.mCurTypeDef = operatorDef->mDeclaringType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -10923,7 +11095,7 @@ BfType* BfModule::CheckOperator(BfTypeInstance* typeInstance, BfOperatorDef* ope if (rhs) { if (operatorInfo->mRHSType == NULL) - return NULL; + return NULL; if (!CanCast(rhs, operatorInfo->mRHSType, castFlags)) return NULL; } @@ -11209,7 +11381,7 @@ StringT<128> BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodName for (int paramIdx = 0; paramIdx < (int)methodInst->GetParamCount(); paramIdx++) { int paramKind = methodInst->GetParamKind(paramIdx); - if (paramKind == BfParamKind_ImplicitCapture) + if ((paramKind == BfParamKind_ImplicitCapture) || (paramKind == BfParamKind_AppendIdx)) continue; if (dispParamIdx > 0) @@ -11283,26 +11455,26 @@ static void AddAttributeTargetName(BfAttributeTargets& flagsLeft, BfAttributeTar } static String GetAttributesTargetListString(BfAttributeTargets attrTarget) -{ +{ String resultStr; auto flagsLeft = attrTarget; - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Assembly, resultStr, "assembly declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Assembly, resultStr, "assembly declarations"); AddAttributeTargetName(flagsLeft, BfAttributeTargets_Module, resultStr, "module declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Class, resultStr, "class declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Struct, resultStr, "struct declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Enum, resultStr, "enum declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Constructor, resultStr, "constructor declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Method, resultStr, "method declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Property, resultStr, "property declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Field, resultStr, "field declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_StaticField, resultStr, "static field declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Interface, resultStr, "interface declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Parameter, resultStr, "parameter declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Class, resultStr, "class declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Struct, resultStr, "struct declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Enum, resultStr, "enum declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Constructor, resultStr, "constructor declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Method, resultStr, "method declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Property, resultStr, "property declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Field, resultStr, "field declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_StaticField, resultStr, "static field declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Interface, resultStr, "interface declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Parameter, resultStr, "parameter declarations"); AddAttributeTargetName(flagsLeft, BfAttributeTargets_Delegate, resultStr, "delegate declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Function, resultStr, "function declarations"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_ReturnValue, resultStr, "return value"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_GenericParameter, resultStr, "generic parameters"); - AddAttributeTargetName(flagsLeft, BfAttributeTargets_Invocation, resultStr, "invocations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Function, resultStr, "function declarations"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_ReturnValue, resultStr, "return value"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_GenericParameter, resultStr, "generic parameters"); + AddAttributeTargetName(flagsLeft, BfAttributeTargets_Invocation, resultStr, "invocations"); AddAttributeTargetName(flagsLeft, BfAttributeTargets_MemberAccess, resultStr, "member access"); AddAttributeTargetName(flagsLeft, BfAttributeTargets_Alloc, resultStr, "allocations"); AddAttributeTargetName(flagsLeft, BfAttributeTargets_Alias, resultStr, "aliases"); @@ -11312,10 +11484,21 @@ static String GetAttributesTargetListString(BfAttributeTargets attrTarget) return resultStr; } +BfIRType BfModule::CurrentAddToConstHolder(BfIRType irType) +{ + if (irType.mKind == BfIRTypeData::TypeKind_SizedArray) + { + auto sizedArrayType = (BfConstantSizedArrayType*)mBfIRBuilder->GetConstantById(irType.mId); + return mCurTypeInstance->GetOrCreateConstHolder()->GetSizedArrayType(CurrentAddToConstHolder(sizedArrayType->mType), (int)sizedArrayType->mLength); + } + + return irType; +} + void BfModule::CurrentAddToConstHolder(BfIRValue& irVal) { auto constant = mBfIRBuilder->GetConstant(irVal); - + int stringPoolIdx = GetStringPoolIdx(irVal, mBfIRBuilder); if (stringPoolIdx != -1) { @@ -11326,23 +11509,23 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal) if (constant->mConstType == BfConstType_Agg) { auto constArray = (BfConstantAgg*)constant; - + SizedArray newVals; for (auto val : constArray->mValues) { auto newVal = val; CurrentAddToConstHolder(newVal); - newVals.push_back(newVal); + newVals.push_back(newVal); } - irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstAgg(constArray->mType, newVals); + irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstAgg(CurrentAddToConstHolder(constArray->mType), newVals); return; } - auto origConst = irVal; + auto origConst = irVal; if ((constant->mConstType == BfConstType_BitCast) || (constant->mConstType == BfConstType_BitCastNull)) { - auto bitcast = (BfConstantBitCast*)constant; + auto bitcast = (BfConstantBitCast*)constant; BfIRValue newVal; if (bitcast->mTarget) { @@ -11351,11 +11534,11 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal) } else newVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstNull(); - irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstBitCast(newVal, bitcast->mToType); + irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstBitCast(newVal, CurrentAddToConstHolder(bitcast->mToType)); return; } - irVal = mCurTypeInstance->CreateConst(constant, mBfIRBuilder); + irVal = mCurTypeInstance->CreateConst(constant, mBfIRBuilder); } void BfModule::ClearConstData() @@ -11365,10 +11548,11 @@ void BfModule::ClearConstData() mStringCharPtrPool.Clear(); mStringPoolRefs.Clear(); mUnreifiedStringPoolRefs.Clear(); + mStaticFieldRefs.Clear(); } BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType) -{ +{ switch (constant->mTypeCode) { case BfTypeCode_StringId: @@ -11407,7 +11591,7 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef); typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType, allowUnactualized), stringType); } - + if (!typedValue) { auto constVal = mBfIRBuilder->CreateConst(constant, constHolder); @@ -11423,15 +11607,15 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst typedValue.mType = wantType; return typedValue; } - } - auto castedTypedValue = Cast(NULL, typedValue, wantType, (BfCastFlags)(BfCastFlags_SilentFail | BfCastFlags_Explicit)); + } + auto castedTypedValue = Cast(NULL, typedValue, wantType, (BfCastFlags)(BfCastFlags_SilentFail | BfCastFlags_Explicit)); if (!castedTypedValue) - return BfTypedValue(); + return BfTypedValue(); return castedTypedValue; } break; default: break; - } + } BfIRValue irValue = ConstantToCurrent(constant, constHolder, wantType); BF_ASSERT(irValue); if (!irValue) @@ -11458,12 +11642,12 @@ bool BfModule::HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* co if (constant->mConstType == BfConstType_Agg) { - auto constArray = (BfConstantAgg*)constant; + auto constArray = (BfConstantAgg*)constant; for (auto val : constArray->mValues) { if (HasUnactializedConstant(constHolder->GetConstant(val), constHolder)) - return true; - } + return true; + } } return false; @@ -11509,13 +11693,13 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con if (constant->mConstType == BfConstType_PtrToInt) { auto fromPtrToInt = (BfConstantPtrToInt*)constant; - auto fromTarget = constHolder->GetConstantById(fromPtrToInt->mTarget); + auto fromTarget = constHolder->GetConstantById(fromPtrToInt->mTarget); return mBfIRBuilder->CreatePtrToInt(ConstantToCurrent(fromTarget, constHolder, NULL), fromPtrToInt->mToTypeCode); } if (constant->mConstType == BfConstType_IntToPtr) { - auto fromPtrToInt = (BfConstantIntToPtr*)constant; + auto fromPtrToInt = (BfConstantIntToPtr*)constant; auto fromTarget = constHolder->GetConstantById(fromPtrToInt->mTarget); BfIRType toIRType = fromPtrToInt->mToType; if (toIRType.mKind == BfIRTypeData::TypeKind_TypeId) @@ -11546,15 +11730,18 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con if ((wantType == NULL) && (constArray->mType.mKind == BfIRTypeData::TypeKind_TypeId)) wantType = mContext->mTypes[constArray->mType.mId]; + if (wantType->IsArray()) + wantType = CreateSizedArrayType(wantType->GetUnderlyingType(), (int)constArray->mValues.mSize); + SizedArray newVals; if (wantType->IsSizedArray()) { - auto elementType = wantType->GetUnderlyingType(); + auto elementType = wantType->GetUnderlyingType(); for (auto val : constArray->mValues) { newVals.Add(ConstantToCurrent(constHolder->GetConstant(val), constHolder, elementType)); } - } + } else { auto wantTypeInst = wantType->ToTypeInstance(); @@ -11603,7 +11790,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType, BfIRPopulateType_Identity), newVals); } - return mBfIRBuilder->CreateConst(constant, constHolder); + return mBfIRBuilder->CreateConst(constant, constHolder); } void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget) @@ -11612,7 +11799,7 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf return; for (auto& customAttribute : customAttributes->mAttributes) - { + { if (!customAttribute.mAwaitingValidation) continue; @@ -11620,7 +11807,7 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf { Fail(StrFormat("Attribute '%s' is not valid on this declaration type. It is only valid on %s.", customAttribute.GetRefNode()->ToString().c_str(), GetAttributesTargetListString(customAttribute.mType->mAttributeData->mAttributeTargets).c_str()), customAttribute.mRef->mAttributeTypeRef); // CS0592 - } + } customAttribute.mAwaitingValidation = false; } @@ -11634,7 +11821,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if (!mCompiler->mHasRequiredTypes) return; - if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL)) + if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL)) { if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(attributesDirective)) sourceClassifier->VisitChild(attributesDirective); @@ -11643,7 +11830,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri SetAndRestoreValue prevIsCapturingMethodMatchInfo; if (mCompiler->IsAutocomplete()) prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false); - + BfTypeInstance* baseAttrTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompiler->mAttributeTypeDef)->ToTypeInstance(); BfAttributeTargets targetOverride = (BfAttributeTargets)0; @@ -11693,15 +11880,15 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri BfType* attrType; if (mContext->mCurTypeState != NULL) { - SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurAttributeTypeRef, attributesDirective->mAttributeTypeRef); + SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurAttributeTypeRef, attributesDirective->mAttributeTypeRef); attrType = ResolveTypeRef(attributesDirective->mAttributeTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_NoReify)); } else { attrType = ResolveTypeRef(attributesDirective->mAttributeTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_NoReify)); } - - BfTypeDef* attrTypeDef = NULL; + + BfTypeDef* attrTypeDef = NULL; if ((attrType != NULL) && (attrType->IsTypeInstance())) attrTypeDef = attrType->ToTypeInstance()->mTypeDef; @@ -11715,13 +11902,13 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri bool isBypassedAttr = false; if (attrTypeDef != NULL) - { + { // 'Object' has some dependencies on some attributes, but those attributes are classes so we have a circular dependency issue // We solve it by having a 'bypass' for known attributes that Object depends on if ((attributesDirective->mArguments.empty()) && (autoComplete == NULL) && (attrType != NULL) && (attrType->IsTypeInstance())) { if (attrType->IsInstanceOf(mCompiler->mCReprAttributeTypeDef)) - { + { for (auto methodDef : attrTypeDef->mMethods) { if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mProtection == BfProtection_Public)) @@ -11734,7 +11921,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri } } } - + if (isBypassedAttr) { customAttribute.mAwaitingValidation = false; @@ -11746,22 +11933,22 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri SetAndRestoreValue prevCurMethodInst(mContext->mUnreifiedModule->mCurMethodInstance, mCurMethodInstance); if (mContext->mCurTypeState != NULL) { - SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurAttributeTypeRef, attributesDirective->mAttributeTypeRef); + SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurAttributeTypeRef, attributesDirective->mAttributeTypeRef); mContext->mUnreifiedModule->ResolveTypeResult(attributesDirective->mAttributeTypeRef, attrType, BfPopulateType_BaseType, (BfResolveTypeRefFlags)0); } else { mContext->mUnreifiedModule->ResolveTypeResult(attributesDirective->mAttributeTypeRef, attrType, BfPopulateType_BaseType, (BfResolveTypeRefFlags)0); } - } - + } + BfTypeInstance* attrTypeInst = NULL; if (attrType == NULL) continue; attrTypeInst = attrType->ToTypeInstance(); if ((attrTypeInst != NULL) && (attrTypeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting)) - mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods); - + mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods); + if ((attrTypeInst == NULL) || (!TypeIsSubTypeOf(attrTypeInst, baseAttrTypeInst)) || (attrTypeInst->mAttributeData == NULL)) { Fail(StrFormat("'%s' is not an attribute class", TypeToString(attrType).c_str()), attributesDirective->mAttributeTypeRef); //CS0616 @@ -11778,8 +11965,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri AddDependency(attrTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute); customAttribute.mType = attrTypeInst; - - bool allocatedMethodState = NULL; + + bool allocatedMethodState = NULL; defer( { if (allocatedMethodState) @@ -11817,11 +12004,11 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri inPropSet = true; if (autoComplete != NULL) autoComplete->CheckNode(assignExpr->mLeft, true); - + String findName = assignExpr->mLeft->ToString(); BfPropertyDef* bestProp = NULL; BfTypeInstance* bestPropTypeInst = NULL; - BfFieldDef* bestField = NULL; + BfFieldDef* bestField = NULL; BfTypeInstance* bestFieldTypeInst = NULL; auto checkTypeInst = attrTypeInst; while (checkTypeInst != NULL) @@ -11857,10 +12044,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri checkTypeInst = checkTypeInst->mBaseType; } - + bool handledExpr = false; - if (bestField != NULL) + if (bestField != NULL) { handledExpr = true; @@ -11879,12 +12066,12 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri AddDependency(bestFieldTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute); - BfCustomAttributeSetField setField; + BfCustomAttributeSetField setField; setField.mFieldRef = BfFieldRef(bestFieldTypeInst, bestField); auto& fieldTypeInst = checkTypeInst->mFieldInstances[bestField->mIdx]; if (assignExpr->mRight != NULL) - { + { BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues); if (result) { @@ -11898,7 +12085,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri else if (bestProp == NULL) { Fail(StrFormat("'%s' does not contain a field or property named '%s'", TypeToString(attrTypeInst).c_str(), findName.c_str()), assignExpr->mLeft); - } + } else { BfMethodDef* setMethod = NULL; @@ -11985,7 +12172,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri resolvedArg.mTypedValue = constResolver.Resolve(arg, NULL, BfConstResolveFlag_NoActualizeValues); if (!inPropSet) - { + { argValues.push_back(resolvedArg); } } @@ -11993,21 +12180,21 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if (autoComplete != NULL) autoComplete->mShowAttributeProperties = NULL; } - + auto wasCapturingMethodInfo = false; if (autoComplete != NULL) { wasCapturingMethodInfo = autoComplete->mIsCapturingMethodMatchInfo; if (attributesDirective->mCtorOpenParen != NULL) autoComplete->CheckInvocation(attributesDirective, attributesDirective->mCtorOpenParen, attributesDirective->mCtorCloseParen, attributesDirective->mCommas); - } - + } + BfMethodMatcher methodMatcher(attributesDirective, this, "", argValues, BfMethodGenericArguments()); methodMatcher.mBfEvalExprFlags = constResolver.mBfEvalExprFlags; attrTypeDef = attrTypeInst->mTypeDef; bool success = true; - + bool isFailurePass = false; for (int pass = 0; pass < 2; pass++) { @@ -12043,9 +12230,9 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri } if (methodMatcher.mBestMethodDef == NULL) - methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef; + methodMatcher.mBestMethodDef = methodMatcher.mBackupMethodDef; - BF_ASSERT(methodMatcher.mBestMethodDef != NULL); + BF_ASSERT(methodMatcher.mBestMethodDef != NULL); customAttribute.mCtor = methodMatcher.mBestMethodDef; if (methodMatcher.mBestMethodTypeInstance == mCurTypeInstance) @@ -12058,7 +12245,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if (!constResolver.PrepareMethodArguments(attributesDirective->mAttributeTypeRef, &methodMatcher, customAttribute.mCtorArgs)) success = false; - + for (auto& arg : argValues) { if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0) @@ -12077,7 +12264,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri CurrentAddToConstHolder(ctorArg); } } - + if (attributesDirective->mAttributeTargetSpecifier != NULL) { targetOverride = BfAttributeTargets_ReturnValue; @@ -12086,7 +12273,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri Fail(StrFormat("'%s' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '%s'. All attributes in this block will be ignored.", GetAttributesTargetListString(targetOverride).c_str(), GetAttributesTargetListString(attrTarget).c_str()), attributesDirective->mAttributeTargetSpecifier); // CS0657 success = false; - } + } } if ((success) && (targetOverride != (BfAttributeTargets)0)) @@ -12104,11 +12291,11 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri methodInfoEx->mMethodCustomAttributes->mReturnCustomAttributes->mAttributes.push_back(customAttribute); } } - + // Mark as failed since we don't actually want to add this to the custom attributes set - success = false; + success = false; } - + if (success) { if ((attrTypeInst->mAttributeData->mFlags & BfAttributeFlag_DisallowAllowMultiple) != 0) @@ -12117,14 +12304,14 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri { if (prevCustomAttribute.mType == attrTypeInst) { - Fail(StrFormat("Duplicate '%s' attribute", attributesDirective->mAttributeTypeRef->ToCleanAttributeString().c_str()), attributesDirective->mAttributeTypeRef); // CS0579 + Fail(StrFormat("Duplicate '%s' attribute", attributesDirective->mAttributeTypeRef->ToCleanAttributeString().c_str()), attributesDirective->mAttributeTypeRef); // CS0579 } } } } if (success) - { + { customAttributes->mAttributes.push_back(customAttribute); } } @@ -12198,7 +12385,7 @@ void BfModule::ProcessTypeInstCustomAttributes(int& packing, bool& isUnion, bool isOrdered = true; } else if (typeName == "System.OrderedAttribute") - { + { isOrdered = true; } else if (typeName == "System.AlwaysIncludeAttribute") @@ -12212,7 +12399,7 @@ void BfModule::ProcessTypeInstCustomAttributes(int& packing, bool& isUnion, bool { auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue); if ((constant != NULL) && (constant->mBool)) - mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | BfAlwaysIncludeFlag_AssumeInstantiated); + mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | BfAlwaysIncludeFlag_AssumeInstantiated); } else if (propertyDef->mName == "IncludeAllMethods") { @@ -12255,7 +12442,7 @@ void BfModule::ProcessTypeInstCustomAttributes(int& packing, bool& isUnion, bool if ((customAttribute.mType->mAttributeData != NULL) && ((customAttribute.mType->mAttributeData->mAlwaysIncludeUser & BfAlwaysIncludeFlag_AssumeInstantiated) != 0)) mCurTypeInstance->mAlwaysIncludeFlags = (BfAlwaysIncludeFlags)(mCurTypeInstance->mAlwaysIncludeFlags | customAttribute.mType->mAttributeData->mAlwaysIncludeUser); } - } + } } // Checking to see if we're an attribute or not @@ -12281,14 +12468,14 @@ void BfModule::ProcessCustomAttributeData() if (mCurTypeInstance->mCustomAttributes != NULL) { for (auto& customAttribute : mCurTypeInstance->mCustomAttributes->mAttributes) - { + { if (customAttribute.mType->IsInstanceOf(mCompiler->mAttributeUsageAttributeTypeDef)) { if (customAttribute.mCtorArgs.size() > 0) { auto constant = mCurTypeInstance->mConstHolder->GetConstant(customAttribute.mCtorArgs[0]); if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode))) - attributeData->mAttributeTargets = (BfAttributeTargets)constant->mInt32; + attributeData->mAttributeTargets = (BfAttributeTargets)constant->mInt32; } if (customAttribute.mCtorArgs.size() == 2) @@ -12305,7 +12492,7 @@ void BfModule::ProcessCustomAttributeData() BfPropertyDef* propDef = setProp.mPropertyRef; if (propDef->mName == "AllowMultiple") - { + { auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue); if ((constant != NULL) && (constant->mBool)) attributeData->mFlags = (BfAttributeFlags)(attributeData->mFlags & ~BfAttributeFlag_DisallowAllowMultiple); @@ -12330,7 +12517,7 @@ void BfModule::ProcessCustomAttributeData() { auto constant = mCurTypeInstance->mConstHolder->GetConstant(setProp.mParam.mValue); if (constant != NULL) - attributeData->mAlwaysIncludeUser = (BfAlwaysIncludeFlags)constant->mInt32; + attributeData->mAlwaysIncludeUser = (BfAlwaysIncludeFlags)constant->mInt32; } } @@ -12340,9 +12527,9 @@ void BfModule::ProcessCustomAttributeData() } if ((!hasCustomAttribute) && (mCurTypeInstance->mBaseType->mAttributeData != NULL)) - { + { attributeData->mAttributeTargets = mCurTypeInstance->mBaseType->mAttributeData->mAttributeTargets; - attributeData->mFlags = mCurTypeInstance->mBaseType->mAttributeData->mFlags; + attributeData->mFlags = mCurTypeInstance->mBaseType->mAttributeData->mFlags; attributeData->mAlwaysIncludeUser = mCurTypeInstance->mBaseType->mAttributeData->mAlwaysIncludeUser; } @@ -12443,7 +12630,7 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue& } BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue) -{ +{ if ((typedValue.mType != NULL) && (typedValue.mType->IsRef())) { auto refType = (BfRefType*)typedValue.mType; @@ -12476,6 +12663,23 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue) return typedValue; } +BfTypedValue BfModule::SanitizeAddr(BfTypedValue typedValue) +{ + if (!typedValue) + return typedValue; + + if (typedValue.mType->IsRef()) + { + typedValue = LoadValue(typedValue); + + auto copiedVal = BfTypedValue(CreateAlloca(typedValue.mType), typedValue.mType, true); + mBfIRBuilder->CreateStore(typedValue.mValue, copiedVal.mValue); + return copiedVal; + } + + return typedValue; +} + BfTypedValue BfModule::ToRef(BfTypedValue typedValue, BfRefType* refType) { if (refType == NULL) @@ -12512,7 +12716,7 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo { auto globalVar = (BfGlobalVar*)constantValue; if (globalVar->mName[0] == '#') - { + { BfTypedValue result = GetCompilerFieldValue(globalVar->mName); if (result) { @@ -12529,7 +12733,9 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo } return result; } - return GetDefaultTypedValue(typedValue.mType); + + if (!mIsComptimeModule) + return GetDefaultTypedValue(typedValue.mType); } } @@ -12576,14 +12782,12 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo if (loadedVal) { if (typedValue.mType->IsVar()) - { + { return BfTypedValue(loadedVal, typedValue.mType, false); } - /*if (isVolatile) - mBfIRBuilder->CreateFence(BfIRFenceType_AcquireRelease);*/ PopulateType(typedValue.mType, BfPopulateType_Data); - loadedVal = mBfIRBuilder->CreateAlignedLoad(loadedVal, std::max(1, (int)typedValue.mType->mAlign), isVolatile); + loadedVal = mBfIRBuilder->CreateAlignedLoad(loadedVal, std::max(1, (int)typedValue.mType->mAlign), isVolatile || typedValue.IsVolatile()); } return BfTypedValue(loadedVal, typedValue.mType, false); } @@ -12626,7 +12830,7 @@ BfTypedValue BfModule::AggregateSplat(BfTypedValue typedValue, BfIRValue* valueA }; std::function checkTypeLambda = [&](BfType* checkType) - { + { if (checkType->IsStruct()) { BfIRValue curValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(checkType, BfIRPopulateType_Full)); @@ -12684,7 +12888,7 @@ BfTypedValue BfModule::AggregateSplat(BfTypedValue typedValue, BfIRValue* valueA } else { - fieldValue = _ExtractValue(checkType); + fieldValue = _ExtractValue(checkType); } curValue = mBfIRBuilder->CreateInsertValue(curValue, fieldValue, dataIdx); } @@ -12698,7 +12902,7 @@ BfTypedValue BfModule::AggregateSplat(BfTypedValue typedValue, BfIRValue* valueA return BfIRValue(); }; - BfIRValue value = checkTypeLambda(typedValue.mType); + BfIRValue value = checkTypeLambda(typedValue.mType); return BfTypedValue(value, typedValue.mType, typedValue.IsThis() ? BfTypedValueKind_ThisValue : BfTypedValueKind_Value); } @@ -12714,7 +12918,7 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal /*static int sCallIdx = 0; if (!mCompiler->mIsResolveOnly) sCallIdx++; - int callIdx = sCallIdx;*/ + int callIdx = sCallIdx;*/ int elementIdx = 0; @@ -12781,7 +12985,7 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal // NOP; // } - auto val = ExtractSplatValue(typedValue, elementIdx++, dataType); + auto val = ExtractSplatValue(typedValue, elementIdx++, dataType); mBfIRBuilder->CreateStore(val, fieldAddrVal); } } @@ -12791,10 +12995,9 @@ void BfModule::AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal auto val = ExtractSplatValue(typedValue, elementIdx++, checkType); mBfIRBuilder->CreateStore(val, curAddrVal); } - }; - checkTypeLambda(typedValue.mType, addrVal); + checkTypeLambda(typedValue.mType, addrVal); } BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal, bool forceMutable, bool forceAddressable) @@ -12806,12 +13009,12 @@ BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal, bool forceMutable, (!typedVal.mType->IsValuelessType()))) { wasReadOnly = true; // Any non-addr is implicitly read-only - + //static int gCallIdx = 0; FixValueActualization(typedVal); if (typedVal.IsAddr()) return typedVal; - BfType* type = typedVal.mType; + BfType* type = typedVal.mType; PopulateType(type); BfIRValue tempVar; if (typedVal.mValue.IsFake()) @@ -12824,7 +13027,7 @@ BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal, bool forceMutable, else mBfIRBuilder->CreateAlignedStore(typedVal.mValue, tempVar, type->mAlign); } - + if (forceMutable) wasReadOnly = false; @@ -12839,7 +13042,7 @@ BfTypedValue BfModule::MakeAddressable(BfTypedValue typedVal, bool forceMutable, BfTypedValue BfModule::RemoveReadOnly(BfTypedValue typedValue) { if (typedValue.mKind == BfTypedValueKind_ReadOnlyAddr) - typedValue.mKind = BfTypedValueKind_Addr; + typedValue.mKind = BfTypedValueKind_Addr; return typedValue; } @@ -12878,7 +13081,7 @@ BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, if (decompAddr == typedValue.mValue) { val = checkMethodState->mSplatDecompAddrs[idx + componentIdx]; - + if ((wantType->IsComposite()) && (typedValue.mType->IsMethodRef())) { // This is really backing for a POINTER to a composite inside a methodRef @@ -12914,7 +13117,7 @@ BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, if (val) { if (typedValue.mKind == BfTypedValueKind_SplatHead_NeedsCasting) - { + { BF_ASSERT(wantType != NULL); if (wantType != NULL) return mBfIRBuilder->CreateBitCast(val, mBfIRBuilder->MapType(wantType)); @@ -12924,7 +13127,7 @@ BfIRValue BfModule::ExtractSplatValue(BfTypedValue typedValue, int componentIdx, } BFMODULE_FATAL(this, "Splat not found"); - return BfIRValue(); + return BfIRValue(); } BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fieldInstance, int fieldIdx) @@ -12934,7 +13137,7 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi BfType* fieldType = NULL; if (fieldInstance != NULL) { - fieldType = fieldInstance->mResolvedType; + fieldType = fieldInstance->mResolvedType; if (typedValue.mType->IsUnion()) { if (fieldIdx == 1) @@ -12952,12 +13155,12 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi { if (typedValue.mType->IsPayloadEnum()) { - auto typeInst = typedValue.mType->ToTypeInstance(); + auto typeInst = typedValue.mType->ToTypeInstance(); if (fieldIdx == 1) fieldType = typeInst->GetUnionInnerType(); else if (fieldIdx == 2) { - fieldType = typeInst->GetDiscriminatorType(&useFieldIdx); + fieldType = typeInst->GetDiscriminatorType(&useFieldIdx); } } else if (typedValue.mType->IsUnion()) @@ -12978,16 +13181,16 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi BF_ASSERT(typedValue.mType->IsStruct()); if (typedValue.IsSplat()) - { + { if (typedValue.mType->IsPayloadEnum()) - { + { if (fieldIdx == 1) { // Payload auto typeInst = typedValue.mType->ToTypeInstance(); auto unionInnerType = typeInst->GetUnionInnerType(); bool isAddr = false; - BfIRValue irVal = ExtractSplatValue(typedValue, 0, unionInnerType, &isAddr); + BfIRValue irVal = ExtractSplatValue(typedValue, 0, unionInnerType, &isAddr); return BfTypedValue(irVal, unionInnerType, BfTypedValueKind_SplatHead); } @@ -13007,7 +13210,7 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi BfIRValue irVal = ExtractSplatValue(typedValue, componentIdx, dscrType, &isAddr); return BfTypedValue(irVal, dscrType, isAddr); } - } + } int componentIdx = 0; @@ -13019,7 +13222,7 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi { auto checkTypeInstance = checkType->ToTypeInstance(); if ((checkType->IsUnion()) || (checkType->IsEnum())) - { + { //TODO: Why did we have this removed? It messed up an extraction from a nullable splattable fieldType = checkTypeInstance->GetUnionInnerType(); checkTypeLambda(fieldType); @@ -13027,10 +13230,10 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi if (checkType->IsEnum()) { // Past discriminator... - componentIdx++; - } + componentIdx++; + } return; - } + } if (checkTypeInstance->mBaseType != NULL) checkTypeLambda(checkTypeInstance->mBaseType); @@ -13079,8 +13282,8 @@ BfTypedValue BfModule::ExtractValue(BfTypedValue typedValue, BfFieldInstance* fi if (typedValue.IsAddr()) { BF_ASSERT(fieldType != NULL); - auto valRef = mBfIRBuilder->CreateInBoundsGEP(typedValue.mValue, 0, useFieldIdx); - return BfTypedValue(valRef, fieldType, BfTypedValueKind_ReadOnlyAddr); + auto valRef = mBfIRBuilder->CreateInBoundsGEP(typedValue.mValue, 0, useFieldIdx); + return BfTypedValue(valRef, fieldType, BfTypedValueKind_ReadOnlyAddr); } else { @@ -13095,7 +13298,7 @@ BfIRValue BfModule::ExtractValue(BfTypedValue typedValue, int dataIdx) { auto addrVal = mBfIRBuilder->CreateInBoundsGEP(typedValue.mValue, 0, dataIdx); return mBfIRBuilder->CreateAlignedLoad(addrVal, typedValue.mType->mAlign); - } + } return mBfIRBuilder->CreateExtractValue(typedValue.mValue, dataIdx); } @@ -13113,7 +13316,7 @@ BfIRValue BfModule::CreateIndexedValue(BfType* elementType, BfIRValue value, BfI // else // return mBfIRBuilder->CreateInBoundsGEP(value, indexValue); // } -// +// // auto ptrType = CreatePointerType(elementType); // auto ofsVal = mBfIRBuilder->CreateNumericCast(indexValue, true, BfTypeCode_IntPtr); // auto ofsScaledVal = mBfIRBuilder->CreateMul(ofsVal, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, elementType->GetStride())); @@ -13142,7 +13345,7 @@ bool BfModule::CheckModifyValue(BfTypedValue& typedValue, BfAstNode* refNode, co if (typedValue.mType->IsVar()) return true; - + if (typedValue.IsReadOnly()) { Fail(StrFormat("Cannot %s read-only variable", modifyType), refNode); @@ -13181,7 +13384,7 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan else if (methodA->mMethodDef->mName != methodB->mMethodDef->mName) return false; if (methodA->mMethodDef->mCheckedKind != methodB->mMethodDef->mCheckedKind) - return false; + return false; if (methodA->mMethodDef->mHasComptime != methodB->mMethodDef->mHasComptime) return false; if ((methodA->mMethodDef->mMethodType == BfMethodType_Mixin) != (methodB->mMethodDef->mMethodType == BfMethodType_Mixin)) @@ -13191,7 +13394,7 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan { if (methodA->mMethodDef->mIsStatic != methodB->mMethodDef->mIsStatic) return false; - } + } if (methodA->mMethodDef->mMethodType == BfMethodType_Operator) { @@ -13202,7 +13405,7 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan if (operatorA->mOperatorDeclaration->mUnaryOp != operatorB->mOperatorDeclaration->mUnaryOp) return false; if (operatorA->mOperatorDeclaration->mBinOp != operatorB->mOperatorDeclaration->mBinOp) - return false; + return false; if (operatorA->mOperatorDeclaration->mAssignOp != operatorB->mOperatorDeclaration->mAssignOp) return false; if (operatorA->mOperatorDeclaration->mIsConvOperator) @@ -13221,16 +13424,16 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan if (methodA->mHadGenericDelegateParams != methodB->mHadGenericDelegateParams) return false; - for (int paramIdx = 0; paramIdx < (int)methodA->GetParamCount() - implicitParamCountA; paramIdx++) + for (int paramIdx = 0; paramIdx < (int)methodA->GetParamCount() - implicitParamCountA; paramIdx++) { if ((!BfTypeUtils::TypeEquals(methodA->GetParamType(paramIdx + implicitParamCountA), methodB->GetParamType(paramIdx + implicitParamCountB), implOwner)) || (methodA->GetParamKind(paramIdx + implicitParamCountA) != methodB->GetParamKind(paramIdx + implicitParamCountB))) return false; } - + // Compare generic params. Generic params are part of the method signature here if (methodA->GetNumGenericParams() != methodB->GetNumGenericParams()) - return false; + return false; for (int genericParamIdx = 0; genericParamIdx < (int)methodA->GetNumGenericParams(); genericParamIdx++) { auto genericParamA = methodA->mMethodInfoEx->mGenericParams[genericParamIdx]; @@ -13245,7 +13448,7 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan for (int interfaceIdx = 0; interfaceIdx < (int)genericParamA->mInterfaceConstraints.size(); interfaceIdx++) if (genericParamA->mInterfaceConstraints[interfaceIdx] != genericParamB->mInterfaceConstraints[interfaceIdx]) return false; - } + } return true; } @@ -13280,11 +13483,11 @@ bool BfModule::IsCompatibleInterfaceMethod(BfMethodInstance* iMethodInst, BfMeth if (iOperatorDef->mOperatorDeclaration->mUnaryOp != operatorDef->mOperatorDeclaration->mUnaryOp) return false; if (iOperatorDef->mOperatorDeclaration->mBinOp != operatorDef->mOperatorDeclaration->mBinOp) - return false; + return false; } if (iMethodInst->GetParamCount() != methodInstance->GetParamCount()) - return false; + return false; auto selfType = methodInstance->GetOwner(); for (int paramIdx = 0; paramIdx < (int)iMethodInst->GetParamCount(); paramIdx++) @@ -13326,23 +13529,23 @@ bool BfModule::IsCompatibleInterfaceMethod(BfMethodInstance* iMethodInst, BfMeth } void BfModule::AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInstanceFlags flags) -{ +{ BfMethodInstance* methodInstance = methodRef; if ((mCurTypeInstance != NULL) && (!mCompiler->IsAutocomplete())) { auto methodInstanceGroup = methodInstance->mMethodInstanceGroup; if ((methodInstance->IsSpecializedGenericMethod()) || (methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)) - { + { BF_ASSERT(!methodRef.mTypeInstance->IsFunction()); // This ensures we rebuild - there are some cases where we get a method reference but never call it, so this is required here AddDependency(methodInstance->GetOwner(), mCurTypeInstance, BfDependencyMap::DependencyFlag_Calls); - BfMethodRef methodRef = methodInstance; + BfMethodRef methodRef = methodInstance; BfSpecializedMethodRefInfo* specializedMethodRefInfo = NULL; bool isNew = mCurTypeInstance->mSpecializedMethodReferences.TryAdd(methodRef, NULL, &specializedMethodRefInfo); - + if (((flags & BfGetMethodInstanceFlag_Unreified) == 0) && ((flags & BfGetMethodInstanceFlag_NoForceReification) == 0) && (mIsReified)) @@ -13354,7 +13557,7 @@ void BfModule::AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInsta } BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags) -{ +{ if ((flags & BfGetMethodInstanceFlag_ResultNotUsed) != 0) return BfModuleMethodInstance(methodInstance, BfIRValue()); @@ -13380,8 +13583,8 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc if (methodInstance->mMethodDef->mMethodType == BfMethodType_Mixin) { return BfModuleMethodInstance(methodInstance, BfIRFunction()); - } - + } + bool isInlined = (methodInstance->mAlwaysInline) || ((flags & BfGetMethodInstanceFlag_ForceInline) != 0); if ((methodInstance->mIsIntrinsic) || (methodInstance->mMethodDef->mIsExtern)) isInlined = false; @@ -13391,12 +13594,12 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc methodRef.mMethodRefFlags = (BfMethodRefFlags)(methodRef.mMethodRefFlags | BfMethodRefFlag_AlwaysInclude); else methodRef.mMethodRefFlags = BfMethodRefFlag_None; - + if (!isGenFunction) - { + { BfIRValue* irFuncPtr = NULL; if (mFuncReferences.TryGetValue(methodRef, &irFuncPtr)) - return BfModuleMethodInstance(methodInstance, *irFuncPtr); + return BfModuleMethodInstance(methodInstance, *irFuncPtr); } if (mAwaitingInitFinish) @@ -13429,13 +13632,14 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc inlineMethodRequest->mFromModule = this; inlineMethodRequest->mFunc = func; inlineMethodRequest->mFromModuleRevision = mRevision; - inlineMethodRequest->mMethodInstance = methodInstance; + inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx; + inlineMethodRequest->mMethodInstance = methodInstance; BF_ASSERT(mIsModuleMutable); - + BfLogSysM("mInlineMethodWorkList %p for method %p in module %p in ReferenceExternalMethodInstance\n", inlineMethodRequest, methodInstance, this); } } - + return BfModuleMethodInstance(methodInstance, func); } @@ -13461,7 +13665,7 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance) if (methodDecl != NULL) { auto attributesDirective = methodDecl->mAttributes; - if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL)) + if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL)) { if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(attributesDirective)) sourceClassifier->VisitChild(attributesDirective); @@ -13473,7 +13677,7 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance) // Only allow attributes on System.Object methods that can be handled inside the DefBuilder GetMethodCustomAttributes(methodInstance); } - BF_ASSERT(mModuleOptions == NULL); + BF_ASSERT(mModuleOptions == NULL); if (methodInstance->GetCustomAttributes() != NULL) { auto project = typeInst->mTypeDef->mProject; @@ -13533,24 +13737,24 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance) specModuleName += StrFormat("O%d", wantOptions.mOptLevel); if (wantOptions.mSIMDSetting != moduleOptions.mSIMDSetting) specModuleName += StrFormat("SIMD%d", wantOptions.mSIMDSetting); - + declareModule = new BfModule(mContext, specModuleName); declareModule->mProject = project; declareModule->mModuleOptions = new BfModuleOptions(); *declareModule->mModuleOptions = wantOptions; - declareModule->mParentModule = lastCheckModule; + declareModule->mParentModule = lastCheckModule; declareModule->Init(); lastCheckModule->mNextAltModule = declareModule; } } - } + } declareModule->PrepareForIRWriting(typeInst); return declareModule; } BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType) -{ +{ if (methodDef->mMethodType == BfMethodType_Init) return BfModuleMethodInstance(); @@ -13580,7 +13784,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BfLocalMethod* localMethod; if (rootMethodState->mLocalMethodCache.TryGetValue(methodDef->mName, &localMethod)) { - // Handle the def in the correct method state + // Handle the def in the correct method state return GetLocalMethodInstance(localMethod, methodGenericArguments); } @@ -13594,8 +13798,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM #endif BF_ASSERT(methodDef->mMethodType != BfMethodType_Ignore); - - + // We need to do the 'mNeedsMethodProcessing' check because we want to do a proper initial "awaiting reference" population // on the methods before we handle an on-demand situation. This also ensures that our type options are set before doing // a FinishInit @@ -13621,21 +13824,21 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM } } } - + bool tryModuleMethodLookup = false; BfModuleMethodInstance moduleMethodInst; - + BfModule* instModule = typeInst->mModule; - + if (keepInCurrentModule) { // Stay here instModule = this; } - + if (this == mContext->mUnreifiedModule) { - // Stay in this 'resolve only' module here + // Stay in this 'resolve only' module here } else if (flags & BfGetMethodInstanceFlag_ExplicitResolveOnlyPass) { @@ -13646,14 +13849,14 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BF_ASSERT(instModule == mParentModule); } else if (instModule != this) - { + { if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32)) flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_DepthExceeded); if ((!mIsComptimeModule) && (!mIsReified) && (instModule->mIsReified)) { BF_ASSERT(!mCompiler->mIsResolveOnly); - // A resolve-only module is specializing a method from a type in a reified module, + // A resolve-only module is specializing a method from a type in a reified module, // we need to take care that this doesn't cause anything new to become reified BfModuleMethodInstance moduleMethodInstance = mContext->mUnreifiedModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_ExplicitResolveOnlyPass), foreignType); if (!moduleMethodInstance) @@ -13684,16 +13887,16 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM //specializationRequest->mMethodDef = methodDef; specializationRequest->mMethodGenericArguments = methodGenericArguments; specializationRequest->mType = typeInst; - specializationRequest->mFlags = flags; + specializationRequest->mFlags = flags; } } auto defFlags = (BfGetMethodInstanceFlags)(flags & ~BfGetMethodInstanceFlag_ForceInline); - + defFlags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_NoReference); if (mIsComptimeModule) - { + { defFlags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly); if (!mCompiler->mIsResolveOnly) defFlags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_NoForceReification | BfGetMethodInstanceFlag_Unreified | BfGetMethodInstanceFlag_MethodInstanceOnly); @@ -13711,7 +13914,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM CheckHotMethod(moduleMethodInst.mMethodInstance, ""); } } - } + } if (tryModuleMethodLookup) { @@ -13722,7 +13925,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM if (((flags & BfGetMethodInstanceFlag_ForceInline) != 0) && (!methodDef->mAlwaysInline)) { auto moduleMethodInstance = GetMethodInstance(typeInst, methodDef, methodGenericArguments, (BfGetMethodInstanceFlags)(flags & ~BfGetMethodInstanceFlag_ForceInline), foreignType); - if (moduleMethodInstance) + if (moduleMethodInstance) return ReferenceExternalMethodInstance(moduleMethodInstance.mMethodInstance, flags); return moduleMethodInst; } @@ -13731,22 +13934,22 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM bool hadConcreteInterfaceGenericArgument = false; if ((flags & BfGetMethodInstanceFlag_Unreified) != 0) - isReified = false; + isReified = false; if ((flags & BfGetMethodInstanceFlag_ExplicitResolveOnlyPass) != 0) { - isReified = false; + isReified = false; } - BfTypeVector sanitizedMethodGenericArguments; + BfTypeVector sanitizedMethodGenericArguments; SizedArray projectList; - + bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0; if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0)) isUnspecializedPass = false; // Check for whether we are an extension method from a project that does not hold the root type, AND that isn't already the project for this type - bool isExternalExtensionMethod = false; + bool isExternalExtensionMethod = false; if ((!typeInst->IsUnspecializedType()) && (!isUnspecializedPass)) { if (((flags & BfGetMethodInstanceFlag_ForeignMethodDef) == 0) && @@ -13772,7 +13975,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { BF_ASSERT(typeInst->mTypeDef->mIsCombinedPartial); projectList.push_back(methodDef->mDeclaringType->mProject); - } + } } } @@ -13783,7 +13986,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { auto genericTypeInst = (BfTypeInstance*)typeInst; if (genericTypeInst->mGenericTypeInfo->mProjectsReferenced.empty()) - genericTypeInst->GenerateProjectsReferenced(); + genericTypeInst->GenerateProjectsReferenced(); typeProjectsCounts = (int)genericTypeInst->mGenericTypeInfo->mProjectsReferenced.size(); projectList.Insert(0, &genericTypeInst->mGenericTypeInfo->mProjectsReferenced[0], genericTypeInst->mGenericTypeInfo->mProjectsReferenced.size()); } @@ -13793,8 +13996,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM projectList.Insert(0, typeInst->mTypeDef->mProject); } - isUnspecializedPass = true; - + isUnspecializedPass = true; + for (int genericArgIdx = 0; genericArgIdx < (int) methodGenericArguments.size(); genericArgIdx++) { auto genericArgType = methodGenericArguments[genericArgIdx]; @@ -13814,14 +14017,14 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM isUnspecializedPass = false; } else - { + { BfTypeUtils::GetProjectList(genericArgType, &projectList, typeProjectsCounts); isUnspecializedPass = false; } sanitizedMethodGenericArguments.push_back(genericArgType); } - + if ((int)projectList.size() > typeProjectsCounts) { // Just leave the new items @@ -13836,8 +14039,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM projectList.Clear(); } } - - const BfTypeVector& lookupMethodGenericArguments = isUnspecializedPass ? BfTypeVector() : sanitizedMethodGenericArguments; + + const BfTypeVector& lookupMethodGenericArguments = isUnspecializedPass ? BfTypeVector() : sanitizedMethodGenericArguments; BfMethodInstanceGroup* methodInstGroup = NULL; if ((flags & BfGetMethodInstanceFlag_ForeignMethodDef) != 0) { @@ -13893,20 +14096,20 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM } else { - methodInstGroup = &typeInst->mMethodInstanceGroups[methodDef->mIdx]; + methodInstGroup = &typeInst->mMethodInstanceGroups[methodDef->mIdx]; } if (methodInstGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) { - if (typeInst->mDefineState > BfTypeDefineState_DefinedAndMethodsSlotted) + if (typeInst->mDefineState > BfTypeDefineState_DefinedAndMethodsSlotted) { BfLogSysM("Forcing BfMethodOnDemandKind_NotSet to BfMethodOnDemandKind_AlwaysInclude for Method:%s in Type:%p\n", methodDef->mName.c_str(), typeInst); - methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; + methodInstGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; } } - + BfIRFunction prevIRFunc; - + bool doingRedeclare = false; BfMethodInstance* methodInstance = NULL; @@ -13914,7 +14117,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { if (!mCompiler->mIsResolveOnly) BF_ASSERT(mCompiler->mCompileState <= BfCompiler::CompileState_Normal); - methodInstance->mIsReified = true; + methodInstance->mIsReified = true; }; if (lookupMethodGenericArguments.size() == 0) @@ -13977,7 +14180,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { if (methodInstance->mMethodProcessRequest != NULL) { - // Disconnect method process request + // Disconnect method process request methodInstance->mMethodProcessRequest->mMethodInstance = NULL; methodInstance->mMethodProcessRequest = NULL; } @@ -14005,7 +14208,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM methodInstance->mIRFunction = BfIRFunction(); if (!mIsModuleMutable) StartExtension(); - + if ((!mBfIRBuilder->mIgnoreWrites) && (methodInstance->mDeclModule != NULL)) { StringT<512> mangledName; @@ -14019,14 +14222,14 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM AddMethodToWorkList(methodInstance); } - } + } } } else { if (methodInstGroup->mDefault == NULL) - { - auto defaultMethodInstance = GetMethodInstance(typeInst, methodDef, BfTypeVector(), + { + auto defaultMethodInstance = GetMethodInstance(typeInst, methodDef, BfTypeVector(), (BfGetMethodInstanceFlags)((flags & (BfGetMethodInstanceFlag_ForeignMethodDef)) | BfGetMethodInstanceFlag_UnspecializedPass | BfGetMethodInstanceFlag_MethodInstanceOnly), foreignType); methodInstGroup = defaultMethodInstance.mMethodInstance->mMethodInstanceGroup; } @@ -14034,7 +14237,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BF_ASSERT(lookupMethodGenericArguments.size() != 0); if (methodInstGroup->mMethodSpecializationMap == NULL) methodInstGroup->mMethodSpecializationMap = new BfMethodInstanceGroup::MapType(); - + BfMethodInstance** methodInstancePtr = NULL; if (methodInstGroup->mMethodSpecializationMap->TryGetValue(lookupMethodGenericArguments, &methodInstancePtr)) { @@ -14086,9 +14289,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM } } } - + if ((methodInstance != NULL) && (!doingRedeclare)) - { + { SetMethodDependency(methodInstance); if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) @@ -14122,7 +14325,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM AddMethodToWorkList(methodInstance); } else - { + { methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Referenced; auto owningModule = methodInstance->GetOwner()->mModule; if (!owningModule->mIsScratchModule) @@ -14160,8 +14363,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM inlineMethodRequest->mFromModule = this; inlineMethodRequest->mFunc = methodInstance->mIRFunction; inlineMethodRequest->mFromModuleRevision = mRevision; - inlineMethodRequest->mMethodInstance = methodInstance; - + inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx; + inlineMethodRequest->mMethodInstance = methodInstance; + BfLogSysM("mInlineMethodWorkList %p for method %p in module %p in GetMethodInstance\n", inlineMethodRequest, methodInstance, this); BF_ASSERT(mIsModuleMutable); } @@ -14176,7 +14380,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM return methodInstance; if (methodInstance->mDeclModule != this) - return ReferenceExternalMethodInstance(methodInstance, flags); + return ReferenceExternalMethodInstance(methodInstance, flags); if ((!methodInstance->mIRFunction) && (mIsModuleMutable) && (!mBfIRBuilder->mIgnoreWrites)) { @@ -14188,7 +14392,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM auto func = CreateDllImportGlobalVar(methodInstance, true); BF_ASSERT(func); mFuncReferences[methodInstance] = func; - } + } } return BfModuleMethodInstance(methodInstance); @@ -14219,7 +14423,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM GetMethodInstance(typeInst, methodDef, BfTypeVector(), BfGetMethodInstanceFlag_UnspecializedPass); } } - + if (methodInstance == NULL) { if (!mCompiler->EnsureCeUnpaused(typeInst)) @@ -14239,7 +14443,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BfLogSysM("Created Default MethodInst: %p TypeInst: %p Group: %p\n", methodInstance, typeInst, methodInstGroup); } else - { + { bool depthExceeded = ((flags & BfGetMethodInstanceFlag_DepthExceeded) != 0); if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth >= 32)) @@ -14256,21 +14460,21 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BF_ASSERT(added); methodInstance = new BfMethodInstance(); *methodInstancePtr = methodInstance; - - if (mCompiler->IsAutocomplete()) - methodInstance->mRequestedByAutocomplete = true; - + + if (mCompiler->IsAutocomplete()) + methodInstance->mRequestedByAutocomplete = true; + BfLogSysM("Created Specialized MethodInst: %p TypeInst: %p\n", methodInstance, typeInst); } if ((prevIRFunc) && (!prevIRFunc.IsFake())) - methodInstance->mIRFunction = prevIRFunc; // Take it over + methodInstance->mIRFunction = prevIRFunc; // Take it over } methodInstance->mMethodDef = methodDef; methodInstance->mAlwaysInline = methodDef->mAlwaysInline; methodInstance->mMethodInstanceGroup = methodInstGroup; - methodInstance->mIsReified = isReified; + methodInstance->mIsReified = isReified; SetupMethodIdHash(methodInstance); @@ -14282,7 +14486,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM BF_ASSERT(foreignType != NULL); methodInstance->GetMethodInfoEx()->mForeignType = foreignType; } - + if ((typeInst->IsInstanceOf(mCompiler->mValueTypeTypeDef)) && (methodDef->mName == BF_METHODNAME_EQUALS)) { if (!lookupMethodGenericArguments.empty()) @@ -14298,7 +14502,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { methodInstance->mMangleWithIdx = true; } - + BF_ASSERT(typeInst == methodInstance->GetOwner()); auto methodDeclaration = methodDef->GetMethodDeclaration(); @@ -14308,10 +14512,10 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { auto genericParamType = GetGenericParamType(BfGenericParamKind_Method, genericParamIdx); methodInstance->GetMethodInfoEx()->mMethodGenericArguments.Add(genericParamType); - } + } } else if ((methodDeclaration != NULL) && (methodDeclaration->mGenericParams != NULL)) - { + { if (!sanitizedMethodGenericArguments.IsEmpty()) methodInstance->GetMethodInfoEx()->mMethodGenericArguments = sanitizedMethodGenericArguments; if (methodDef->mGenericParams.size() != sanitizedMethodGenericArguments.size()) @@ -14326,7 +14530,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM if (genericArg->IsPrimitiveType()) genericArg = GetWrappedStructType(genericArg); if (genericArg != NULL) - AddDependency(genericArg, typeInst, BfDependencyMap::DependencyFlag_MethodGenericArg); + AddDependency(genericArg, typeInst, BfDependencyMap::DependencyFlag_MethodGenericArg); } } @@ -14338,20 +14542,20 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx); methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance); - } + } } for (int externConstraintIdx = 0; externConstraintIdx < (int)methodDef->mExternalConstraints.size(); externConstraintIdx++) { auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, externConstraintIdx + (int)methodDef->mGenericParams.size()); methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance); - } - + } + bool addToWorkList = !processNow; if (mCompiler->GetAutoComplete() != NULL) { if (typeInst->IsSpecializedByAutoCompleteMethod()) - addToWorkList = false; + addToWorkList = false; if (methodInstance->mRequestedByAutocomplete) addToWorkList = false; } @@ -14370,9 +14574,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM if ((!methodInstance->mIsReified) && (mCompiler->mCompileState != BfCompiler::CompileState_Normal)) { - // We can be sure this method won't become reified later. Normally we can "go either way" with an unreified method + // We can be sure this method won't become reified later. Normally we can "go either way" with an unreified method // of a reified module - - // If we declare it in the reified module then we can switch it to "reified" before actual processing without any extra work, + // If we declare it in the reified module then we can switch it to "reified" before actual processing without any extra work, // BUT if we don't reify it then we have to remove the body after processing. // But if we declare it in the unreified module module and then end up needing to reify it then we need to re-declare it in // the proper reified module. @@ -14388,7 +14592,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { declareModule->PrepareForIRWriting(methodInstance->GetOwner()); } - } + } SetMethodDependency(methodInstance); @@ -14402,15 +14606,15 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM addToWorkList = false; } - if ((flags & BfGetMethodInstanceFlag_MethodInstanceOnly) != 0) + if (((flags & BfGetMethodInstanceFlag_MethodInstanceOnly) != 0) && (methodInstGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude)) { addToWorkList = false; } // if ((flags & BfGetMethodInstanceFlag_NoReference) != 0) // addToWorkList = false; - - declareModule->DoMethodDeclaration(methodDef->GetMethodDeclaration(), false, addToWorkList); + + declareModule->DoMethodDeclaration(methodDef->GetMethodDeclaration(), false, addToWorkList); if (processNow) { @@ -14418,7 +14622,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM ProcessMethod(methodInstance); } - if (IsSkippingExtraResolveChecks()) + if (IsSkippingExtraResolveChecks()) return BfModuleMethodInstance(methodInstance, BfIRFunction()); if (methodInstance->mDeclModule != this) @@ -14438,7 +14642,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfMethodInstance* methodInsta BfMethodInstance* BfModule::GetOuterMethodInstance(BfMethodInstance* methodInstance) { if (!methodInstance->mMethodDef->mIsLocalMethod) - return NULL; + return NULL; auto outerLocal = methodInstance->mMethodInfoEx->mClosureInstanceInfo->mLocalMethod->mOuterLocalMethod; if (outerLocal == NULL) return NULL; @@ -14452,9 +14656,9 @@ BfMethodInstance* BfModule::GetOuterMethodInstance(BfMethodInstance* methodInsta void BfModule::SetupMethodIdHash(BfMethodInstance* methodInstance) { HashContext hashCtx; - + std::function _MixinMethodInstance = [&](BfMethodInstance* methodInstance) - { + { hashCtx.Mixin(methodInstance->GetOwner()->mTypeId); hashCtx.Mixin(methodInstance->mMethodDef->mIdx); @@ -14467,7 +14671,7 @@ void BfModule::SetupMethodIdHash(BfMethodInstance* methodInstance) }; _MixinMethodInstance(methodInstance); - + if (methodInstance->mMethodDef->mIsLocalMethod) { auto outmostMethodInstance = mCurMethodState->GetRootMethodState()->mMethodInstance; @@ -14476,7 +14680,7 @@ void BfModule::SetupMethodIdHash(BfMethodInstance* methodInstance) BF_ASSERT((outmostMethodInstance->mIdHash != 0) || (outmostMethodInstance->mIsAutocompleteMethod)); hashCtx.Mixin(outmostMethodInstance->mIdHash); } - } + } methodInstance->mIdHash = (int64)hashCtx.Finish64(); } @@ -14492,21 +14696,21 @@ bool BfModule::CheckUseMethodInstance(BfMethodInstance* methodInstance, BfAstNod BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType) { BfIRValue globalValue; - + BfIRValue* globalValuePtr = NULL; if (mInterfaceSlotRefs.TryGetValue(ifaceType, &globalValuePtr)) { globalValue = *globalValuePtr; } - + if (!globalValue) { // This is necessary to reify the interface type - PopulateType(ifaceType); - + PopulateType(ifaceType); + StringT<512> slotVarName; BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), ifaceType, "sBfSlotOfs"); - BfType* intType = GetPrimitiveType(BfTypeCode_Int32); + BfType* intType = GetPrimitiveType(BfTypeCode_Int32); BfIRValue value; if ((mCompiler->mHotState != NULL) && (ifaceType->mSlotNum >= 0)) @@ -14532,7 +14736,7 @@ void BfModule::HadSlotCountDependency() return; BF_ASSERT(!mBfIRBuilder->mIgnoreWrites); BF_ASSERT((mUsedSlotCount == BF_MAX(mCompiler->mMaxInterfaceSlots, 0)) || (mUsedSlotCount == -1)); - mUsedSlotCount = BF_MAX(mCompiler->mMaxInterfaceSlots, 0); + mUsedSlotCount = BF_MAX(mCompiler->mMaxInterfaceSlots, 0); } BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) @@ -14553,6 +14757,10 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) { return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mRevision), GetPrimitiveType(BfTypeCode_Int32)); } + if (str == "#NextId") + { + return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int64, (uint64)++mCompiler->mUniqueId), GetPrimitiveType(BfTypeCode_Int32)); + } if (str == "#ModuleName") { return BfTypedValue(GetStringObjectValue(mModuleName), ResolveTypeDef(mCompiler->mStringTypeDef)); @@ -14567,7 +14775,7 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) return BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Int32, mCompiler->mOptions.mAllocStackCount), GetPrimitiveType(BfTypeCode_Int32)); } - if (mCurMethodState->mMixinState != NULL) + if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)) { if (str == "#CallerLineNum") { @@ -14594,6 +14802,25 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str) filePath = mCurMethodState->mMixinState->mInjectFilePosition.mFileInstance->mParser->mFileName; return BfTypedValue(GetStringObjectValue(GetFileDir(filePath)), ResolveTypeDef(mCompiler->mStringTypeDef)); } + else if (str == "#CallerTypeName") + { + String typeName = ""; + if (mCurMethodState->mMixinState->mMixinMethodInstance) + typeName = TypeToString(mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner()); + return BfTypedValue(GetStringObjectValue(typeName), ResolveTypeDef(mCompiler->mStringTypeDef)); + } + else if (str == "#CallerType") + { + auto typeType = ResolveTypeDef(mCompiler->mTypeTypeDef); + BfType* type = NULL; + if (mCurMethodState->mMixinState->mMixinMethodInstance) + type = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner(); + if (type != NULL) + { + AddDependency(type, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); + return BfTypedValue(CreateTypeDataRef(type), typeType); + } + } else if (str == "#CallerMemberName") { String memberName = ""; @@ -14653,11 +14880,10 @@ BfTypedValue BfModule::GetCompilerFieldValue(BfTypedValue typedValue) return BfTypedValue(); } - BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) -{ +{ BfIRValue globalValue; - + auto fieldDef = fieldInstance->GetFieldDef(); if ((fieldDef->mIsConst) && (!fieldDef->mIsExtern)) @@ -14671,15 +14897,15 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) { return GetDefaultTypedValue(fieldInstance->GetResolvedType()); } - } + } - if ((mIsScratchModule) && (mCompiler->mIsResolveOnly)) + if ((mIsScratchModule) && (mCompiler->mIsResolveOnly) && (!fieldInstance->mOwner->IsInstanceOf(mCompiler->mCompilerTypeDef))) { // Just fake it for the extern and unspecialized modules - // We can't do this for compilation because unreified methods with default params need to get acutal global variable refs + // We can't do this for compilation because unreified methods with default params need to get actual global variable refs return BfTypedValue(mBfIRBuilder->CreateConstNull(), fieldInstance->GetResolvedType(), true); } - + BfIRValue* globalValuePtr = NULL; if (mStaticFieldRefs.TryGetValue(fieldInstance, &globalValuePtr)) { @@ -14694,7 +14920,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) } } else - { + { StringT<512> staticVarName; BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance); @@ -14705,7 +14931,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) } if (mIsComptimeModule) - { + { mCompiler->mCeMachine->QueueStaticField(fieldInstance, staticVarName); } @@ -14714,6 +14940,9 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) { BfIRType irType = mBfIRBuilder->MapType(typeType); + if (fieldInstance->IsAppendedObject()) + irType = mBfIRBuilder->MapTypeInst(typeType->ToTypeInstance()); + SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mBfIRBuilder->mIgnoreWrites || staticVarName.StartsWith('#')); globalValue = mBfIRBuilder->CreateGlobalVariable( @@ -14723,19 +14952,21 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) BfIRValue(), staticVarName, IsThreadLocal(fieldInstance)); - + BF_ASSERT(globalValue); mStaticFieldRefs[fieldInstance] = globalValue; - + BfLogSysM("Mod:%p Type:%p ReferenceStaticField %p -> %p\n", this, fieldInstance->mOwner, fieldInstance, globalValue); } - } + } auto type = fieldInstance->GetResolvedType(); if (type->IsValuelessType()) return BfTypedValue(globalValue, type); - return BfTypedValue(globalValue, type, !fieldDef->mIsConst); + if (fieldDef->mIsVolatile) + return BfTypedValue(globalValue, type, BfTypedValueKind_VolatileAddr); + return BfTypedValue(globalValue, type, !fieldDef->mIsConst && !fieldInstance->IsAppendedObject()); } BfFieldInstance* BfModule::GetFieldInstance(BfTypeInstance* typeInst, int fieldIdx, const char* fieldName) @@ -14747,17 +14978,17 @@ BfFieldInstance* BfModule::GetFieldInstance(BfTypeInstance* typeInst, int fieldI Fail(StrFormat("Invalid field data in type '%s'", TypeToString(typeInst).c_str())); return 0; } - return &typeInst->mFieldInstances[fieldIdx]; + return &typeInst->mFieldInstances[fieldIdx]; } void BfModule::MarkUsingThis() { auto useMethodState = mCurMethodState; - while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing)) + while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing)) { useMethodState = useMethodState->mPrevMethodState; } - + if ((useMethodState != NULL) && (!useMethodState->mLocals.IsEmpty())) { auto localVar = useMethodState->mLocals[0]; @@ -14767,7 +14998,7 @@ void BfModule::MarkUsingThis() } BfTypedValue BfModule::GetThis(bool markUsing) -{ +{ if ((mIsComptimeModule) && (mCompiler->mCeMachine->mDebugger != NULL) && (mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL)) { if (mCompiler->mCeMachine->mDebugger->mCurDbgState->mExplicitThis) @@ -14780,7 +15011,7 @@ BfTypedValue BfModule::GetThis(bool markUsing) for (auto& dbgVar : activeFrame->mFunction->mDbgInfo->mVariables) { if (dbgVar.mName == "this") - return BfTypedValue(mBfIRBuilder->CreateConstAggCE(mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs), dbgVar.mType, + return BfTypedValue(mBfIRBuilder->CreateConstAggCE(mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs), dbgVar.mType, dbgVar.mIsConst ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr); } } @@ -14789,10 +15020,10 @@ BfTypedValue BfModule::GetThis(bool markUsing) } auto useMethodState = mCurMethodState; - while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing)) + while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing)) { useMethodState = useMethodState->mPrevMethodState; - } + } if (useMethodState != NULL) { @@ -14800,8 +15031,8 @@ BfTypedValue BfModule::GetThis(bool markUsing) if (useMethodState->mTempKind == BfMethodState::TempKind_NonStatic) { auto thisType = mCurTypeInstance; - if (thisType->IsValueType()) - return BfTypedValue(mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapTypeInstPtr(thisType)), thisType, BfTypedValueKind_ThisAddr); + if (thisType->IsValueType()) + return BfTypedValue(mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapTypeInstPtr(thisType)), thisType, BfTypedValueKind_ThisAddr); else return BfTypedValue(mBfIRBuilder->CreateConstNull(mBfIRBuilder->MapTypeInst(thisType)), thisType, BfTypedValueKind_ThisValue); } @@ -14811,7 +15042,7 @@ BfTypedValue BfModule::GetThis(bool markUsing) } } else - { + { //TODO: Do we allow useMethodState to be NULL anymore? return BfTypedValue(); } @@ -14854,7 +15085,7 @@ BfTypedValue BfModule::GetThis(bool markUsing) return BfTypedValue(); } - + if (useMethodState->mLocals.IsEmpty()) { // This can happen in rare non-capture cases, such as when we need to do a const expression resolve for a sized-array return type on a local method @@ -14868,7 +15099,7 @@ BfTypedValue BfModule::GetThis(bool markUsing) bool preferValue = !IsTargetingBeefBackend(); if (!thisLocal->mAddr) preferValue = true; - + bool usedVal = false; BfIRValue thisValue; if ((preferValue) && (!thisLocal->mIsLowered)) @@ -14904,10 +15135,10 @@ BfTypedValue BfModule::GetThis(bool markUsing) auto refType = (BfRefType*)field.mResolvedType; auto underlyingType = refType->GetUnderlyingType(); result = BfTypedValue(mBfIRBuilder->CreateLoad(result.mValue), underlyingType, true); - } + } if (field.mResolvedType->IsObject()) { - result = LoadValue(result); + result = LoadValue(result); result.mKind = BfTypedValueKind_ThisValue; } else @@ -14933,20 +15164,20 @@ BfTypedValue BfModule::GetThis(bool markUsing) return BfTypedValue(GetDefaultValue(thisType), thisType, BfTypedValueKind_ThisValue); } } - + if (mCurMethodInstance == NULL) return BfTypedValue(); - auto localDef = useMethodState->mLocals[0]; - auto curMethodOwner = mCurMethodInstance->mMethodInstanceGroup->mOwner; + auto localDef = useMethodState->mLocals[0]; + auto curMethodOwner = mCurMethodInstance->mMethodInstanceGroup->mOwner; if ((curMethodOwner->IsStruct()) || (curMethodOwner->IsTypedPrimitive())) - { + { if ((localDef->mResolvedType->IsTypedPrimitive()) && (!mCurMethodInstance->mMethodDef->mIsMutating)) { return BfTypedValue(thisValue, useMethodState->mLocals[0]->mResolvedType, BfTypedValueKind_ReadOnlyThisValue); } if (localDef->mIsSplat) - { + { return BfTypedValue(thisValue, useMethodState->mLocals[0]->mResolvedType, BfTypedValueKind_ThisSplatHead); } return BfTypedValue(thisValue, useMethodState->mLocals[0]->mResolvedType, localDef->mIsReadOnly ? BfTypedValueKind_ReadOnlyThisAddr : BfTypedValueKind_ThisAddr); @@ -14965,7 +15196,7 @@ BfLocalVariable* BfModule::GetThisVariable() } bool BfModule::IsInGeneric() -{ +{ return ((mCurMethodInstance != NULL) && (mCurMethodInstance->GetNumGenericArguments() != 0)) || (mCurTypeInstance->IsGenericTypeInstance()); } @@ -14974,13 +15205,13 @@ bool BfModule::InDefinitionSection() if (mCurTypeInstance != NULL) { if (mCurTypeInstance->IsUnspecializedTypeVariation()) - return false; + return false; } return !IsInSpecializedSection(); } bool BfModule::IsInSpecializedGeneric() -{ +{ if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType())) return true; if ((mCurMethodInstance == NULL) || (mCurMethodInstance->mIsUnspecialized)) @@ -14990,7 +15221,7 @@ bool BfModule::IsInSpecializedGeneric() bool BfModule::IsInSpecializedSection() { - return IsInSpecializedGeneric() || + return IsInSpecializedGeneric() || ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)); } @@ -15005,12 +15236,11 @@ bool BfModule::IsInUnspecializedGeneric() ////////////////////////////////////////////////////////////////////////// - BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd) { //if ((type->IsValuelessType()) || (type->IsMethodRef())) if (type->IsValuelessType()) - return mBfIRBuilder->GetFakeVal(); + return mBfIRBuilder->GetFakeVal(); auto allocaInst = CreateAlloca(type, doLifetimeEnd, name.c_str()); if ((!doLifetimeEnd) && (WantsLifetimes())) @@ -15025,12 +15255,12 @@ BfIRValue BfModule::AllocLocalVariable(BfType* type, const StringImpl& name, boo initLocalVariables = typeOptions->Apply(initLocalVariables, BfOptionFlags_InitLocalVariables); // Local variable inits are implicitly handled in the Beef Backend if ((initLocalVariables) && (!IsTargetingBeefBackend())) - { + { auto prevBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRInitBlock); auto storeInst = mBfIRBuilder->CreateAlignedStore(GetDefaultValue(type), allocaInst, type->mAlign); - mBfIRBuilder->ClearDebugLocation(storeInst); - mBfIRBuilder->SetInsertPoint(prevBlock); + mBfIRBuilder->ClearDebugLocation(storeInst); + mBfIRBuilder->SetInsertPoint(prevBlock); } return allocaInst; } @@ -15074,7 +15304,6 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli if (localVarDef->mResolvedType->IsValuelessType()) { - } else { @@ -15123,7 +15352,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli // { // diValue = mBfIRBuilder->CreateAliasValue(constMem); // didConstToMem = true; -// +// // diType = mBfIRBuilder->DbgCreateReferenceType(diType); // } //else @@ -15154,6 +15383,16 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli if (!mBfIRBuilder->mIgnoreWrites) { + if ((localVarDef->mIsStatic) && (localVarDef->mAddr) && (!localVarDef->mResolvedType->IsValuelessType())) + { + auto refType = CreateRefType(localVarDef->mResolvedType); + diType = mBfIRBuilder->DbgGetType(refType); + + auto refAlloca = CreateAlloca(refType); + mBfIRBuilder->CreateStore(localVarDef->mAddr, refAlloca); + diValue = refAlloca; + } + auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, localVarDef->mName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, diType, initType); localVarDef->mDbgVarInst = diVariable; @@ -15161,7 +15400,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli if (mBfIRBuilder->HasDebugLocation()) { if ((isConstant) && (!didConstToMem)) - { + { BfTypedValue result(localVarDef->mConstValue, localVarDef->mResolvedType); FixValueActualization(result); localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(result.mValue, diVariable); @@ -15177,7 +15416,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli if (isByAddr) localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertDeclare(diValue, diVariable, declareBefore); else if (diValue) - { + { localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(diValue, diVariable); } else if (mCompiler->mOptions.mToolsetType != BfToolsetType_GNU) // DWARF chokes on this: @@ -15190,10 +15429,10 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli } BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType) -{ +{ if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend()) && (!localVarDef->mResolvedType->IsValuelessType())) { - if ((!localVarDef->mValue.IsConst()) && + if ((!localVarDef->mValue.IsConst()) && (!localVarDef->mValue.IsArg()) && (!localVarDef->mValue.IsFake())) { mBfIRBuilder->CreateValueScopeRetain(localVarDef->mValue); @@ -15203,10 +15442,10 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo if (addDebugInfo) DoLocalVariableDebugInfo(localVarDef, doAliasValue, declareBefore, initType); - + localVarDef->mDeclBlock = mBfIRBuilder->GetInsertBlock(); DoAddLocalVariable(localVarDef); - + auto rootMethodState = mCurMethodState->GetRootMethodState(); if (localVarDef->mLocalVarId == -1) @@ -15220,18 +15459,18 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo { if (auto autoCtorDecl = BfNodeDynCast(mCurMethodInstance->mMethodDef->mMethodDeclaration)) checkLocal = false; - } + } if ((localVarDef->mNameNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!mIsComptimeModule) && (checkLocal)) - mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef); + mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef); if (((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL)) && (checkLocal)) - { - bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing); + { + bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing); if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL) && (rootMethodState->mMethodInstance != NULL) && (!mIsComptimeModule)) mCompiler->mResolvePassData->HandleLocalReference(localVarDef->mNameNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVarDef->mLocalVarId); } - + return localVarDef; } @@ -15247,7 +15486,7 @@ void BfModule::CreateDIRetVal() }*/ if ((mCurMethodState->mRetVal) || (mCurMethodState->mRetValAddr)) - { + { BfType* dbgType = mCurMethodInstance->mReturnType; BfIRValue dbgValue = mCurMethodState->mRetVal.mValue; if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) @@ -15264,7 +15503,7 @@ void BfModule::CreateDIRetVal() mCurMethodState->mDIRetVal = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, "@return", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(dbgType)); auto declareCall = mBfIRBuilder->DbgInsertDeclare(dbgValue, mCurMethodState->mDIRetVal); - } + } } BfTypedValue BfModule::CreateTuple(const Array& values, const Array& fieldNames) @@ -15272,7 +15511,7 @@ BfTypedValue BfModule::CreateTuple(const Array& values, const Arra BfTypeVector fieldTypes; for (auto arg : values) fieldTypes.Add(arg.mType); - + auto tupleType = CreateTupleType(fieldTypes, fieldNames); auto tupleTypedValue = BfTypedValue(CreateAlloca(tupleType), tupleType, true); @@ -15291,14 +15530,14 @@ BfTypedValue BfModule::CreateTuple(const Array& values, const Arra } void BfModule::CheckVariableDef(BfLocalVariable* variableDef) -{ +{ if (variableDef->mName.IsEmpty()) return; BfLocalVarEntry* localVarEntryPtr = NULL; if ((mCurMethodState != NULL) && (mCurMethodState->mLocalVarSet.TryGet(BfLocalVarEntry(variableDef), &localVarEntryPtr))) { - auto checkLocal = localVarEntryPtr->mLocalVar; + auto checkLocal = localVarEntryPtr->mLocalVar; if ((checkLocal->mLocalVarIdx >= mCurMethodState->GetLocalStartIdx()) && (!checkLocal->mIsShadow)) { BfError* error; @@ -15318,7 +15557,7 @@ void BfModule::CheckVariableDef(BfLocalVariable* variableDef) if ((checkLocal->mNameNode != NULL) && (error != NULL)) mCompiler->mPassInstance->MoreInfo("Previous declaration", checkLocal->mNameNode); return; - } + } } } @@ -15339,14 +15578,14 @@ BfScopeData* BfModule::FindScope(BfAstNode* scopeName, BfMixinState* fromMixinSt return &mCurMethodState->mHeadScope; } else if (tokenNode->GetToken() == BfToken_Mixin) - { + { if (fromMixinState == NULL) { if (mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin) Fail("'mixin' scope specifier can only be used within a mixin declaration", scopeName); return mCurMethodState->mCurScope; } - + fromMixinState->mUsedInvocationScope = true; return fromMixinState->mTargetScope; } @@ -15386,7 +15625,7 @@ BfScopeData* BfModule::FindScope(BfAstNode* scopeName, BfMixinState* fromMixinSt { return FindScope(scopeNode->mTargetNode, allowAcrossDeferredBlock); } - + return mCurMethodState->mCurScope; } @@ -15436,7 +15675,7 @@ void BfModule::ClearLifetimeEnds() bool BfModule::WantsDebugInfo() { - if ((mCurMethodInstance != NULL) && + if ((mCurMethodInstance != NULL) && ((mCurMethodInstance->mIsUnspecialized) || (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin))) return false; @@ -15494,7 +15733,7 @@ BfReflectKind BfModule::GetUserReflectKind(BfTypeInstance* attrType) } BfReflectKind BfModule::GetReflectKind(BfReflectKind reflectKind, BfTypeInstance* typeInstance) -{ +{ auto checkTypeInstance = typeInstance; while (checkTypeInstance != NULL) { @@ -15537,7 +15776,7 @@ BfReflectKind BfModule::GetReflectKind(BfReflectKind reflectKind, BfTypeInstance auto iface = ifaceEntry.mInterfaceType; auto customAttr = iface->mCustomAttributes->Get(mCompiler->mReflectAttributeTypeDef); if (customAttr != NULL) - { + { for (auto& prop : customAttr->mSetProperties) { auto propDef = prop.mPropertyRef.mTypeInstance->mTypeDef->mProperties[prop.mPropertyRef.mPropIdx]; @@ -15572,7 +15811,7 @@ bool BfModule::HasDeferredScopeCalls(BfScopeData* scope) checkScope = checkScope->mPrevScope; } - return false; + return false; } void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeData, BfIRBlock doneBlock) @@ -15609,7 +15848,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } // Why did we want to do SetIllegalSrcPos here? - // Don't we always want to step onto these instances? + // Don't we always want to step onto these instances? // Find a case where we don't and perhaps only do it there. // The downside was that 'EmitEnsureInstructionAt' on the end of block statements causes // a (seemingly) unneeded NOP when we do SetIllegalSrcPos @@ -15647,15 +15886,15 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa while (checkScope != NULL) { if (checkScope->mCloseNode != NULL) - deferCloseNode = checkScope->mCloseNode; - + deferCloseNode = checkScope->mCloseNode; + if (doneBlock) { // Try to find a match where we've already emitted these calls and then jumped to the correct block for (auto& checkHandler : checkScope->mDeferredHandlers) { if (checkHandler.mDoneBlock == doneBlock) - { + { scopeJumpBlock = checkScope; mBfIRBuilder->CreateBr(checkHandler.mHandlerBlock); mBfIRBuilder->ClearDebugLocation_Last(); @@ -15669,16 +15908,16 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } bool hasWork = (checkScope->mSavedStack) || (checkScope->mDeferredCallEntries.mHead != NULL); - + if (checkScope != scopeData) // Only emit a block for deferred lifetimes if we're going back beyond this entry hasWork |= (!deferredLifetimeEnds.IsEmpty()); if (hasWork) { SetAndRestoreValue prevScope(mCurMethodState->mCurScope, checkScope); - + if (deferCloseNode != NULL) - { + { UpdateSrcPos(deferCloseNode); } @@ -15687,9 +15926,9 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa if (doneBlock) { - bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth; + bool crossingMixin = mCurMethodState->mCurScope->mMixinDepth != checkScope->mMixinDepth; - String blockName = "deferredCalls"; + String blockName = "deferredCalls"; //blockName += StrFormat("_%d", mBfIRBuilder->mBlockCount); BfDeferredHandler deferredHandler; @@ -15710,32 +15949,32 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa mBfIRBuilder->AddBlock(deferredHandler.mHandlerBlock); mBfIRBuilder->SetInsertPoint(deferredHandler.mHandlerBlock); } - + deferredHandler.mDoneBlock = doneBlock; - + if (!mBfIRBuilder->mIgnoreWrites) checkScope->mDeferredHandlers.push_back(deferredHandler); - + if (checkScope == &mCurMethodState->mHeadScope) { if (!mCurMethodState->mDIRetVal) - { - // Weird case- if we have a return from a mixin, we need the DbgLoc to be for the mixin but we need the DIRetVal to + { + // Weird case- if we have a return from a mixin, we need the DbgLoc to be for the mixin but we need the DIRetVal to // be scoped to the physical method - + /*if (deferCloseNode != NULL) - { - UpdateSrcPos(deferCloseNode); + { + UpdateSrcPos(deferCloseNode); }*/ CreateDIRetVal(); - } + } } if (checkScope != mCurMethodState->mTailScope) { if (deferredHandler.mHandlerBlock.IsFake()) { - BF_ASSERT(mBfIRBuilder->mIgnoreWrites); + BF_ASSERT(mBfIRBuilder->mIgnoreWrites); } if (!mBfIRBuilder->mIgnoreWrites) @@ -15754,8 +15993,8 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa SetAndRestoreValue prevMixinState(mCurMethodState->mMixinState, checkScope->mMixinState); if (deferCloseNode != NULL) - { - UpdateSrcPos(deferCloseNode); + { + UpdateSrcPos(deferCloseNode); } if (wantsNop) EmitEnsureInstructionAt(); @@ -15768,7 +16007,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa { // Already handled, can happen if we defer again within the block deferredCallEntry = deferredCallEntry->mNext; - continue; + continue; } auto prevHead = checkScope->mDeferredCallEntries.mHead; @@ -15790,7 +16029,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa if (checkScope->mSavedStack) { - checkScope->mSavedStackUses.Add(mBfIRBuilder->CreateStackRestore(checkScope->mSavedStack)); + checkScope->mSavedStackUses.Add(mBfIRBuilder->CreateStackRestore(checkScope->mSavedStack)); if (mCurMethodState->mDynStackRevIdx) { @@ -15803,7 +16042,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa if (!checkScope->mIsScopeHead) { - // We manually emit function-level lifetime ends after the 'ret' in ProcessMethod + // We manually emit function-level lifetime ends after the 'ret' in ProcessMethod if (!IsTargetingBeefBackend()) { for (auto lifetimeEnd : checkScope->mDeferredLifetimeEnds) @@ -15843,16 +16082,16 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa BfScopeData* checkScope = mCurMethodState->mCurScope; while (checkScope != NULL) - { + { if (checkScope == scopeJumpBlock) break; - if (!checkScope->mIsScopeHead) + if (!checkScope->mIsScopeHead) { for (auto lifetimeEnd : checkScope->mDeferredLifetimeEnds) { if (needsEnsureInst) - { + { needsEnsureInst = false; } @@ -15868,7 +16107,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa } void BfModule::MarkScopeLeft(BfScopeData* scopeData, bool isNoReturn) -{ +{ if ((mCurMethodState->mDeferredLocalAssignData != NULL) && (!isNoReturn)) { auto deferredLocalAssignData = mCurMethodState->mDeferredLocalAssignData; @@ -15880,13 +16119,13 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData, bool isNoReturn) if ((deferredLocalAssignData->mScopeData != NULL) && (deferredLocalAssignData->mScopeData->mScopeDepth == scopeData->mScopeDepth)) deferredLocalAssignData->mIsUnconditional = false; deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData; - } + } } - + // When we leave a scope, mark those as assigned for deferred assignment purposes for (int localIdx = scopeData->mLocalVarStart; localIdx < (int)mCurMethodState->mLocals.size(); localIdx++) { - auto localDef = mCurMethodState->mLocals[localIdx]; + auto localDef = mCurMethodState->mLocals[localIdx]; if (localDef->mAssignedKind == BfLocalVarAssignKind_None) { bool hadAssignment = false; @@ -15894,7 +16133,7 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData, bool isNoReturn) { for (auto& entry : mCurMethodState->mDeferredLocalAssignData->mAssignedLocals) if (entry.mLocalVar == localDef) - hadAssignment = true; + hadAssignment = true; } if (!hadAssignment) { @@ -15915,7 +16154,7 @@ void BfModule::CreateReturn(BfIRValue val) mBfIRBuilder->CreateStore(val, mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); mBfIRBuilder->CreateRetVoid(); return; - } + } if (mCurMethodInstance->mReturnType->IsVar()) return; @@ -15925,7 +16164,7 @@ void BfModule::CreateReturn(BfIRValue val) mBfIRBuilder->CreateRetVoid(); return; } - + if (mCurMethodInstance->mReturnType->IsStruct()) { BfTypeCode loweredReturnType = BfTypeCode_None; @@ -15944,11 +16183,11 @@ void BfModule::CreateReturn(BfIRValue val) auto loadedReturnValue = mBfIRBuilder->CreateLoad(ptrReturnValue); mBfIRBuilder->CreateRet(loadedReturnValue); return; - } + } } - + BF_ASSERT(val); - mBfIRBuilder->CreateRet(val); + mBfIRBuilder->CreateRet(val); } void BfModule::EmitReturn(const BfTypedValue& val) @@ -16002,7 +16241,7 @@ void BfModule::EmitDefaultReturn() return; if (mCurMethodState->mIRExitBlock) - { + { EmitDeferredScopeCalls(true, NULL, mCurMethodState->mIRExitBlock); } else @@ -16022,7 +16261,7 @@ void BfModule::EmitDefaultReturn() } void BfModule::AssertErrorState() -{ +{ if (mIgnoreErrors) return; if (mHadBuildError) @@ -16057,11 +16296,11 @@ void BfModule::AssertErrorState() } if (mCurMethodInstance != NULL) { - if ((mCurMethodInstance->mMethodDef->mDeclaringType != NULL) && - (mCurMethodInstance->mMethodDef->mDeclaringType->mSource != NULL) && + if ((mCurMethodInstance->mMethodDef->mDeclaringType != NULL) && + (mCurMethodInstance->mMethodDef->mDeclaringType->mSource != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed)) return; - if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && + if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->mSource != NULL) && (mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed)) return; @@ -16107,7 +16346,7 @@ void BfModule::CreateDelegateInvokeMethod() SizedArray staticParamTypes; SizedArray staticFuncArgs; SizedArray memberFuncArgs; - + auto multicastDelegateType = typeInstance->mBaseType; if (multicastDelegateType->mFieldInstances.size() != 2) { @@ -16117,10 +16356,10 @@ void BfModule::CreateDelegateInvokeMethod() auto multicastDelegate = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapType(multicastDelegateType)); auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(multicastDelegate, 0, 2); // Load 'delegate.mTarget' - auto fieldVal = mBfIRBuilder->CreateAlignedLoad(fieldPtr, mSystem->mPtrSize); - + auto fieldVal = mBfIRBuilder->CreateAlignedLoad(fieldPtr, mSystem->mPtrSize); + BfExprEvaluator exprEvaluator(this); - + SizedArray origParamTypes; BfIRType origReturnType; BfIRType staticReturnType; @@ -16128,14 +16367,14 @@ void BfModule::CreateDelegateInvokeMethod() if (mCurMethodInstance->mReturnType->IsValueType()) mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType, BfIRPopulateType_Full); - + if ((mIsComptimeModule) || (mCurMethodInstance->GetStructRetIdx() != 0)) memberFuncArgs.push_back(BfIRValue()); // Push 'target' int thisIdx = 0; if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) - { - thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; + { + thisIdx = mCurMethodInstance->GetStructRetIdx() ^ 1; memberFuncArgs.push_back(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx())); } @@ -16146,12 +16385,12 @@ void BfModule::CreateDelegateInvokeMethod() memberFuncArgs.push_back(BfIRValue()); // Push 'target' mCurMethodInstance->GetIRFunctionInfo(this, staticReturnType, staticParamTypes, true); - + for (int i = 1; i < (int)mCurMethodState->mLocals.size(); i++) { BfTypedValue localVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[i], true); exprEvaluator.PushArg(localVal, staticFuncArgs); - exprEvaluator.PushArg(localVal, memberFuncArgs); + exprEvaluator.PushArg(localVal, memberFuncArgs); } auto staticFunc = mBfIRBuilder->CreateFunctionType(staticReturnType, staticParamTypes, false); @@ -16159,11 +16398,11 @@ void BfModule::CreateDelegateInvokeMethod() auto staticFuncPtrPtr = mBfIRBuilder->GetPointerTo(staticFuncPtr); auto trueBB = mBfIRBuilder->CreateBlock("if.then", true); - auto falseBB = mBfIRBuilder->CreateBlock("if.else"); + auto falseBB = mBfIRBuilder->CreateBlock("if.else"); auto doneBB = mBfIRBuilder->CreateBlock("done"); auto checkTargetNull = mBfIRBuilder->CreateIsNotNull(fieldVal); - mBfIRBuilder->CreateCondBr(checkTargetNull, trueBB, falseBB); + mBfIRBuilder->CreateCondBr(checkTargetNull, trueBB, falseBB); BfIRValue nonStaticResult; BfIRValue staticResult; @@ -16171,10 +16410,10 @@ void BfModule::CreateDelegateInvokeMethod() auto callingConv = GetIRCallingConvention(mCurMethodInstance); /// Non-static invocation - { + { auto memberFuncPtr = mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapMethod(mCurMethodInstance)); auto memberFuncPtrPtr = mBfIRBuilder->GetPointerTo(memberFuncPtr); - + mBfIRBuilder->SetInsertPoint(trueBB); memberFuncArgs[thisIdx] = mBfIRBuilder->CreateBitCast(fieldVal, mBfIRBuilder->MapType(mCurTypeInstance)); auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(multicastDelegate, 0, 1); // Load 'delegate.mFuncPtr' @@ -16197,7 +16436,7 @@ void BfModule::CreateDelegateInvokeMethod() mBfIRBuilder->SetInsertPoint(falseBB); auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(multicastDelegate, 0, 1); // Load 'delegate.mFuncPtr' auto funcPtrPtr = mBfIRBuilder->CreateBitCast(fieldPtr, staticFuncPtrPtr); - auto funcPtr = mBfIRBuilder->CreateAlignedLoad(funcPtrPtr, mSystem->mPtrSize); + auto funcPtr = mBfIRBuilder->CreateAlignedLoad(funcPtrPtr, mSystem->mPtrSize); staticResult = mBfIRBuilder->CreateCall(funcPtr, staticFuncArgs); if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx(true) != -1)) { @@ -16229,7 +16468,7 @@ void BfModule::CreateDelegateInvokeMethod() { // Do nothing } - else if ((mCurMethodInstance->mReturnType->IsValuelessType()) || + else if ((mCurMethodInstance->mReturnType->IsValuelessType()) || ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))) { mBfIRBuilder->CreateRetVoid(); @@ -16245,21 +16484,20 @@ void BfModule::CreateDelegateInvokeMethod() loweredIRReturnType = mBfIRBuilder->MapType(mCurMethodInstance->mReturnType); auto phi = mBfIRBuilder->CreatePhi(loweredIRReturnType, 2); mBfIRBuilder->AddPhiIncoming(phi, nonStaticResult, trueBB); - mBfIRBuilder->AddPhiIncoming(phi, staticResult, falseBB); + mBfIRBuilder->AddPhiIncoming(phi, staticResult, falseBB); mBfIRBuilder->CreateRet(phi); } } // "Interested" here means every method for a normal compile, and just the method the cursor is on for autocompletion bool BfModule::IsInterestedInMethod(BfTypeInstance* typeInstance, BfMethodDef* methodDef) -{ +{ auto typeDef = typeInstance->mTypeDef; - auto methodDeclaration = methodDef->mMethodDeclaration; - + auto methodDeclaration = methodDef->mMethodDeclaration; if (!mCompiler->mIsResolveOnly) return true; - + if (typeInstance->IsGenericTypeInstance()) { // We only really want to process the unspecialized type for autocompletion @@ -16270,12 +16508,12 @@ bool BfModule::IsInterestedInMethod(BfTypeInstance* typeInstance, BfMethodDef* m BfAstNode* checkNode = methodDeclaration; if (methodDeclaration == NULL) checkNode = methodDef->mBody; - + if ((!mCompiler->mResolvePassData->mParsers.IsEmpty()) && (typeDef->mTypeDeclaration->IsFromParser(mCompiler->mResolvePassData->mParsers[0]))) { if (mCompiler->mResolvePassData->mAutoComplete == NULL) - return true; - } + return true; + } return false; } @@ -16284,13 +16522,13 @@ void BfModule::CalcAppendAlign(BfMethodInstance* methodInst) methodInst->mAppendAllocAlign = 1; } -BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl& args) +BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl& args, bool force) { BP_ZONE("BfModule::TryConstCalcAppend"); BF_ASSERT(methodInst->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend); - if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) + if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (!force)) return BfTypedValue(); // We want to regenerate all ctor calls when the method internals change @@ -16316,11 +16554,11 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr { if (argIdx >= (int)args.size()) break; - auto paramType = methodInst->GetParamType(paramIdx); + auto paramType = methodInst->GetParamType(paramIdx); PopulateType(paramType); int argCount = 0; - if (!paramType->IsValuelessType()) - { + if (!paramType->IsValuelessType()) + { if ((!mIsComptimeModule) && (methodInst->GetParamIsSplat(paramIdx))) argCount = paramType->GetSplatCount(); else @@ -16348,9 +16586,9 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr } paramIdx++; - argIdx += argCount; - } - + argIdx += argCount; + } + auto methodDef = methodInst->mMethodDef; auto methodDecl = methodDef->GetMethodDeclaration(); auto methodDeclBlock = BfNodeDynCast(methodDecl->mBody); @@ -16360,7 +16598,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr BfTypedValue constValue; auto prevBlock = mBfIRBuilder->GetInsertBlock(); - + auto checkState = mCurMethodState->mConstResolveState; while (checkState != NULL) { @@ -16379,6 +16617,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr BfConstResolveState constResolveState; constResolveState.mMethodInstance = methodInst; constResolveState.mPrevConstResolveState = mCurMethodState->mConstResolveState; + constResolveState.mInCalcAppend = true; SetAndRestoreValue ignoreWrites(mBfIRBuilder->mIgnoreWrites, true); BfMethodState methodState; @@ -16396,7 +16635,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr auto paramType = methodInst->GetParamType(paramIdx); // Fix this after we allow structs to be consts //BF_ASSERT(!paramType->IsSplattable()); - + BfLocalVariable* localVar = new BfLocalVariable(); localVar->mName = methodInst->GetParamName(paramIdx); localVar->mResolvedType = paramType; @@ -16406,7 +16645,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr argIdx++; } - AppendAllocVisitor appendAllocVisitor; + AppendAllocVisitor appendAllocVisitor; appendAllocVisitor.mConstAccum = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_IntPtr)); appendAllocVisitor.mIsFirstConstPass = isFirstRun; @@ -16418,10 +16657,12 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr else appendAllocVisitor.mConstAccum = baseCtorAppendValue; } - + appendAllocVisitor.mModule = this; - - appendAllocVisitor.VisitChild(methodDecl->mBody); + + appendAllocVisitor.VisitChild(methodDecl->mBody); + if (constResolveState.mFailed) + appendAllocVisitor.mFailed = true; if (!appendAllocVisitor.mFailed) constValue = appendAllocVisitor.mConstAccum; if (isFirstRun) @@ -16443,16 +16684,16 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr } } } - } + } mBfIRBuilder->SetInsertPoint(prevBlock); - if (!constValue) + if (!constValue) { // If we did a 'force' then some params may not have been const -- only clear mMayBeConst if we had // all-const args if (wasAllConst) - { + { methodInst->mMayBeConst = false; } } @@ -16464,10 +16705,10 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) { // Any errors should only be shown in the actual CTOR call SetAndRestoreValue prevIgnoreWrites(mIgnoreErrors, true); - + auto methodDef = mCurMethodInstance->mMethodDef; BF_ASSERT((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend)); - auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration; + auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration; BfCustomAttributes* customAttributes = NULL; defer(delete customAttributes); @@ -16497,17 +16738,16 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) BfType* targetThisType = targetType; BfTypedValue target(mBfIRBuilder->GetFakeVal(), targetThisType); - + BfExprEvaluator exprEvaluator(this); BfResolvedArgs argValues; if ((ctorDeclaration != NULL) && (ctorInvocation != NULL)) { argValues.Init(&ctorInvocation->mArguments); } - + // { - } BfFunctionBindResult bindResult; bindResult.mSkipThis = true; @@ -16518,7 +16758,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) SetAndRestoreValue prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult); exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, true); } - + if (bindResult.mMethodInstance == NULL) { AssertErrorState(); @@ -16529,11 +16769,11 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) { return BfTypedValue(); } - + BF_ASSERT(bindResult.mIRArgs[0].IsFake()); bindResult.mIRArgs.RemoveAt(0); - auto calcAppendMethodModule = GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND); - BfTypedValue appendSizeTypedValue = TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, bindResult.mIRArgs); + auto calcAppendMethodModule = GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND); + BfTypedValue appendSizeTypedValue = TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, bindResult.mIRArgs, true); BF_ASSERT(calcAppendMethodModule.mMethodInstance->mAppendAllocAlign >= 0); mCurMethodInstance->mAppendAllocAlign = BF_MAX((int)mCurMethodInstance->mAppendAllocAlign, calcAppendMethodModule.mMethodInstance->mAppendAllocAlign); BF_ASSERT(calcAppendMethodModule.mMethodInstance->mEndingAppendAllocAlign > -1); @@ -16541,7 +16781,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) if (appendSizeTypedValue) return appendSizeTypedValue; - + if (constOnly) return BfTypedValue(mBfIRBuilder->GetFakeVal(), GetPrimitiveType(BfTypeCode_IntPtr)); @@ -16563,15 +16803,22 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly) bindResult.mSkipThis = true; bindResult.mWantsArgs = true; SetAndRestoreValue prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult); - exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, true); + exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, true); BF_ASSERT(bindResult.mIRArgs[0].IsFake()); bindResult.mIRArgs.RemoveAt(0); calcAppendArgs = bindResult.mIRArgs; - } - BF_ASSERT(calcAppendMethodModule.mFunc); - appendSizeTypedValue = exprEvaluator.CreateCall(NULL, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs); + } + + if (mBfIRBuilder->mIgnoreWrites) + { + appendSizeTypedValue = GetFakeTypedValue(GetPrimitiveType(BfTypeCode_IntPtr)); + } + else + { + BF_ASSERT(calcAppendMethodModule.mFunc); + appendSizeTypedValue = exprEvaluator.CreateCall(NULL, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs); + } - BF_ASSERT(appendSizeTypedValue.mType == GetPrimitiveType(BfTypeCode_IntPtr)); return appendSizeTypedValue; } @@ -16584,45 +16831,45 @@ void BfModule::EmitCtorCalcAppend() auto methodDef = mCurMethodInstance->mMethodDef; auto methodDecl = methodDef->GetMethodDeclaration(); - + Array deferredNodeList; auto methodDeclBlock = BfNodeDynCast(methodDecl->mBody); if (methodDeclBlock == NULL) - return; - + return; + AppendAllocVisitor appendAllocVisitor; auto baseCalcAppend = CallBaseCtorCalc(false); if (baseCalcAppend) - { - mBfIRBuilder->CreateStore(baseCalcAppend.mValue, mCurMethodState->mRetVal.mValue); - } + { + mBfIRBuilder->CreateStore(baseCalcAppend.mValue, mCurMethodState->mRetVal.mValue); + } appendAllocVisitor.mModule = this; appendAllocVisitor.VisitChild(methodDecl->mBody); } void BfModule::CreateStaticCtor() -{ +{ auto typeDef = mCurTypeInstance->mTypeDef; auto methodDef = mCurMethodInstance->mMethodDef; - + BfIRBlock exitBB; if ((HasCompiledOutput()) && (!mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mChainType != BfMethodChainType_ChainMember)) { auto boolType = GetPrimitiveType(BfTypeCode_Boolean); - auto didStaticInitVarAddr = mBfIRBuilder->CreateGlobalVariable( + auto didStaticInitVarAddr = mBfIRBuilder->CreateGlobalVariable( mBfIRBuilder->MapType(boolType), false, BfIRLinkageType_Internal, GetDefaultValue(boolType), "didStaticInit"); - auto initBB = mBfIRBuilder->CreateBlock("init", true); + auto initBB = mBfIRBuilder->CreateBlock("init", true); mCurMethodState->mIRExitBlock = mBfIRBuilder->CreateBlock("exit", true); - + auto didStaticInitVar = mBfIRBuilder->CreateLoad(didStaticInitVarAddr); mBfIRBuilder->CreateCondBr(didStaticInitVar, mCurMethodState->mIRExitBlock, initBB); - + mBfIRBuilder->SetInsertPoint(initBB); mBfIRBuilder->CreateStore(GetConstValue(1, boolType), didStaticInitVarAddr); } @@ -16637,30 +16884,38 @@ void BfModule::CreateStaticCtor() { if (!mCompiler->mPassInstance->HasFailed()) Fail("Internal error: System.Internal doesn't contain LoadSharedLibrary method"); - } + } } - // Fill in initializer values + // Fill in initializer values if ((!mCompiler->mIsResolveOnly) || (mCompiler->mResolvePassData->mAutoComplete == NULL)) { for (auto fieldDef : typeDef->mFields) { - if ((!fieldDef->mIsConst) && (fieldDef->mIsStatic) && (fieldDef->GetInitializer() != NULL)) + if ((!fieldDef->mIsConst) && (fieldDef->mIsStatic)) { // For extensions, only handle these fields in the appropriate extension if ((fieldDef->mDeclaringType->mTypeDeclaration != methodDef->mDeclaringType->mTypeDeclaration)) continue; - - UpdateSrcPos(fieldDef->GetInitializer()); - - auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldDef->mIdx]; + + auto initializer = fieldDef->GetInitializer(); + auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldDef->mIdx]; if (!fieldInst->mFieldIncluded) continue; if (fieldInst->mResolvedType->IsVar()) - { + { continue; } - GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true); + + if (fieldInst->IsAppendedObject()) + { + AppendedObjectInit(fieldInst); + } + else if (initializer != NULL) + { + UpdateSrcPos(initializer); + GetFieldInitializerValue(fieldInst, NULL, NULL, NULL, true); + } } } @@ -16691,9 +16946,14 @@ void BfModule::CreateStaticCtor() if ((!BfNodeIsA(fieldDef->mTypeRef)) && (!BfNodeIsA(fieldDef->mTypeRef))) { wantType = ResolveTypeRef(fieldDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowInferredSizedArray); - } - CreateValueFromExpression(fieldDef->GetInitializer(), wantType, BfEvalExprFlags_FieldInitializer); - } + } + + BfEvalExprFlags exprFlags = BfEvalExprFlags_FieldInitializer; + if (fieldDef->mIsAppend) + exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_AppendFieldInitializer); + + CreateValueFromExpression(fieldDef->GetInitializer(), wantType, exprFlags); + } } } } @@ -16701,11 +16961,11 @@ void BfModule::CreateStaticCtor() } if (mCurMethodInstance->mChainType == BfMethodChainType_ChainHead) - CallChainedMethods(mCurMethodInstance, false); + CallChainedMethods(mCurMethodInstance, false); } void BfModule::EmitDtorBody() -{ +{ if (!mCurMethodState->mIRExitBlock) mCurMethodState->mIRExitBlock = mBfIRBuilder->CreateBlock("exit", true); @@ -16719,14 +16979,14 @@ void BfModule::EmitDtorBody() auto funcPtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapMethod(mCurMethodInstance)); auto dtorPtr = mBfIRBuilder->CreateBitCast(dtorThunk, funcPtrType); - + SizedArray args; args.push_back(thisVal.mValue); auto result = mBfIRBuilder->CreateCall(dtorPtr, args); mBfIRBuilder->SetCallCallingConv(result, BfIRCallingConv_CDecl); // Fall through to Object::~this call - + auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this"); if (mIsComptimeModule) mCompiler->mCeMachine->QueueMethod(dtorFunc.mMethodInstance, dtorFunc.mFunc); @@ -16734,24 +16994,24 @@ void BfModule::EmitDtorBody() SizedArray vals = { basePtr }; result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals); mBfIRBuilder->SetCallCallingConv(result, GetIRCallingConvention(dtorFunc.mMethodInstance)); - mBfIRBuilder->SetTailCall(result); + mBfIRBuilder->SetTailCall(result); - return; + return; } auto typeDef = mCurTypeInstance->mTypeDef; - auto methodDef = mCurMethodInstance->mMethodDef; - auto methodDeclaration = methodDef->GetMethodDeclaration(); + auto methodDef = mCurMethodInstance->mMethodDef; + auto methodDeclaration = methodDef->GetMethodDeclaration(); if (mCurMethodInstance->mChainType == BfMethodChainType_ChainHead) CallChainedMethods(mCurMethodInstance, true); if (auto bodyBlock = BfNodeDynCast(methodDef->mBody)) - { - VisitEmbeddedStatement(bodyBlock); + { + VisitEmbeddedStatement(bodyBlock); if (bodyBlock->mCloseBrace != NULL) { - UpdateSrcPos(bodyBlock->mCloseBrace); + UpdateSrcPos(bodyBlock->mCloseBrace); } } else @@ -16766,10 +17026,10 @@ void BfModule::EmitDtorBody() { Fail("Destructors cannot have expression bodies", methodDeclaration->mFatArrowToken, true); } - } + } if ((!mCompiler->mIsResolveOnly) || (mCompiler->mResolvePassData->mAutoComplete == NULL)) - { + { for (int fieldIdx = (int)mCurTypeInstance->mFieldInstances.size() - 1; fieldIdx >= 0; fieldIdx--) { auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldIdx]; @@ -16816,8 +17076,8 @@ void BfModule::EmitDtorBody() BfIRValue value; if (fieldDef->mIsStatic) - { - value = ReferenceStaticField(fieldInst).mValue; + { + value = ReferenceStaticField(fieldInst).mValue; } else { @@ -16829,46 +17089,57 @@ void BfModule::EmitDtorBody() else if (!mCurTypeInstance->IsValueType()) { auto thisValue = GetThis(); - value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx); + value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx); } else - { + { AssertErrorState(); value = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(fieldInst->mResolvedType)); } } BfIRValue staticVal; - + if (hasDbgInfo) { BfIRValue dbgShowValue = value; - + BfLocalVariable* localDef = new BfLocalVariable(); localDef->mName = "_"; localDef->mResolvedType = fieldInst->mResolvedType; - localDef->mAddr = value; - if ((mBfIRBuilder->DbgHasInfo()) && (!IsTargetingBeefBackend())) + if (fieldInst->IsAppendedObject()) { - // Create another pointer indirection, a ref to the gep - auto refFieldType = CreateRefType(fieldInst->mResolvedType); - - auto allocaInst = CreateAlloca(refFieldType); - - auto storeResult = mBfIRBuilder->CreateStore(value, allocaInst); - - localDef->mResolvedType = refFieldType; - localDef->mAddr = allocaInst; + localDef->mValue = mBfIRBuilder->CreateBitCast(value, mBfIRBuilder->MapType(fieldInst->mResolvedType)); } - + else + { + localDef->mAddr = value; + if ((mBfIRBuilder->DbgHasInfo()) && (!IsTargetingBeefBackend())) + { + // Create another pointer indirection, a ref to the gep + auto refFieldType = CreateRefType(fieldInst->mResolvedType); + + auto allocaInst = CreateAlloca(refFieldType); + + auto storeResult = mBfIRBuilder->CreateStore(value, allocaInst); + + localDef->mResolvedType = refFieldType; + localDef->mAddr = allocaInst; + } + } + mBfIRBuilder->RestoreDebugLocation(); - + auto defLocalVar = AddLocalVariableDef(localDef, true); - // Put back so we actually modify the correct value*/ - defLocalVar->mResolvedType = fieldInst->mResolvedType; - defLocalVar->mAddr = value; - } + + if (!fieldInst->IsAppendedObject()) + { + // Put back so we actually modify the correct value*/ + defLocalVar->mResolvedType = fieldInst->mResolvedType; + defLocalVar->mAddr = value; + } + } while (fieldDtor != NULL) { @@ -16881,13 +17152,79 @@ void BfModule::EmitDtorBody() } } - UpdateSrcPos(fieldDtor); + UpdateSrcPos(fieldDtor); VisitEmbeddedStatement(fieldDtor->mBody); fieldDtor = fieldDtor->mNextFieldDtor; } RestoreScopeState(); } + + if ((fieldDef != NULL) && (fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldInst->IsAppendedObject())) + { + if (fieldDef->mDeclaringType != mCurMethodInstance->mMethodDef->mDeclaringType) + { + BF_ASSERT(mCurTypeInstance->mTypeDef->mIsCombinedPartial); + continue; + } + + auto refNode = fieldDef->GetRefNode(); + UpdateSrcPos(refNode); + + auto objectType = mContext->mBfObjectType; + BfTypeInstance* checkTypeInst = mCurTypeInstance->ToTypeInstance(); + + BfTypedValue val; + if (fieldDef->mIsStatic) + val = ReferenceStaticField(fieldInst); + else + { + auto fieldAddr = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, fieldInst->mDataIdx); + val = BfTypedValue(mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(fieldInst->mResolvedType)), fieldInst->mResolvedType); + } + + bool allowPrivate = checkTypeInst == mCurTypeInstance; + bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst); + while (checkTypeInst != NULL) + { + auto dtorMethodDef = checkTypeInst->mTypeDef->GetMethodByName("~this"); + if (dtorMethodDef) + { + if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate)) + { + auto error = Fail(StrFormat("'%s.~this()' is inaccessible due to its protection level", TypeToString(checkTypeInst).c_str()), refNode); // CS0122 + } + } + checkTypeInst = checkTypeInst->mBaseType; + allowPrivate = false; + } + + // call dtor + BfExprEvaluator expressionEvaluator(this); + PopulateType(val.mType); + PopulateType(objectType, BfPopulateType_DataAndMethods); + + if (objectType->mVirtualMethodTable.size() == 0) + { + if (!mCompiler->IsAutocomplete()) + AssertErrorState(); + } + else if (!IsSkippingExtraResolveChecks()) + { + BfMethodInstance* methodInstance = objectType->mVirtualMethodTable[mCompiler->GetVTableMethodOffset() + 0].mImplementingMethod; + BF_ASSERT(methodInstance->mMethodDef->mName == "~this"); + SizedArray llvmArgs; + llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType))); + expressionEvaluator.CreateCall(refNode, methodInstance, mBfIRBuilder->GetFakeVal(), false, llvmArgs); + } + + if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) + { + auto int8PtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_Int8)); + auto int8PtrVal = mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(int8PtrType)); + mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_Deleted), int8PtrVal); + } + } } if ((!methodDef->mIsStatic) && (mCurMethodInstance->mChainType != BfMethodChainType_ChainMember)) @@ -16905,7 +17242,7 @@ void BfModule::EmitDtorBody() UpdateSrcPos(typeDef->mTypeDeclaration->mNameNode); } - BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this"); + BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this"); if (dtorMethodDef != NULL) { auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); @@ -16933,15 +17270,15 @@ void BfModule::EmitDtorBody() break; } checkBaseType = checkBaseType->mBaseType; - } + } } - EmitLifetimeEnds(&mCurMethodState->mHeadScope); + EmitLifetimeEnds(&mCurMethodState->mHeadScope); } else { - // The reason we can't just do the 'normal' path for this is that the BfTypeInstance here is NOT the - // autocomplete type instance, so FieldInstance initializer values contain expressions from the full + // The reason we can't just do the 'normal' path for this is that the BfTypeInstance here is NOT the + // autocomplete type instance, so FieldInstance initializer values contain expressions from the full // resolve pass, NOT the autocomplete expression for (auto tempTypeDef : mCompiler->mResolvePassData->mAutoCompleteTempTypes) { @@ -16951,7 +17288,7 @@ void BfModule::EmitDtorBody() { auto fieldDecl = fieldDef->GetFieldDeclaration(); - if ((fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && + if ((fieldDef->mIsStatic == methodDef->mIsStatic) && (fieldDef->mFieldDeclaration != NULL) && (fieldDecl->mFieldDtor != NULL) && (mCompiler->mResolvePassData->mIsClassifying)) { BfType* fieldType = NULL; @@ -16961,15 +17298,15 @@ void BfModule::EmitDtorBody() auto curFieldInstance = &mCurTypeInstance->mFieldInstances[curFieldIdx]; auto curFieldDef = curFieldInstance->GetFieldDef(); if ((curFieldDef != NULL) && (fieldDef->mName == curFieldDef->mName)) - fieldType = curFieldInstance->GetResolvedType(); + fieldType = curFieldInstance->GetResolvedType(); } if (fieldType == NULL) fieldType = GetPrimitiveType(BfTypeCode_Var); - + auto fieldDtor = fieldDecl->mFieldDtor; BfScopeData scopeData; - mCurMethodState->AddScope(&scopeData); + mCurMethodState->AddScope(&scopeData); NewScopeState(); // This is just for autocomplete, it doesn't matter that mAddr is incorrect @@ -16977,7 +17314,7 @@ void BfModule::EmitDtorBody() { BfLocalVariable* localDef = new BfLocalVariable(); localDef->mName = "_"; - localDef->mResolvedType = fieldType; + localDef->mResolvedType = fieldType; localDef->mAddr = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(fieldType)); localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; AddLocalVariableDef(localDef); @@ -16991,13 +17328,13 @@ void BfModule::EmitDtorBody() sourceClassifier->VisitChild(fieldDtor); } - UpdateSrcPos(fieldDtor); + UpdateSrcPos(fieldDtor); VisitEmbeddedStatement(fieldDtor->mBody); fieldDtor = fieldDtor->mNextFieldDtor; } RestoreScopeState(); - } + } } } } @@ -17016,7 +17353,7 @@ BfIRValue BfModule::CreateDllImportGlobalVar(BfMethodInstance* methodInstance, b { if (customAttr.mType->mTypeDef->mFullName.ToString() == "System.ImportAttribute") { - foundDllImportAttr = true; + foundDllImportAttr = true; } } if (!foundDllImportAttr) @@ -17028,21 +17365,21 @@ BfIRValue BfModule::CreateDllImportGlobalVar(BfMethodInstance* methodInstance, b StringT<512> name = "bf_hs_preserve@"; BfMangler::Mangle(name, mCompiler->GetMangleKind(), methodInstance); name += "__imp"; - + BfIRType returnType; SizedArray paramTypes; methodInstance->GetIRFunctionInfo(this, returnType, paramTypes); - + BfIRFunctionType externFunctionType = mBfIRBuilder->CreateFunctionType(returnType, paramTypes, methodInstance->IsVarArgs()); auto ptrType = mBfIRBuilder->GetPointerTo(externFunctionType); BfIRValue initVal; if (define) { - if (methodInstance->GetImportCallKind() != BfImportCallKind_None) + if (methodInstance->GetImportCallKind() != BfImportCallKind_None) initVal = mBfIRBuilder->CreateConstNull(ptrType); } - + auto globalVar = mBfIRBuilder->CreateGlobalVariable(ptrType, false, BfIRLinkageType_External, initVal, name); if ((define) && (mBfIRBuilder->DbgHasInfo())) @@ -17067,7 +17404,7 @@ void BfModule::CreateDllImportMethod() bool allowTailCall = true; mBfIRBuilder->ClearDebugLocation(); - + bool isHotCompile = mCompiler->IsHotCompile(); // If we are hot swapping, we need to have this stub because we may need to call the LoadSharedLibraries on demand @@ -17109,7 +17446,7 @@ void BfModule::CreateDllImportMethod() if (HasCompiledOutput()) { BfDllImportEntry dllImportEntry; - dllImportEntry.mFuncVar = globalVar; + dllImportEntry.mFuncVar = globalVar; dllImportEntry.mMethodInstance = mCurMethodInstance; mDllImportEntries.push_back(dllImportEntry); } @@ -17130,7 +17467,7 @@ BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstanc return BfIRCallingConv_StdCall; if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall) return BfIRCallingConv_FastCall; - if (!methodDef->mIsStatic) + if (!methodDef->mIsStatic) { if (owner->mIsCRepr) return BfIRCallingConv_ThisCall; @@ -17144,20 +17481,20 @@ BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstanc } void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined) -{ +{ BfMethodDef* methodDef = NULL; if (methodInstance != NULL) methodDef = methodInstance->mMethodDef; if (!func) return; - + if (mCompiler->mOptions.mNoFramePointerElim) - mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_NoFramePointerElim); + mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_NoFramePointerElim); mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_NoUnwind); - if (mSystem->mPtrSize == 8) // We need unwind info for debugging + if (mSystem->mPtrSize == 8) // We need unwind info for debugging mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_UWTable); - + if (methodInstance == NULL) return; @@ -17173,17 +17510,17 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func auto callingConv = GetIRCallingConvention(methodInstance); if (callingConv != BfIRCallingConv_CDecl) mBfIRBuilder->SetFuncCallingConv(func, callingConv); - + if (isInlined) { - mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_AlwaysInline); + mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_AlwaysInline); } int argIdx = 0; int paramIdx = 0; - if ((methodInstance->HasThis()) && (!methodDef->mHasExplicitThis)) - paramIdx = -1; + if ((methodInstance->HasThis()) && (!methodDef->mHasExplicitThis)) + paramIdx = -1; int argCount = methodInstance->GetIRFunctionParamCount(this); @@ -17205,7 +17542,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func BfType* resolvedTypeRef2 = NULL; String paramName; bool isSplattable = false; - bool tryLowering = !mIsComptimeModule; + bool tryLowering = !mIsComptimeModule; if (isThis) { paramName = "this"; @@ -17238,7 +17575,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func else if (resolvedTypeRef->GetSplatCount() + argIdx <= mCompiler->mOptions.mMaxSplatRegs) isSplattable = true; } - } + } } if (tryLowering) @@ -17246,7 +17583,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; if (resolvedTypeRef->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2)) - { + { mBfIRBuilder->Func_SetParamName(func, argIdx + 1, paramName + "__1"); argIdx++; @@ -17258,7 +17595,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func paramIdx++; continue; - } + } } auto _SetupParam = [&](const StringImpl& paramName, BfType* resolvedTypeRef) @@ -17284,7 +17621,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func addDeref = resolvedTypeRef->mSize; } else if (methodInstance->WantsStructsAttribByVal(resolvedTypeRef)) - { + { mBfIRBuilder->PopulateType(resolvedTypeRef, BfIRPopulateType_Full); BF_ASSERT(resolvedTypeRef->mAlign > 0); mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize); @@ -17304,15 +17641,15 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func }; if (isSplattable) - { + { std::function checkTypeLambda = [&](BfType* checkType, const StringImpl& curName) - { + { if (checkType->IsStruct()) { auto checkTypeInstance = checkType->ToTypeInstance(); if (checkTypeInstance->mBaseType != NULL) checkTypeLambda(checkTypeInstance->mBaseType, curName); - + if (checkTypeInstance->mIsUnion) { BfType* unionInnerType = checkTypeInstance->GetUnionInnerType(); @@ -17351,7 +17688,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func checkTypeLambda(methodRefType->GetCaptureType(dataIdx), curName + "_" + methodRefMethodInst->GetParamName(methodRefParamIdx)); } else - { + { _SetupParam(curName + "_" + methodRefMethodInst->GetParamName(methodRefParamIdx), methodRefType->GetCaptureType(dataIdx)); } } @@ -17370,7 +17707,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func _SetupParam(paramName, resolvedTypeRef); if (resolvedTypeRef2 != NULL) _SetupParam(paramName, resolvedTypeRef2); - + paramIdx++; } } @@ -17435,7 +17772,7 @@ void BfModule::EmitCtorBody(bool& skipBody) // Prologue mBfIRBuilder->ClearDebugLocation(); - bool hadThisInitializer = false; + bool hadThisInitializer = false; if ((ctorDeclaration != NULL) && (ctorInvocation != NULL)) { auto targetToken = BfNodeDynCast(ctorInvocation->mTarget); @@ -17483,16 +17820,16 @@ void BfModule::EmitCtorBody(bool& skipBody) baseCtorNode = mContext->mBfObjectType->mTypeDef->mTypeDeclaration; bool calledCtorNoBody = false; - + if ((mCurTypeInstance->IsTypedPrimitive()) && (!mCurTypeInstance->IsValuelessType())) { // Zero out typed primitives in ctor mBfIRBuilder->CreateAlignedStore(GetDefaultValue(mCurTypeInstance->GetUnderlyingType()), mBfIRBuilder->GetArgument(0), mCurTypeInstance->mAlign); - } + } if ((!mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType == BfMethodType_Ctor) && (!hadThisInitializer)) { - // Call the root type's default ctor (with no body) to initialize its fields and call the chained ctors + // Call the root type's default ctor (with no body) to initialize its fields and call the chained ctors if (mCurTypeInstance->mTypeDef->mHasCtorNoBody) { BfMethodDef* defaultCtor = NULL; @@ -17509,7 +17846,7 @@ void BfModule::EmitCtorBody(bool& skipBody) { UpdateSrcPos(mCurTypeInstance->mTypeDef->GetRefNode()); SetIllegalSrcPos(); - + auto moduleMethodInstance = GetMethodInstance(mCurTypeInstance, defaultCtor, BfTypeVector()); BfExprEvaluator exprEvaluator(this); @@ -17538,9 +17875,9 @@ void BfModule::EmitCtorBody(bool& skipBody) { // If we had a 'this' initializer, that other ctor will have initialized our fields - //auto - - if ((!mCompiler->mIsResolveOnly) || + //auto + + if ((!mCompiler->mIsResolveOnly) || (mCompiler->mResolvePassData->mAutoComplete == NULL) || (mCompiler->mResolvePassData->mAutoComplete->mResolveType == BfResolveType_ShowFileSymbolReferences)) { @@ -17551,7 +17888,7 @@ void BfModule::EmitCtorBody(bool& skipBody) bool hadInlineInitBlock = false; BfScopeData scopeData; scopeData.mInInitBlock = true; - + auto _CheckInitBlock = [&](BfAstNode* node) { if (!hadInlineInitBlock) @@ -17580,7 +17917,7 @@ void BfModule::EmitCtorBody(bool& skipBody) mCurMethodState->mCurScope->mDIInlinedAt = mBfIRBuilder->DbgGetCurrentLocation(); BF_ASSERT(mCurMethodState->mCurScope->mDIInlinedAt); // mCurMethodState->mCurScope->mDIInlinedAt may still be null ifwe don't have an explicit ctor - + String linkageName; if ((mIsComptimeModule) && (mCompiler->mCeMachine->mCurBuilder != NULL)) linkageName = StrFormat("%d", mCompiler->mCeMachine->mCurBuilder->DbgCreateMethodRef(mCurMethodInstance, "$initFields")); @@ -17623,7 +17960,7 @@ void BfModule::EmitCtorBody(bool& skipBody) // For extensions, only handle these fields in the appropriate extension if ((fieldDef->mDeclaringType->mTypeDeclaration != methodDef->mDeclaringType->mTypeDeclaration)) continue; - + if ((!fieldDef->mIsConst) && (!fieldDef->mIsStatic)) { auto fieldInst = &mCurTypeInstance->mFieldInstances[fieldDef->mIdx]; @@ -17633,6 +17970,13 @@ void BfModule::EmitCtorBody(bool& skipBody) continue; auto initializer = fieldDef->GetInitializer(); + if (fieldInst->IsAppendedObject()) + { + UpdateSrcPos(fieldDef->GetNameNode()); + AppendedObjectInit(fieldInst); + continue; + } + if (initializer == NULL) { continue; @@ -17640,7 +17984,7 @@ void BfModule::EmitCtorBody(bool& skipBody) // if (fieldDef->mProtection != BfProtection_Hidden) // continue; // if (mCurTypeInstance->IsObject()) // Already zeroed out -// continue; +// continue; } if (fieldInst->mResolvedType == NULL) @@ -17663,10 +18007,10 @@ void BfModule::EmitCtorBody(bool& skipBody) { // Failed } - auto assignValue = GetFieldInitializerValue(fieldInst); + auto assignValue = GetFieldInitializerValue(fieldInst); if (mCurTypeInstance->IsUnion()) - { + { auto fieldPtrType = CreatePointerType(fieldInst->mResolvedType); fieldAddr = mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(fieldPtrType)); } @@ -17677,7 +18021,7 @@ void BfModule::EmitCtorBody(bool& skipBody) } EmitInitBlocks(_CheckInitBlock); - + if (hadInlineInitBlock) { RestoreScopeState(); @@ -17696,8 +18040,8 @@ void BfModule::EmitCtorBody(bool& skipBody) mCurMethodState->AddScope(&scopeData); NewScopeState(); - // The reason we can't just do the 'normal' path for this is that the BfTypeInstance here is NOT the - // autocomplete type instance, so FieldInstance initializer values contain expressions from the full + // The reason we can't just do the 'normal' path for this is that the BfTypeInstance here is NOT the + // autocomplete type instance, so FieldInstance initializer values contain expressions from the full // resolve pass, NOT the autocomplete expression for (auto tempTypeDef : mCompiler->mResolvePassData->mAutoCompleteTempTypes) { @@ -17705,7 +18049,7 @@ void BfModule::EmitCtorBody(bool& skipBody) { for (auto fieldDef : tempTypeDef->mFields) { - auto initializer = fieldDef->GetInitializer(); + auto initializer = fieldDef->GetInitializer(); if ((!fieldDef->mIsStatic) && (initializer != NULL) && (mCompiler->mResolvePassData->mIsClassifying)) { @@ -17722,7 +18066,12 @@ void BfModule::EmitCtorBody(bool& skipBody) if ((wantType != NULL) && ((wantType->IsVar()) || (wantType->IsLet()) || (wantType->IsRef()))) wantType = NULL; - CreateValueFromExpression(initializer, wantType, BfEvalExprFlags_FieldInitializer); + + BfEvalExprFlags exprFlags = BfEvalExprFlags_FieldInitializer; + if (fieldDef->mIsAppend) + exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_AppendFieldInitializer); + + CreateValueFromExpression(initializer, wantType, exprFlags); } } @@ -17737,10 +18086,10 @@ void BfModule::EmitCtorBody(bool& skipBody) { if (initMethodDef->mMethodType != BfMethodType_Init) continue; - initBodies.Insert(0, initMethodDef->mBody); + initBodies.Insert(0, initMethodDef->mBody); } - for (auto body : initBodies) - VisitEmbeddedStatement(body); + for (auto body : initBodies) + VisitEmbeddedStatement(body); } } @@ -17756,7 +18105,7 @@ void BfModule::EmitCtorBody(bool& skipBody) } RestoreScopeState(); - } + } } if (!methodInstance->mIsAutocompleteMethod) @@ -17778,11 +18127,13 @@ void BfModule::EmitCtorBody(bool& skipBody) BF_ASSERT(localVar->mName == paramDef->mName); auto localVal = exprEvaluator.LoadLocal(localVar); localVal = LoadOrAggregateValue(localVal); - - if (!localVal.mType->IsVar()) + + if (!localVal.mType->IsVar()) { auto thisVal = GetThis(); auto fieldPtr = mBfIRBuilder->CreateInBoundsGEP(thisVal.mValue, 0, fieldInstance.mDataIdx); + if (mCurTypeInstance->IsUnion()) + fieldPtr = mBfIRBuilder->CreateBitCast(fieldPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(fieldInstance.mResolvedType))); mBfIRBuilder->CreateAlignedStore(localVal.mValue, fieldPtr, localVar->mResolvedType->mAlign); } MarkFieldInitialized(&fieldInstance); @@ -17791,7 +18142,7 @@ void BfModule::EmitCtorBody(bool& skipBody) } // Call base ctor (if applicable) - BfTypeInstance* targetType = NULL; + BfTypeInstance* targetType = NULL; BfAstNode* targetRefNode = NULL; if (ctorDeclaration != NULL) targetRefNode = ctorDeclaration->mInitializer; @@ -17800,7 +18151,7 @@ void BfModule::EmitCtorBody(bool& skipBody) if (baseCtorNode != NULL) { - UpdateSrcPos(baseCtorNode); + UpdateSrcPos(baseCtorNode); if (methodDef->mBody == NULL) SetIllegalSrcPos(); } @@ -17821,7 +18172,7 @@ void BfModule::EmitCtorBody(bool& skipBody) bool hadCtorWithAllDefaults = false; bool isHiddenGenerated = (methodDeclaration == NULL) && (methodDef->mProtection == BfProtection_Hidden); - + for (int pass = 0; pass < 2; pass++) { baseType->mTypeDef->PopulateMemberSets(); @@ -17830,7 +18181,7 @@ void BfModule::EmitCtorBody(bool& skipBody) baseType->mTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry); if (entry != NULL) checkMethodDef = (BfMethodDef*)entry->mMemberDef; - + while (checkMethodDef != NULL) { bool allowMethod = checkMethodDef->mProtection > BfProtection_Private; @@ -17841,11 +18192,11 @@ void BfModule::EmitCtorBody(bool& skipBody) if ((checkMethodDef->mMethodDeclaration == NULL) && (pass == 1) && (!hadCtorWithAllDefaults)) allowMethod = true; } - + if ((checkMethodDef->mMethodType == BfMethodType_Ctor) && (!checkMethodDef->mIsStatic) && (allowMethod)) { if (checkMethodDef->mParams.size() == 0) - { + { if (matchedMethod != NULL) { // Has multiple matched methods - can happen from extensions @@ -17881,7 +18232,7 @@ void BfModule::EmitCtorBody(bool& skipBody) auto callInst = mBfIRBuilder->CreateCall(ctorBodyMethodInstance.mFunc, args); auto callingConv = GetIRCallingConvention(ctorBodyMethodInstance.mMethodInstance); if (callingConv != BfIRCallingConv_CDecl) - mBfIRBuilder->SetCallCallingConv(callInst, callingConv); + mBfIRBuilder->SetCallCallingConv(callInst, callingConv); if (mIsComptimeModule) mCompiler->mCeMachine->QueueMethod(ctorBodyMethodInstance); } @@ -17895,7 +18246,7 @@ void BfModule::EmitCtorBody(bool& skipBody) targetRefNode = typeDef->mTypeDeclaration->mNameNode; } } - } + } if (methodDef->mHasAppend) { @@ -17917,9 +18268,10 @@ void BfModule::EmitCtorBody(bool& skipBody) } targetType = NULL; - } + } } + auto autoComplete = mCompiler->GetAutoComplete(); if (targetType != NULL) { BfAstNode* refNode = methodDeclaration; @@ -17928,7 +18280,6 @@ void BfModule::EmitCtorBody(bool& skipBody) BfAutoParentNodeEntry autoParentNodeEntry(this, refNode); - auto autoComplete = mCompiler->GetAutoComplete(); auto wasCapturingMethodInfo = (autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo); if ((autoComplete != NULL) && (ctorDeclaration != NULL) && (ctorInvocation != NULL)) { @@ -17941,7 +18292,7 @@ void BfModule::EmitCtorBody(bool& skipBody) BfExprEvaluator exprEvaluator(this); BfResolvedArgs argValues; if ((ctorDeclaration != NULL) && (ctorInvocation != NULL)) - { + { argValues.Init(&ctorInvocation->mArguments); if (gDebugStuff) { @@ -17952,7 +18303,7 @@ void BfModule::EmitCtorBody(bool& skipBody) BfTypedValue appendIdxVal; if (methodDef->mHasAppend) - { + { auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1]; BF_ASSERT(localVar->mName == "appendIdx"); auto intRefType = localVar->mResolvedType; @@ -17968,16 +18319,101 @@ void BfModule::EmitCtorBody(bool& skipBody) if (autoComplete->mMethodMatchInfo != NULL) autoComplete->mIsCapturingMethodMatchInfo = true; else - autoComplete->mIsCapturingMethodMatchInfo = false; + autoComplete->mIsCapturingMethodMatchInfo = false; } else autoComplete->mIsCapturingMethodMatchInfo = false; } } + + auto autoCtorDecl = BfNodeDynCast(methodDeclaration); + if ((autoComplete != NULL) && (autoComplete->CheckFixit(methodDeclaration)) && (methodDeclaration != NULL) && (autoCtorDecl != NULL)) + { + auto typeDecl = methodDef->mDeclaringType->mTypeDeclaration; + BfParserData* parser = typeDecl->GetSourceData()->ToParserData(); + if (parser != NULL) + { + String fixitStr = "Expand auto constructor\t"; + int insertPos = typeDecl->mSrcStart; + + bool needsBlock = false; + + if (auto defBlock = BfNodeDynCast(typeDecl->mDefineNode)) + { + insertPos = defBlock->mOpenBrace->mSrcStart + 1; + } + else if (auto tokenNode = BfNodeDynCast(typeDecl->mDefineNode)) + { + insertPos = tokenNode->mSrcStart; + fixitStr += StrFormat("delete|%s-%d|\x01", + autoComplete->FixitGetLocation(parser, tokenNode->mSrcStart).c_str(), tokenNode->mSrcEnd - tokenNode->mSrcStart); + needsBlock = true; + } + + int srcStart = methodDeclaration->mSrcStart; + if ((autoCtorDecl->mPrefix == NULL) && (typeDecl->mColonToken != NULL)) + srcStart = typeDecl->mColonToken->mSrcStart; + + while ((srcStart > 0) && (::isspace((uint8)parser->mSrc[srcStart - 1]))) + srcStart--; + + fixitStr += StrFormat("expand|%s|%d|", + parser->mFileName.c_str(), insertPos); + + if (needsBlock) + fixitStr += "\t"; + else + fixitStr += "\f"; + + for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++) + { + String paramStr = autoCtorDecl->mParams[paramIdx]->ToString(); + paramStr.Replace('\n', '\r'); + + fixitStr += "public "; + fixitStr += paramStr; + fixitStr += ";\r"; + } + + fixitStr += "\rpublic this("; + for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++) + { + if (paramIdx > 0) + fixitStr += ", "; + String paramStr = autoCtorDecl->mParams[paramIdx]->ToString(); + paramStr.Replace('\n', '\r'); + fixitStr += paramStr; + } + fixitStr += ")\t"; + for (int paramIdx = 0; paramIdx < autoCtorDecl->mParams.mSize; paramIdx++) + { + if (paramIdx > 0) + fixitStr += "\r"; + auto nameNode = autoCtorDecl->mParams[paramIdx]->mNameNode; + if (nameNode == NULL) + continue; + String nameStr = nameNode->ToString(); + fixitStr += "this."; + fixitStr += nameStr; + fixitStr += " = "; + fixitStr += nameStr; + fixitStr += ";"; + } + fixitStr += "\b"; + + if (needsBlock) + fixitStr += "\b"; + + fixitStr += StrFormat("\x01""delete|%s-%d|", + autoComplete->FixitGetLocation(parser, srcStart).c_str(), autoCtorDecl->mSrcEnd - srcStart); + + mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("fixit", fixitStr.c_str())); + } + } } void BfModule::EmitEnumToStringBody() -{ +{ auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef); auto strVal = CreateAlloca(stringType); @@ -17985,7 +18421,7 @@ void BfModule::EmitEnumToStringBody() BfExprEvaluator exprEvaluator(this); auto stringDestAddr = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); - + BfIRBlock appendBlock = mBfIRBuilder->CreateBlock("append"); BfIRBlock noMatchBlock = mBfIRBuilder->CreateBlock("noMatch"); BfIRBlock endBlock = mBfIRBuilder->CreateBlock("end"); @@ -17996,7 +18432,7 @@ void BfModule::EmitEnumToStringBody() BfIRValue enumVal; if (mCurTypeInstance->IsPayloadEnum()) { - discriminatorType = mCurTypeInstance->GetDiscriminatorType(); + discriminatorType = mCurTypeInstance->GetDiscriminatorType(); auto enumTypedValue = ExtractValue(GetThis(), NULL, 2); enumTypedValue = LoadValue(enumTypedValue); enumVal = enumTypedValue.mValue; @@ -18032,20 +18468,20 @@ void BfModule::EmitEnumToStringBody() args.Add(stringDestVal.mValue); args.Add(caseStr); exprEvaluator.CreateCall(NULL, appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args); - + auto payloadType = fieldInstance.mResolvedType->ToTypeInstance(); BF_ASSERT(payloadType->IsTuple()); - - if (payloadType->mFieldInstances.size() != 0) + + if (payloadType->mFieldInstances.size() != 0) { auto payload = rawPayload; if (payload.mType != payloadType) - { + { payload = Cast(NULL, payload, payloadType, BfCastFlags_Force); } auto toStringMethod = GetMethodByName(payloadType->ToTypeInstance(), "ToString"); - + SizedArray irArgs; exprEvaluator.PushThis(NULL, payload, toStringMethod.mMethodInstance, irArgs); stringDestVal = LoadValue(stringDestAddr); @@ -18076,18 +18512,18 @@ void BfModule::EmitEnumToStringBody() BfIRBlock caseBlock = mBfIRBuilder->CreateBlock("case"); mBfIRBuilder->AddBlock(caseBlock); mBfIRBuilder->SetInsertPoint(caseBlock); - + BfIRValue constVal = ConstantToCurrent(constant, mCurTypeInstance->mConstHolder, mCurTypeInstance); mBfIRBuilder->AddSwitchCase(switchVal, constVal, caseBlock); - auto caseStr = GetStringObjectValue(fieldInstance.GetFieldDef()->mName); + auto caseStr = GetStringObjectValue(fieldInstance.GetFieldDef()->mName); mBfIRBuilder->CreateStore(caseStr, strVal); - mBfIRBuilder->CreateBr(appendBlock); + mBfIRBuilder->CreateBr(appendBlock); } mBfIRBuilder->AddBlock(appendBlock); mBfIRBuilder->SetInsertPoint(appendBlock); - + SizedArray args; auto stringDestVal = LoadValue(stringDestAddr); args.Add(stringDestVal.mValue); @@ -18114,7 +18550,7 @@ void BfModule::EmitTupleToStringBody() { auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef); - BfExprEvaluator exprEvaluator(this); + BfExprEvaluator exprEvaluator(this); auto stringDestRef = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); @@ -18138,7 +18574,7 @@ void BfModule::EmitTupleToStringBody() int fieldIdx = 0; auto thisValue = GetThis(); - + auto toStringModuleMethodInstance = GetMethodByName(mContext->mBfObjectType, "ToString", 1); auto toStringSafeModuleMethodInstance = GetMethodByName(mContext->mBfObjectType, "ToString", 2); BfIRValue commaStr; @@ -18155,7 +18591,7 @@ void BfModule::EmitTupleToStringBody() if (fieldIdx > 0) { if (!commaStr) - commaStr = GetStringObjectValue(", "); + commaStr = GetStringObjectValue(", "); SizedArray args; auto stringDestVal = LoadValue(stringDestRef); args.Add(stringDestVal.mValue); @@ -18164,8 +18600,8 @@ void BfModule::EmitTupleToStringBody() } fieldIdx++; - if (fieldInstance.mResolvedType->IsValuelessType()) - continue; + if (fieldInstance.mResolvedType->IsValuelessType()) + continue; BfTypedValue fieldValue = ExtractValue(thisValue, &fieldInstance, fieldInstance.mDataIdx); @@ -18178,7 +18614,7 @@ void BfModule::EmitTupleToStringBody() if ((typeInstance != NULL) && (TypeIsSubTypeOf(typeInstance, iPrintableType, false))) { - BfExprEvaluator exprEvaluator(this); + BfExprEvaluator exprEvaluator(this); SizedArray resolvedArgs; BfMethodMatcher methodMatcher(NULL, this, printModuleMethodInstance.mMethodInstance, resolvedArgs, BfMethodGenericArguments()); methodMatcher.mBestMethodDef = printModuleMethodInstance.mMethodInstance->mMethodDef; @@ -18200,21 +18636,21 @@ void BfModule::EmitTupleToStringBody() if (fieldValue.mType->IsObjectOrInterface()) { fieldValue = LoadValue(fieldValue); - BF_ASSERT(!fieldValue.IsAddr()); + BF_ASSERT(!fieldValue.IsAddr()); SizedArray args; args.Add(mBfIRBuilder->CreateBitCast(fieldValue.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType))); auto stringDestVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]); stringDestVal = LoadValue(stringDestVal); - args.Add(stringDestVal.mValue); + args.Add(stringDestVal.mValue); exprEvaluator.CreateCall(NULL, toStringSafeModuleMethodInstance.mMethodInstance, toStringSafeModuleMethodInstance.mFunc, false, args); continue; } - BfExprEvaluator exprEvaluator(this); - SizedArray resolvedArgs; + BfExprEvaluator exprEvaluator(this); + SizedArray resolvedArgs; BfMethodMatcher methodMatcher(NULL, this, toStringModuleMethodInstance.mMethodInstance, resolvedArgs, BfMethodGenericArguments()); methodMatcher.mBestMethodDef = toStringModuleMethodInstance.mMethodInstance->mMethodDef; - methodMatcher.mBestMethodTypeInstance = mContext->mBfObjectType; + methodMatcher.mBestMethodTypeInstance = mContext->mBfObjectType; methodMatcher.TryDevirtualizeCall(fieldValue); if (methodMatcher.mBestMethodTypeInstance == mContext->mBfObjectType) @@ -18235,13 +18671,13 @@ void BfModule::EmitTupleToStringBody() } BfTypedValue callVal = Cast(NULL, fieldValue, methodMatcher.mBestMethodTypeInstance); - + BfResolvedArg resolvedArg; auto stringDestVal = LoadValue(stringDestRef); resolvedArg.mTypedValue = stringDestVal; resolvedArg.mResolvedType = stringDestVal.mType; resolvedArgs.Add(resolvedArg); - + exprEvaluator.CreateCall(&methodMatcher, callVal); } _AppendChar(')'); @@ -18253,18 +18689,18 @@ void BfModule::EmitIteratorBlock(bool& skipBody) auto methodDef = methodInstance->mMethodDef; auto methodDeclaration = methodDef->GetMethodDeclaration(); auto typeDef = mCurTypeInstance->mTypeDef; - + BfType* innerRetType = NULL; BfTypeInstance* usingInterface = NULL; - auto retTypeInst = mCurMethodInstance->mReturnType->ToGenericTypeInstance(); + auto retTypeInst = mCurMethodInstance->mReturnType->ToGenericTypeInstance(); if (retTypeInst != NULL) { - if ((retTypeInst->IsInstanceOf(mCompiler->mGenericIEnumerableTypeDef)) || + if ((retTypeInst->IsInstanceOf(mCompiler->mGenericIEnumerableTypeDef)) || (retTypeInst->IsInstanceOf(mCompiler->mGenericIEnumeratorTypeDef))) - { + { innerRetType = retTypeInst->mGenericTypeInfo->mTypeGenericArguments[0]; - } + } } if (innerRetType == NULL) @@ -18275,7 +18711,22 @@ void BfModule::EmitIteratorBlock(bool& skipBody) auto blockBody = BfNodeDynCast(methodDeclaration->mBody); if (blockBody == NULL) - return; + return; +} + +void BfModule::EmitGCMarkAppended(BfTypedValue markVal) +{ + auto gcType = ResolveTypeDef(mCompiler->mGCTypeDef, BfPopulateType_DataAndMethods); + if (gcType == NULL) + return; + BfModuleMethodInstance markFromGCThreadMethodInstance = GetMethodByName(gcType->ToTypeInstance(), "MarkAppendedObject", 1); + if (!markFromGCThreadMethodInstance) + return; + + SizedArray args; + args.push_back(mBfIRBuilder->CreateBitCast(markVal.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType))); + BfExprEvaluator exprEvaluator(this); + exprEvaluator.CreateCall(NULL, markFromGCThreadMethodInstance.mMethodInstance, markFromGCThreadMethodInstance.mFunc, false, args); } void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance markFromGCThreadMethodInstance) @@ -18297,13 +18748,13 @@ void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance mark SizedArray args; args.push_back(val); exprEvaluator.CreateCall(NULL, markFromGCThreadMethodInstance.mMethodInstance, markFromGCThreadMethodInstance.mFunc, false, args); - } + } else if (fieldType->IsSizedArray()) { BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)fieldType; if (sizedArrayType->mElementType->WantsGCMarking()) { - BfTypedValue arrayValue = markVal; + BfTypedValue arrayValue = markVal; auto intPtrType = GetPrimitiveType(BfTypeCode_IntPtr); auto itr = CreateAlloca(intPtrType); mBfIRBuilder->CreateStore(GetDefaultValue(intPtrType), itr); @@ -18331,16 +18782,16 @@ void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance mark mBfIRBuilder->CreateStore(incValue, itr); mBfIRBuilder->CreateBr(loopBB); - mBfIRBuilder->SetInsertPoint(doneBB); + mBfIRBuilder->SetInsertPoint(doneBB); } } else if ((fieldType->IsComposite()) && (!fieldType->IsTypedPrimitive()) && (fieldTypeInst != NULL)) - { + { auto markMemberMethodInstance = GetMethodByName(fieldTypeInst, BF_METHODNAME_MARKMEMBERS, 0, true); if (markMemberMethodInstance) { SizedArray args; - + auto methodOwner = markMemberMethodInstance.mMethodInstance->GetOwner(); if (markVal.mType != methodOwner) markVal = Cast(NULL, markVal, methodOwner); @@ -18352,11 +18803,11 @@ void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance mark } void BfModule::CallChainedMethods(BfMethodInstance* methodInstance, bool reverse) -{ +{ Array methodInstances; for (int methodIdx = 0; methodIdx < (int)mCurTypeInstance->mMethodInstanceGroups.size(); methodIdx++) - { + { auto& methodInstGroup = mCurTypeInstance->mMethodInstanceGroups[methodIdx]; auto chainedMethodInst = methodInstGroup.mDefault; if ((chainedMethodInst != NULL) && (chainedMethodInst->mChainType == BfMethodChainType_ChainMember)) @@ -18364,17 +18815,17 @@ void BfModule::CallChainedMethods(BfMethodInstance* methodInstance, bool reverse if ((chainedMethodInst->mMethodDef->mIsStatic == methodInstance->mMethodDef->mIsStatic) && (CompareMethodSignatures(methodInstance, chainedMethodInst))) { - methodInstances.push_back(chainedMethodInst); + methodInstances.push_back(chainedMethodInst); } } } - + std::stable_sort(methodInstances.begin(), methodInstances.end(), [&](BfMethodInstance* lhs, BfMethodInstance* rhs) { bool isBetter; bool isWorse; - CompareDeclTypes(lhs->mMethodDef->mDeclaringType, rhs->mMethodDef->mDeclaringType, isBetter, isWorse); + CompareDeclTypes(mCurTypeInstance, lhs->mMethodDef->mDeclaringType, rhs->mMethodDef->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { return false; @@ -18400,7 +18851,7 @@ void BfModule::CallChainedMethods(BfMethodInstance* methodInstance, bool reverse } void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder) -{ +{ BF_ASSERT(mCurMethodInstance->mIsReified); if (mCurTypeInstance->mHotTypeData == NULL) @@ -18409,7 +18860,7 @@ void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder) BfLogSysM("Created HotTypeData %p created for type %p in AddHotDataReferences\n", mCurTypeInstance->mHotTypeData, mCurTypeInstance); } - auto hotMethod = mCurMethodInstance->mHotMethod; + auto hotMethod = mCurMethodInstance->mHotMethod; for (auto depData : hotMethod->mReferences) { // Only virtual decls are allowed to already be there @@ -18417,7 +18868,7 @@ void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder) } BF_ASSERT(hotMethod->mSrcTypeVersion != NULL); - + int prevSize = (int)hotMethod->mReferences.size(); int refCount = (int)(prevSize + builder->mUsedData.size() + builder->mCalledMethods.size() + builder->mDevirtualizedCalledMethods.size()); if (!mCurMethodInstance->mMethodDef->mIsStatic) @@ -18425,16 +18876,16 @@ void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder) hotMethod->mReferences.Reserve(refCount); if (!mCurMethodInstance->mMethodDef->mIsStatic) - { + { auto hotThis = mCompiler->mHotData->GetThisType(mCurMethodInstance->GetOwner()->mHotTypeData->GetLatestVersion()); hotThis->mRefCount++; hotMethod->mReferences.Insert(0, hotThis); prevSize++; } for (auto val : builder->mAllocatedData) - { + { auto hotAllocation = mCompiler->mHotData->GetAllocation(val); - hotMethod->mReferences.Add(hotAllocation); + hotMethod->mReferences.Add(hotAllocation); } for (auto val : builder->mUsedData) hotMethod->mReferences.Add(val); @@ -18461,7 +18912,7 @@ void BfModule::AddHotDataReferences(BfHotDataReferenceBuilder* builder) auto depData = hotMethod->mReferences[refIdx]; BF_ASSERT(depData != NULL); depData->mRefCount++; - } + } } void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfType* thisType, bool wantsDIData, SizedArrayImpl* diParams) @@ -18472,9 +18923,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp bool isThisStruct = false; if (thisType != NULL) isThisStruct = thisType->IsStruct() && !thisType->IsTypedPrimitive(); - + int argIdx = 0; - + if ((!mIsComptimeModule) && (argIdx == methodInstance->GetStructRetIdx())) argIdx++; @@ -18493,7 +18944,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp paramVar->mValue = mBfIRBuilder->GetArgument(argIdx); else paramVar->mValue = mBfIRBuilder->GetFakeVal(); - + if ((!mIsComptimeModule) && (thisType->IsSplattable()) && (methodInstance->AllowsSplatting(-1))) { if (!thisType->IsTypedPrimitive()) @@ -18531,7 +18982,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp diType = mBfIRBuilder->DbgCreateArtificialType(diType); else if (!paramVar->mIsSplat) diType = mBfIRBuilder->DbgCreatePointerType(diType); - + diParams->push_back(diType); } @@ -18540,12 +18991,12 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp BfTypeUtils::SplatIterate([&](BfType* checkType) { argIdx++; }, paramVar->mResolvedType); } else - { + { argIdx++; if (loweredTypeCode2 != BfTypeCode_None) argIdx++; } - } + } } if ((!mIsComptimeModule) && (argIdx == methodInstance->GetStructRetIdx())) @@ -18557,7 +19008,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp int compositeVariableIdx = -1; int paramIdx = 0; for (paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++) - { + { // We already issues a type error for this param if we had one in declaration processing SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); BfLocalVariable* paramVar = rootMethodState->mBumpAlloc.Alloc(); @@ -18567,7 +19018,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp BfTypeCode loweredTypeCode2 = BfTypeCode_None; bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx); - + auto resolvedType = methodInstance->GetParamType(paramIdx); if (resolvedType == NULL) { @@ -18724,6 +19175,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp DoAddLocalVariable(localVar); } mCurMethodState->mLocals[compositeVariableIdx]->mCompositeCount++; + paramVar->mIsImplicitParam = true; } if (!mCurTypeInstance->IsDelegateOrFunction()) @@ -18761,14 +19213,14 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp // Had error or 'var' } else if (paramsType->IsGenericParam()) - { + { auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)paramsType); if (genericParamInstance->mTypeConstraint != NULL) { auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance(); - if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || - ((typeInstConstraint != NULL) && + if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || + ((typeInstConstraint != NULL) && ((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef))))) { BfLocalVariable* localVar = new BfLocalVariable(); @@ -18820,12 +19272,12 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx) mCurMethodState->mLocals.Clear(); mCurMethodState->mLocalVarSet.Clear(); }; - + while (true) { bool didWork = false; // Don't process local methods if we had a build error - this isn't just an optimization, it keeps us from showing the same error twice since - // we show errors in the capture phase. If we somehow pass the capture phase without error then this method WILL show any errors here, + // we show errors in the capture phase. If we somehow pass the capture phase without error then this method WILL show any errors here, // however (compiler bug), so this is the safest way if (!mCurMethodState->mDeferredLocalMethods.IsEmpty()) { @@ -18942,7 +19394,7 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx) } mContext->CheckLockYield(); - mCurMethodState->mDeferredLambdaInstances.Clear(); + mCurMethodState->mDeferredLambdaInstances.Clear(); } if (!didWork) @@ -18950,16 +19402,16 @@ void BfModule::ProcessMethod_ProcessDeferredLocals(int startIdx) } } -void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int memberDepth, int curOffset, HashSet& objectOffsets, BfModuleMethodInstance markFromGCThreadMethodInstance) +void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int memberDepth, int curOffset, HashSet& objectOffsets, BfModuleMethodInstance markFromGCThreadMethodInstance, bool isAppendObject) { if (checkType->IsComposite()) PopulateType(checkType, BfPopulateType_Data); - + if (!checkType->WantsGCMarking()) return; auto typeInstance = checkType->ToTypeInstance(); - bool callMarkMethod = false; + bool callMarkMethod = false; // Call the actual marking method if (memberDepth == 0) @@ -18978,7 +19430,7 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m { BfSizedArrayType* sizedArrayType = (BfSizedArrayType*)checkType; if (sizedArrayType->mElementType->WantsGCMarking()) - { + { BfTypedValue arrayValue = thisValue; if (thisValue.mType != checkType) { @@ -19016,18 +19468,18 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m mBfIRBuilder->CreateCondBr(cmpRes, doneBB, bodyBB); mBfIRBuilder->SetInsertPoint(bodyBB); - + auto ptrType = CreatePointerType(sizedArrayType->mElementType); auto ptrValue = mBfIRBuilder->CreateBitCast(arrayValue.mValue, mBfIRBuilder->MapType(ptrType)); auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, loadedItr); auto value = BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr); EmitGCMarkValue(value, markFromGCThreadMethodInstance); - + auto incValue = mBfIRBuilder->CreateAdd(loadedItr, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1)); mBfIRBuilder->CreateStore(incValue, itr); mBfIRBuilder->CreateBr(loopBB); - + mBfIRBuilder->SetInsertPoint(doneBB); } else @@ -19038,13 +19490,13 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m auto ptrValue = mBfIRBuilder->CreateBitCast(arrayValue.mValue, mBfIRBuilder->MapType(ptrType)); auto gepResult = mBfIRBuilder->CreateInBoundsGEP(ptrValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataIdx)); auto value = BfTypedValue(gepResult, sizedArrayType->mElementType, BfTypedValueKind_Addr); - - HashSet objectOffsets; + + HashSet objectOffsets; EmitGCMarkValue(value, markFromGCThreadMethodInstance); } } } - } + } else if (typeInstance != NULL) { typeInstance->mTypeDef->PopulateMemberSets(); @@ -19086,11 +19538,14 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m markValue = BfTypedValue(mBfIRBuilder->CreateBitCast(offsetValue, mBfIRBuilder->MapType(memberPtrType)), memberType, true); } - EmitGCMarkValue(markValue, markFromGCThreadMethodInstance); + if (isAppendObject) + EmitGCMarkAppended(markValue); + else + EmitGCMarkValue(markValue, markFromGCThreadMethodInstance); return; } - auto methodDef = mCurMethodInstance->mMethodDef; + auto methodDef = mCurMethodInstance->mMethodDef; if (checkType->IsPayloadEnum()) { @@ -19098,14 +19553,14 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m { if (!fieldInst.mIsEnumPayloadCase) continue; - auto fieldDef = fieldInst.GetFieldDef(); + auto fieldDef = fieldInst.GetFieldDef(); EmitGCMarkValue(thisValue, fieldInst.mResolvedType, memberDepth + 1, curOffset, objectOffsets, markFromGCThreadMethodInstance); } return; } if (typeInstance == NULL) - return; + return; for (auto& fieldInst : typeInstance->mFieldInstances) { @@ -19113,7 +19568,7 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m if (fieldDef == NULL) continue; if (fieldDef->mIsStatic) - continue; + continue; if (typeInstance == mCurTypeInstance) { // Note: we don't do method chaining when we are marking members of members. Theoretically this means @@ -19121,9 +19576,10 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m if ((fieldDef->mDeclaringType->mTypeDeclaration != methodDef->mDeclaringType->mTypeDeclaration)) continue; } - EmitGCMarkValue(thisValue, fieldInst.mResolvedType, memberDepth + 1, curOffset + fieldInst.mDataOffset, objectOffsets, markFromGCThreadMethodInstance); + + EmitGCMarkValue(thisValue, fieldInst.mResolvedType, memberDepth + 1, curOffset + fieldInst.mDataOffset, objectOffsets, markFromGCThreadMethodInstance, fieldInst.IsAppendedObject()); } - + if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType != mContext->mBfObjectType)) { EmitGCMarkValue(thisValue, typeInstance->mBaseType, memberDepth, curOffset, objectOffsets, markFromGCThreadMethodInstance); @@ -19207,7 +19663,7 @@ void BfModule::EmitGCMarkMembers() auto thisValue = GetThis(); auto baseValue = Cast(NULL, thisValue, methodBaseType, BfCastFlags_Explicit); - SizedArray args; + SizedArray args; if ((!mIsComptimeModule) && (moduleMethodInst.mMethodInstance->GetParamIsSplat(-1))) { BfExprEvaluator exprEvaluator(this); @@ -19250,7 +19706,7 @@ void BfModule::EmitGCMarkMembers() if (!fieldInst.mFieldIncluded) continue; - auto fieldType = fieldInst.mResolvedType; + auto fieldType = fieldInst.mResolvedType; auto fieldDef = fieldInst.GetFieldDef(); BfTypedValue markVal; @@ -19275,11 +19731,25 @@ void BfModule::EmitGCMarkMembers() } else if (!fieldDef->mIsStatic) { - markVal = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst.mDataIdx/*, fieldDef->mName*/), fieldInst.mResolvedType, true); + if (fieldInst.IsAppendedObject()) + { + auto fieldAddr = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, fieldInst.mDataIdx); + auto val = mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(mContext->mBfObjectType)); + markVal = BfTypedValue(mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(fieldInst.mResolvedType)), fieldInst.mResolvedType); + } + else + { + markVal = BfTypedValue(mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst.mDataIdx/*, fieldDef->mName*/), fieldInst.mResolvedType, true); + } } if (markVal) - EmitGCMarkValue(markVal, markFromGCThreadMethodInstance); + { + if (fieldInst.IsAppendedObject()) + EmitGCMarkAppended(markVal); + else + EmitGCMarkValue(markVal, markFromGCThreadMethodInstance); + } } } } @@ -19300,19 +19770,19 @@ void BfModule::EmitGCFindTLSMembers() BF_ASSERT(reportTLSMark); for (auto& fieldInst : mCurTypeInstance->mFieldInstances) - { + { auto fieldDef = fieldInst.GetFieldDef(); if (fieldDef == NULL) continue; if (!fieldInst.mIsThreadLocal) continue; - + // For extensions, only handle these fields in the appropriate extension if ((fieldDef->mDeclaringType->mTypeDeclaration != methodDef->mDeclaringType->mTypeDeclaration)) continue; if (!fieldInst.mFieldIncluded) continue; - + if (fieldDef->mIsConst) continue; @@ -19323,18 +19793,18 @@ void BfModule::EmitGCFindTLSMembers() if (fieldType->IsValuelessType()) continue; - + BfTypedValue markVal = ReferenceStaticField(&fieldInst); if (markVal) { BfIRValue fieldRefPtr = mBfIRBuilder->CreateBitCast(markVal.mValue, mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_NullPtr))); BfIRValue markFuncPtr = GetMarkFuncPtr(fieldType); - + SizedArray llvmArgs; llvmArgs.push_back(fieldRefPtr); - llvmArgs.push_back(markFuncPtr); - mBfIRBuilder->CreateCall(reportTLSMark.mFunc, llvmArgs); - } + llvmArgs.push_back(markFuncPtr); + mBfIRBuilder->CreateCall(reportTLSMark.mFunc, llvmArgs); + } } if (mCurMethodInstance->mChainType == BfMethodChainType_ChainHead) @@ -19355,7 +19825,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (!methodInstance->mIsReified) BF_ASSERT(!mIsReified); - + BF_ASSERT((!methodInstance->GetOwner()->IsUnspecializedTypeVariation()) || (mIsComptimeModule)); if (methodInstance->mMethodInfoEx != NULL) @@ -19371,14 +19841,14 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, (mWantsIRIgnoreWrites || methodInstance->mIsUnspecialized) && (!forceIRWrites)); - + if ((HasCompiledOutput()) && (!mBfIRBuilder->mIgnoreWrites)) { BF_ASSERT(!methodInstance->mIRFunction.IsFake() || (methodInstance->GetImportCallKind() != BfImportCallKind_None)); } SetAndRestoreValue prevIsClassifying; - if (((methodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend) || (methodInstance->mIsForeignMethodDef) || (methodInstance->IsSpecializedGenericMethod())) && + if (((methodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend) || (methodInstance->mIsForeignMethodDef) || (methodInstance->IsSpecializedGenericMethod())) && (mCompiler->mResolvePassData != NULL)) { // Don't classify on the CtorCalcAppend, just on the actual Ctor @@ -19406,7 +19876,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } BfMethodInstance* defaultMethodInstance = methodInstance->mMethodInstanceGroup->mDefault; - + if (!mIsComptimeModule) { BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_NotSet); @@ -19434,8 +19904,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // We set mHasBeenProcessed to true immediately -- this helps avoid stack overflow during recursion for things like // self-referencing append allocations in ctor@calcAppend - methodInstance->mHasBeenProcessed = true; - mIncompleteMethodCount--; + methodInstance->mHasBeenProcessed = true; + mIncompleteMethodCount--; BF_ASSERT((mIsSpecialModule) || (mIncompleteMethodCount >= 0)); auto typeDef = methodInstance->mMethodInstanceGroup->mOwner->mTypeDef; @@ -19443,7 +19913,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, auto methodDeclaration = methodDef->GetMethodDeclaration(); if ((methodDef->mHasComptime) && (!mIsComptimeModule)) - mBfIRBuilder->mIgnoreWrites = true; + mBfIRBuilder->mIgnoreWrites = true; if ((methodInstance->mIsReified) && (methodInstance->mVirtualTableIdx != -1)) { @@ -19456,9 +19926,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if ((methodDef->mIsLocalMethod) && (mCurMethodState != NULL)) // See DoMethodDeclaration for an explaination of dependentGenericStartIdx dependentGenericStartIdx = (int)mCurMethodState->GetRootMethodState()->mMethodInstance->GetNumGenericArguments(); - SetAndRestoreValue prevMethodInstance(mCurMethodInstance, methodInstance); + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, methodInstance); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, methodInstance->mMethodInstanceGroup->mOwner); - SetAndRestoreValue prevFilePos(mCurFilePosition); + SetAndRestoreValue prevFilePos(mCurFilePosition); SetAndRestoreValue prevHadBuildError(mHadBuildError, false); SetAndRestoreValue prevHadWarning(mHadBuildWarning, false); SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors); @@ -19499,10 +19969,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } } if ((mCompiler->mResolvePassData != NULL) && (methodDeclaration != NULL) && (nameNode != NULL) && - (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && + (mCompiler->mResolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (methodDef->mIdx >= 0) && (!methodInstance->mIsForeignMethodDef)) { - if (methodInstance->GetExplicitInterface() == NULL) + if (methodInstance->GetExplicitInterface() == NULL) mCompiler->mResolvePassData->HandleMethodReference(nameNode, typeDef, methodDef); else { @@ -19532,12 +20002,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, auto ifaceMethodDef = ifaceInst->mTypeDef->mMethods[checkMethod->mIdx]; mCompiler->mResolvePassData->HandleMethodReference(nameNode, ifaceInst->mTypeDef, ifaceMethodDef); } - } + } } } if (methodDef->mIsOverride) - { + { for (int virtIdx = 0; virtIdx < (int)mCurTypeInstance->mVirtualMethodTable.size(); virtIdx++) { auto& ventry = mCurTypeInstance->mVirtualMethodTable[virtIdx]; @@ -19579,11 +20049,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { if (customAttr->mCtorArgs.size() == 1) { - auto fileNameArg = customAttr->mCtorArgs[0]; + auto fileNameArg = customAttr->mCtorArgs[0]; auto constant = mCurTypeInstance->mConstHolder->GetConstant(fileNameArg); if (constant != NULL) { - if (!constant->IsNull()) + if (!constant->IsNull()) importStrNum = constant->mInt32; } else @@ -19593,7 +20063,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (importStrNum != -1) { if (!mStringPoolRefs.Contains(importStrNum)) - mStringPoolRefs.Add(importStrNum); + mStringPoolRefs.Add(importStrNum); } } } @@ -19602,7 +20072,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (methodInstance->GetImportCallKind() != BfImportCallKind_None) { if (mBfIRBuilder->mIgnoreWrites) - return; + return; BfLogSysM("DllImportGlobalVar processing %p\n", methodInstance); @@ -19613,41 +20083,41 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, BF_ASSERT(dllImportGlobalVar || methodInstance->mHasFailed); mFuncReferences[mCurMethodInstance] = dllImportGlobalVar; } - + if (HasCompiledOutput()) { BfDllImportEntry dllImportEntry; - dllImportEntry.mFuncVar = methodInstance->mIRFunction; + dllImportEntry.mFuncVar = methodInstance->mIRFunction; dllImportEntry.mMethodInstance = mCurMethodInstance; mDllImportEntries.push_back(dllImportEntry); } - return; + return; } StringT<512> mangledName; BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), mCurMethodInstance); if (!methodInstance->mIRFunction) - { + { bool isIntrinsic = false; - SetupIRFunction(methodInstance, mangledName, false, &isIntrinsic); + SetupIRFunction(methodInstance, mangledName, false, &isIntrinsic); } if (methodInstance->mIsIntrinsic) return; if (mCurTypeInstance->IsFunction()) return; - + auto prevActiveFunction = mBfIRBuilder->GetActiveFunction(); - mBfIRBuilder->SetActiveFunction(mCurMethodInstance->mIRFunction); + mBfIRBuilder->SetActiveFunction(mCurMethodInstance->mIRFunction); if (methodDef->mBody != NULL) UpdateSrcPos(methodDef->mBody, BfSrcPosFlag_NoSetDebugLoc); - else if (methodDeclaration != NULL) + else if (methodDeclaration != NULL) UpdateSrcPos(methodDeclaration, BfSrcPosFlag_NoSetDebugLoc); else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) UpdateSrcPos(methodDef->mDeclaringType->GetRefNode(), BfSrcPosFlag_NoSetDebugLoc); else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL) - UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc); - + UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc); + if ((mCurMethodState == NULL) && (!IsInSpecializedSection())) // Only do initial classify for the 'outer' method state, not any local methods or lambdas { if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (methodDef->mBody != NULL) && (!mCurTypeInstance->IsBoxed())) @@ -19655,7 +20125,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (auto sourceClassifier = mCompiler->mResolvePassData->GetSourceClassifier(methodDef->mBody)) sourceClassifier->VisitChildNoRef(methodDef->mBody); } - } + } BfHotDataReferenceBuilder hotDataReferenceBuilder; BfMethodState methodState; @@ -19663,7 +20133,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, methodState.mClosureState = mCurMethodState->mClosureState; if ((mCompiler->mOptions.mAllowHotSwapping) && (methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized) && (!isInlineDup)) - { + { //BF_ASSERT(methodInstance->mHotMethod != NULL); if (methodInstance->mHotMethod == NULL) CheckHotMethod(methodInstance, mangledName); @@ -19673,32 +20143,32 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, methodState.mPrevMethodState = mCurMethodState; methodState.mMethodInstance = methodInstance; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); - + if (methodInstance->GetCustomAttributes() != NULL) { int typeOptionsIdx = GenerateTypeOptions(methodInstance->GetCustomAttributes(), mCurTypeInstance, false); if (typeOptionsIdx != -1) methodState.mMethodTypeOptions = mSystem->GetTypeOptions(typeOptionsIdx); } - + BfTypeState typeState(mCurTypeInstance); SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (mCurTypeInstance->IsUnspecializedTypeVariation()); - BfMethodInstance* unspecializedMethodInstance = NULL; - if ((prevMethodState.mPrevVal != NULL) && + BfMethodInstance* unspecializedMethodInstance = NULL; + if ((prevMethodState.mPrevVal != NULL) && ((methodState.mClosureState == NULL) || (methodState.mClosureState->mActiveDeferredLocalMethod == NULL))) { // This is 'inner' (probably a closure) - use binding from outer function - methodState.mGenericTypeBindings = prevMethodState.mPrevVal->mGenericTypeBindings; + methodState.mGenericTypeBindings = prevMethodState.mPrevVal->mGenericTypeBindings; } - else if ((methodInstance->mIsUnspecialized) || + else if ((methodInstance->mIsUnspecialized) || ((mCurTypeInstance->IsUnspecializedType()) && (!isGenericVariation))) - { + { methodState.mGenericTypeBindings = &methodInstance->GetMethodInfoEx()->mGenericTypeBindings; } - else if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) || + else if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) || ((mCurTypeInstance->IsGenericTypeInstance()) && (!isGenericVariation || mIsComptimeModule) && (!methodInstance->mMethodDef->mIsLocalMethod) && (!methodInstance->mMethodDef->mDeclaringType->IsEmitted())))) { unspecializedMethodInstance = GetUnspecializedMethodInstance(methodInstance, !methodInstance->mMethodDef->mIsLocalMethod); @@ -19713,12 +20183,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, BF_ASSERT(unspecializedMethodInstance != methodInstance); if (!unspecializedMethodInstance->mHasBeenProcessed) { - // Make sure the unspecialized method is processed so we can take its bindings + // Make sure the unspecialized method is processed so we can take its bindings // Clear mCurMethodState so we don't think we're in a local method SetAndRestoreValue prevMethodState_Unspec(mCurMethodState, prevMethodState.mPrevVal); if (unspecializedMethodInstance->mMethodProcessRequest == NULL) unspecializedMethodInstance->mDeclModule->mIncompleteMethodCount++; - mContext->ProcessMethod(unspecializedMethodInstance); + mContext->ProcessMethod(unspecializedMethodInstance); } methodState.mGenericTypeBindings = &unspecializedMethodInstance->GetMethodInfoEx()->mGenericTypeBindings; } @@ -19738,8 +20208,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (operatorDef->mOperatorDeclaration->mBinOp != BfBinaryOp_None) { if (methodDef->mParams.size() != 2) - { - Fail("Binary operators must declare two parameters", paramErrorRefNode); + { + Fail("Binary operators must declare two parameters", paramErrorRefNode); } else { @@ -19813,7 +20283,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { Fail("Assignment operators must declare one parameter", paramErrorRefNode); } - + if (!mCurMethodInstance->mReturnType->IsVoid()) { Fail("The return type for assignment operator must be 'void'", operatorDef->mOperatorDeclaration->mReturnType); @@ -19841,12 +20311,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, auto checkParam0 = mCurMethodInstance->GetParamType(0); if ((checkParam0->IsRef()) && (!checkParam0->IsOut())) checkParam0 = checkParam0->GetUnderlyingType(); - + if ((checkParam0 != mCurTypeInstance) && (!checkParam0->IsSelf()) && (mCurMethodInstance->mReturnType != mCurTypeInstance) && (!mCurMethodInstance->mReturnType->IsSelf())) Fail("User-defined conversion must convert to or from the enclosing type", paramErrorRefNode); if (checkParam0 == mCurMethodInstance->mReturnType) - Fail("User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type", operatorDef->mOperatorDeclaration->mReturnType); + Fail("User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type", operatorDef->mOperatorDeclaration->mReturnType); // On type lookup error we default to 'object', so don't do the 'base class' error if that may have // happened here @@ -19881,20 +20351,20 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, diParams.push_back(mBfIRBuilder->DbgGetType(methodInstance->mReturnType)); bool isThisStruct = mCurTypeInstance->IsStruct() && !mCurTypeInstance->IsTypedPrimitive(); - BfType* thisType = NULL; + BfType* thisType = NULL; if (!methodDef->mIsStatic) { if ((methodState.mClosureState != NULL) && (methodState.mClosureState->mClosureType != NULL)) thisType = methodState.mClosureState->mClosureType; else - thisType = mCurTypeInstance; + thisType = mCurTypeInstance; } - + PopulateType(methodInstance->mReturnType, BfPopulateType_Data); - + ProcessMethod_SetupParams(methodInstance, thisType, wantsDIData, &diParams); - - ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// // { @@ -19905,24 +20375,24 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) UpdateSrcPos(methodDef->mDeclaringType->GetRefNode(), BfSrcPosFlag_NoSetDebugLoc); else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL) - UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc); + UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration, BfSrcPosFlag_NoSetDebugLoc); } BfIRMDNode diFunction; - + if (wantsDIData) { - BP_ZONE("BfModule::DoMethodDeclaration.DISetup"); + BP_ZONE("BfModule::DoMethodDeclaration.DISetup"); BfIRMDNode diFuncType = mBfIRBuilder->DbgCreateSubroutineType(diParams); int defLine = mCurFilePosition.mCurLine; if (mDICompileUnit) - { - int flags = 0; + { + int flags = 0; BfIRMDNode funcScope = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance); - + if (methodDef->mProtection == BfProtection_Public) flags = llvm::DINode::FlagPublic; else if (methodDef->mProtection == BfProtection_Protected) @@ -19939,7 +20409,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, flags |= llvm::DINode::FlagStaticMember; else { - if ((mCurTypeInstance->IsValuelessType()) || + if ((mCurTypeInstance->IsValuelessType()) || ((!mIsComptimeModule) && (mCurTypeInstance->IsSplattable()))) flags |= llvm::DINode::FlagStaticMember; } @@ -19948,9 +20418,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { flags |= llvm::DINode::FlagArtificial; } - + auto llvmFunction = methodInstance->mIRFunction; - SizedArray genericArgs; + SizedArray genericArgs; SizedArray genericConstValueArgs; String methodName; @@ -19967,7 +20437,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } methodName += methodDef->mName; - + if (methodInstance->GetNumGenericArguments() != 0) { for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments) @@ -19979,12 +20449,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, genericConstValueArgs.push_back(BfIRValue()); genericConstValueArgs.push_back(mBfIRBuilder->CreateConst(BfTypeCode_UInt64, constExprValueType->mValue.mUInt64)); - genericArgs.push_back(mBfIRBuilder->DbgGetType(GetPrimitiveType(BfTypeCode_Int64))); + genericArgs.push_back(mBfIRBuilder->DbgGetType(GetPrimitiveType(BfTypeCode_Int64))); } else genericArgs.push_back(mBfIRBuilder->DbgGetType(genericArg)); } - + methodName += "<"; for (int i = 0; i < (int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size(); i++) { @@ -19994,7 +20464,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, methodName += TypeToString(type); } methodName += ">"; - } + } if ((methodName.empty()) && (methodDeclaration != NULL)) { @@ -20018,39 +20488,38 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, methodState.mDIFile = mCurFilePosition.mFileInstance->mDIFile; // diFunction = mBfIRBuilder->DbgCreateMethod(funcScope, methodName, mangledName, methodState.mDIFile, -// defLine + 1, diFuncType, false, true, +// defLine + 1, diFuncType, false, true, // (methodInstance->mVirtualTableIdx != -1) ? llvm::dwarf::DW_VIRTUALITY_virtual : llvm::dwarf::DW_VIRTUALITY_none, // (methodInstance->mVirtualTableIdx != -1) ? methodInstance->DbgGetVirtualMethodNum() : 0, // nullptr, flags, IsOptimized(), llvmFunction, genericArgs, genericConstValueArgs); - + diFunction = mBfIRBuilder->DbgCreateMethod(funcScope, methodName, mangledName, methodState.mDIFile, - defLine + 1, diFuncType, false, true, + defLine + 1, diFuncType, false, true, llvm::dwarf::DW_VIRTUALITY_none, 0, BfIRMDNode(), flags, IsOptimized(), llvmFunction, genericArgs, genericConstValueArgs); - } else { methodState.mDIFile = mCurFilePosition.mFileInstance->mDIFile; } } - + ////////////////////////////////////////////////////////////////////////// // Head and Init get rolled into Entry afterwards. - + methodState.mIRFunction = methodInstance->mIRFunction; - methodState.mIRHeadBlock = mBfIRBuilder->CreateBlock("head", true); + methodState.mIRHeadBlock = mBfIRBuilder->CreateBlock("head", true); methodState.mIRInitBlock = mBfIRBuilder->CreateBlock("init", true); - + methodState.mIREntryBlock = mBfIRBuilder->CreateBlock("entry", true); methodState.mCurScope->mDIScope = diFunction; - auto llvmEntryBlock = methodState.mIREntryBlock; + auto llvmEntryBlock = methodState.mIREntryBlock; mBfIRBuilder->SetInsertPoint(llvmEntryBlock); - + if (methodDef->mName == "__MALFORMED") { auto newBlock = mBfIRBuilder->CreateBlock("malformed", true); @@ -20073,15 +20542,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // Clear out DebugLoc - to mark the ".addr" code as part of prologue mBfIRBuilder->ClearDebugLocation(); - + bool isTypedPrimitiveFunc = mCurTypeInstance->IsTypedPrimitive() && (methodDef->mMethodType != BfMethodType_Ctor); int irParamCount = methodInstance->GetIRFunctionParamCount(this); if (methodInstance->GetImportKind() != BfImportKind_Import_Dynamic) { int localIdx = 0; - int argIdx = 0; - + int argIdx = 0; + Array splatAddrValues; for ( ; argIdx < irParamCount; localIdx++) @@ -20113,12 +20582,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { paramVar->mIsReadOnly = true; } - - bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || + + bool wantsAddr = (wantsDIVariables) || (!paramVar->mIsReadOnly) || ((!mIsComptimeModule) && (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter))); if (paramVar->mResolvedType->IsMethodRef()) - wantsAddr = false; + wantsAddr = false; // if ((methodDef->mHasAppend) && (argIdx == 1)) // { @@ -20127,7 +20596,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // } if (paramVar->mIsSplat) - { + { auto prevInsert = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); BfTypeUtils::SplatIterate([&](BfType* checkType) @@ -20148,7 +20617,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->SetInsertPoint(prevInsert); } else if (isThis) - { + { if (wantsAddr) { auto prevInsert = mBfIRBuilder->GetInsertBlock(); @@ -20165,7 +20634,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, wantPtr = true; if (wantPtr) - { + { thisAddrType = mBfIRBuilder->MapTypeInstPtr(thisType->ToTypeInstance()); } @@ -20194,7 +20663,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, alignSize = paramVar->mResolvedType->mAlign; } else - { + { paramVar->mHasLocalStructBacking = true; auto typeInst = paramVar->mResolvedType->ToTypeInstance(); if (typeInst != NULL) @@ -20212,16 +20681,16 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->SetName(allocaInst, paramVar->mName + ".addr"); mBfIRBuilder->SetAllocaAlignment(allocaInst, alignSize); paramVar->mAddr = allocaInst; - mBfIRBuilder->SetInsertPoint(prevInsert); + mBfIRBuilder->SetInsertPoint(prevInsert); if (WantsLifetimes()) mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(allocaInst); } } else if (wantsAddr) - { + { auto allocaInst = CreateAlloca(paramVar->mResolvedType); mBfIRBuilder->SetName(allocaInst, paramVar->mName + ".addr"); - paramVar->mAddr = allocaInst; + paramVar->mAddr = allocaInst; } if (paramVar->mIsSplat) @@ -20242,18 +20711,18 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, argIdx++; } } - - if (methodDef->mBody != NULL) - UpdateSrcPos(methodDef->mBody); + + if (methodDef->mBody != NULL) + UpdateSrcPos(methodDef->mBody); else if ((methodDef->mDeclaringType != NULL) && (methodDef->mDeclaringType->GetRefNode() != NULL)) UpdateSrcPos(methodDef->mDeclaringType->GetRefNode()); else if (mCurTypeInstance->mTypeDef->mTypeDeclaration != NULL) UpdateSrcPos(mCurTypeInstance->mTypeDef->mTypeDeclaration); - + localIdx = 0; argIdx = 0; - - int splatAddrIdx = 0; + + int splatAddrIdx = 0; while (localIdx < (int)methodState.mLocals.size()) { if ((!mIsComptimeModule) && (argIdx == methodInstance->GetStructRetIdx())) @@ -20267,7 +20736,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (!paramVar->IsParam()) continue; if (paramVar->mCompositeCount != -1) - continue; + continue; bool isThis = ((curLocalIdx == 0) && (!mCurMethodInstance->mMethodDef->mIsStatic)); if ((isThis) && (thisType->IsValuelessType())) @@ -20286,7 +20755,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { if ((mCurMethodState->mClosureState != NULL) && (mCurMethodState->mClosureState->mClosureType != NULL)) paramName = "__closure"; - + if ((paramVar->mResolvedType->IsValueType()) && (!paramVar->mIsSplat) && (!paramVar->mIsLowered)) { diType = mBfIRBuilder->DbgGetType(paramVar->mResolvedType); @@ -20311,7 +20780,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, diType = mBfIRBuilder->DbgCreateConstType(diType); } } - + if (!paramVar->mIsSplat) { if ((paramVar->mParamIdx >= 0) && (paramVar->mParamIdx < methodInstance->mDefaultValues.mSize)) @@ -20354,19 +20823,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, paramVar->mDbgVarInst = diVariable; } else if ((paramVar->mIsSplat) && (paramVar->mResolvedType->GetSplatCount() == 0)) - { + { // if ((mBfIRBuilder->HasDebugLocation()) && (wantsDIVariables)) // { -// // Only add this placeholder if we don't have any values +// // Only add this placeholder if we don't have any values // auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, // paramName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, diType); // mBfIRBuilder->DbgInsertValueIntrinsic(GetConstValue(0), diVariable); // } } } - + bool isTypedPrimCtor = mCurTypeInstance->IsTypedPrimitive() && (methodDef->mMethodType == BfMethodType_Ctor); - + if ((!paramVar->mParamFailed) && (paramVar->mAddr)) { // Write our argument value into the .addr @@ -20374,13 +20843,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (paramVar->mIsSplat) { mBfIRBuilder->PopulateType(paramVar->mResolvedType); - // + // } else { bool handled = false; if (paramVar->mIsLowered) - { + { BfTypeCode loweredTypeCode = BfTypeCode_None; BfTypeCode loweredTypeCode2 = BfTypeCode_None; if (paramVar->mResolvedType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2)) @@ -20393,11 +20862,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { isTempTarget = true; targetAddr = CreateAlloca(GetPrimitiveType(BfTypeCode_Int8), true, NULL, GetConstValue(loweredSize)); - mBfIRBuilder->SetAllocaAlignment(targetAddr, - BF_MAX(paramVar->mResolvedType->mAlign, + mBfIRBuilder->SetAllocaAlignment(targetAddr, + BF_MAX(paramVar->mResolvedType->mAlign, BF_MAX(mBfIRBuilder->GetSize(loweredTypeCode), mBfIRBuilder->GetSize(loweredTypeCode2)))); } - + // We have a lowered type coming in, so we have to cast the .addr before storing auto primType = mBfIRBuilder->GetPrimitiveType(loweredTypeCode); auto primPtrType = mBfIRBuilder->GetPointerTo(primType); @@ -20414,7 +20883,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, else primPtrVal2 = mBfIRBuilder->CreateBitCast(mBfIRBuilder->CreateInBoundsGEP(primPtrVal, 1), primPtrType2); mBfIRBuilder->CreateStore(mBfIRBuilder->GetArgument(argIdx + 1), primPtrVal2); - } + } if (isTempTarget) { @@ -20437,14 +20906,14 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->CreateAlignedStore(paramVar->mValue, paramVar->mAddr, paramVar->mResolvedType->mAlign); } } - + if (methodDef->mBody != NULL) UpdateSrcPos(methodDef->mBody); else if (methodDef->mDeclaringType->mTypeDeclaration != NULL) UpdateSrcPos(methodDef->mDeclaringType->mTypeDeclaration); else if (methodDeclaration == NULL) UseDefaultSrcPos(); - + // Write our argument value into the .addr if (paramVar->mIsSplat) { @@ -20476,9 +20945,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, curArgIdx++; splatComponentIdx++; }; - + std::function _FinishSplatsIterate = [&](BfType* checkType, const StringImpl& name) - { + { if (checkType->IsStruct()) { auto checkTypeInstance = checkType->ToTypeInstance(); @@ -20491,13 +20960,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { auto unionInnerType = checkTypeInstance->GetUnionInnerType(); if (!unionInnerType->IsValuelessType()) - { + { _FinishSplatsIterate(unionInnerType, name + "$u"); } if (checkTypeInstance->IsEnum()) { - auto dscrType = checkTypeInstance->GetDiscriminatorType(); + auto dscrType = checkTypeInstance->GetDiscriminatorType(); _FinishSplatsIterate(dscrType, name + "$d"); } } @@ -20521,7 +20990,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // int implicitParamCount = methodInstance->GetImplicitParamCount(); // for (int implicitParamIdx = methodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++) // { -// auto paramType = methodInstance->GetParamType(implicitParamIdx); +// auto paramType = methodInstance->GetParamType(implicitParamIdx); // if (!paramType->IsValuelessType()) // _FinishSplats(paramType, name + "$m$" + methodInstance->GetParamName(implicitParamIdx)); // } @@ -20536,17 +21005,17 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, _FinishSplatsIterate(methodRefType->GetCaptureType(dataIdx), name + "$m$" + paramName); } else - { + { _FinishSplats(methodRefType->GetCaptureType(dataIdx), name + "$m$" + paramName); } } } else if (!checkType->IsValuelessType()) { - _FinishSplats(checkType, name); + _FinishSplats(checkType, name); } }; - + mBfIRBuilder->PopulateType(paramVar->mResolvedType); if (!paramVar->mConstValue) _FinishSplatsIterate(paramVar->mResolvedType, "$" + paramVar->mName); @@ -20556,12 +21025,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (diVariable) { if ((mBfIRBuilder->HasDebugLocation()) && (wantsDIVariables)) - { + { if (!paramVar->mAddr) { if ((!paramVar->mValue) || (paramVar->mValue.IsFake())) { - if ((!paramVar->mIsThis) && (mCompiler->mOptions.mToolsetType != BfToolsetType_GNU)) // DWARF chokes on this: { // We don't need to set the location for this @@ -20579,17 +21047,17 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } if ((isThis) && (!paramVar->mIsSplat) && (paramVar->mAddr)) - { + { // We don't allow actually assignment to "this", so we just do a single load // Keep in mind we don't use the ACTUAL mValue value because that's a register, but // we need to store it in the stack frame for debugging purposes auto loadedThis = mBfIRBuilder->CreateAlignedLoad(paramVar->mAddr/*, "this"*/, paramVar->mResolvedType->mAlign); - mBfIRBuilder->ClearDebugLocation(loadedThis); + mBfIRBuilder->ClearDebugLocation(loadedThis); paramVar->mValue = loadedThis; } - + if ((wantsDIData) && (declareCall)) - mBfIRBuilder->UpdateDebugLocation(declareCall); + mBfIRBuilder->UpdateDebugLocation(declareCall); if (paramVar->mIsSplat) { @@ -20614,7 +21082,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, BF_ASSERT(splatAddrIdx == (int)splatAddrValues.size()); } } - + for (int varIdx = 0; varIdx < (int)mCurMethodState->mLocals.size(); varIdx++) { auto paramVar = mCurMethodState->mLocals[varIdx]; @@ -20631,10 +21099,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // } if (paramVar->mResolvedType->IsValuelessType()) - { + { if ((mBfIRBuilder->HasDebugLocation()) && (wantsDIVariables) && (mCompiler->mOptions.mToolsetType != BfToolsetType_GNU)) // DWARF chokes on this: { - // Only add this placeholder if we don't have any values + // Only add this placeholder if we don't have any values auto diType = mBfIRBuilder->DbgGetType(paramVar->mResolvedType); auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, paramVar->mName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, diType); @@ -20667,7 +21135,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if ((methodDef != NULL) && (propertyDeclaration != NULL) && (propertyDeclaration->mExternSpecifier != NULL)) hasExternSpecifier = true; - // Allocate, clear, set classVData + // Allocate, clear, set classVData if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic)) { @@ -20677,7 +21145,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { skipBody = true; skipEndChecks = true; - + if (HasExecutedOutput()) { // Clear out DebugLoc - to mark the ".addr" code as part of prologue @@ -20708,7 +21176,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->CreateRetVoid(); } else - { + { auto innerMethodDef = innerMethodInstance.mMethodInstance->mMethodDef; BF_ASSERT(innerMethodDef == methodDef); @@ -20720,7 +21188,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, BfIRValue thisValue = mBfIRBuilder->CreateInBoundsGEP(mCurMethodState->mLocals[0]->mValue, 0, 1); BfTypedValue innerVal(thisValue, innerType, true); if (boxedType->IsBoxedStructPtr()) - { + { innerVal = LoadValue(innerVal); innerVal = BfTypedValue(innerVal.mValue, innerType, true); } @@ -20757,12 +21225,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } } } - + mCurMethodState->SetHadReturn(true); mCurMethodState->mLeftBlockUncond = true; } else if (methodDef->mMethodType == BfMethodType_CtorClear) - { + { SetIllegalSrcPos(); mBfIRBuilder->ClearDebugLocation(); PopulateType(mCurTypeInstance, BfPopulateType_Data); @@ -20783,15 +21251,47 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } } } + auto int8PtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_Int8)); + int curSize = mCurTypeInstance->mInstSize; if (curSize > prevSize) { - auto int8PtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_Int8)); auto int8PtrVal = mBfIRBuilder->CreateBitCast(thisVal.mValue, mBfIRBuilder->MapType(int8PtrType)); int8PtrVal = mBfIRBuilder->CreateInBoundsGEP(int8PtrVal, GetConstValue(prevSize)); mBfIRBuilder->CreateMemSet(int8PtrVal, GetConstValue8(0), GetConstValue(curSize - prevSize), GetConstValue(mCurTypeInstance->mInstAlign)); } + if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) + { + auto useThis = mCurMethodState->mLocals[0]->mValue; + auto useThisType = mCurTypeInstance; + + auto checkTypeInst = mCurTypeInstance; + while (checkTypeInst != NULL) + { + for (auto& fieldInstance : checkTypeInst->mFieldInstances) + { + auto fieldDef = fieldInstance.GetFieldDef(); + if ((fieldDef == NULL) || (fieldDef->mIsStatic)) + continue; + if (fieldInstance.IsAppendedObject()) + { + if (checkTypeInst != useThisType) + { + useThis = mBfIRBuilder->CreateBitCast(useThis, mBfIRBuilder->MapType(checkTypeInst)); + useThisType = checkTypeInst; + } + + BfIRValue fieldAddr = mBfIRBuilder->CreateInBoundsGEP(useThis, 0, fieldInstance.mDataIdx); + auto int8PtrVal = mBfIRBuilder->CreateBitCast(fieldAddr, mBfIRBuilder->MapType(int8PtrType)); + mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_Deleted), int8PtrVal); + } + } + + checkTypeInst = checkTypeInst->mBaseType; + } + } + skipUpdateSrcPos = true; } else if (((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorNoBody)) && (!hasExternSpecifier)) @@ -20803,7 +21303,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, EmitDtorBody(); skipBody = true; } - + if ((!mCurTypeInstance->IsBoxed()) && (methodDeclaration != NULL) && (methodDeclaration->mHadYield) && (methodDef->mBody != NULL)) { EmitIteratorBlock(skipBody); @@ -20821,11 +21321,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mCurMethodState->mIgnoreObjectAccessCheck = true; if (customAttributes->Contains(mCompiler->mDisableChecksAttributeTypeDef)) mCurMethodState->mDisableChecks = true; - } - + } + if ((methodDef->mMethodType == BfMethodType_CtorNoBody) && (!methodDef->mIsStatic) && ((methodInstance->mChainType == BfMethodChainType_ChainHead) || (methodInstance->mChainType == BfMethodChainType_None))) - { + { // We chain even non-default ctors to the default ctors auto defaultCtor = methodInstance; if (defaultCtor->mChainType == BfMethodChainType_ChainHead) @@ -20842,17 +21342,17 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (methodDeclaration != NULL) { if (auto operatorDeclaration = BfNodeDynCast(methodDeclaration)) - { + { if (operatorDeclaration->mIsConvOperator) wantsRemoveBody = true; } } - bool isDllImport = false; + bool isDllImport = false; if ((importKind == BfImportKind_Import_Static) || (importKind == BfImportKind_Import_Dynamic)) { if (importStrNum != -1) - { + { if (importKind == BfImportKind_Import_Static) { if (!mImportFileNames.Contains(importStrNum)) @@ -20860,7 +21360,6 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mImportFileNames.Add(importStrNum); } } - } } else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic) @@ -20904,7 +21403,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } else { - // Unfortunate DebugLoc shenanigans- + // Unfortunate DebugLoc shenanigans- // Our params get removed if we don't have any DebugLocs, but we don't want to actually be able to step into this method, // so we only set the loc on the CreateRet which gets inlined out mBfIRBuilder->SaveDebugLocation(); @@ -20929,21 +21428,21 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mCurMethodState->SetHadReturn(true); mCurMethodState->mLeftBlockUncond = true; - } - else if (((methodDef->mName == BF_METHODNAME_ENUM_GETUNDERLYINGREF) || (methodDef->mName == BF_METHODNAME_ENUM_GETUNDERLYING)) && + } + else if (((methodDef->mName == BF_METHODNAME_ENUM_GETUNDERLYINGREF) || (methodDef->mName == BF_METHODNAME_ENUM_GETUNDERLYING)) && (mCurTypeInstance->IsEnum()) && (!mCurTypeInstance->IsBoxed())) { - BfIRValue ret; - // Unfortunate DebugLoc shenanigans- + BfIRValue ret; + // Unfortunate DebugLoc shenanigans- // Our params get removed if we don't have any DebugLocs, but we don't want to actually be able to step into this method, // so we only set the loc on the CreateRet which gets inlined out mBfIRBuilder->SaveDebugLocation(); mBfIRBuilder->ClearDebugLocation(); - BfIRValue fromBool; + BfIRValue fromBool; mBfIRBuilder->RestoreDebugLocation(); ret = mBfIRBuilder->CreateRet(GetThis().mValue); //ExtendLocalLifetimes(0); - EmitLifetimeEnds(&mCurMethodState->mHeadScope); + EmitLifetimeEnds(&mCurMethodState->mHeadScope); mCurMethodState->SetHadReturn(true); mCurMethodState->mLeftBlockUncond = true; @@ -20999,7 +21498,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, skipEndChecks = true; } else - { + { auto propertyDeclaration = methodDef->GetPropertyDeclaration(); if ((propertyDeclaration != NULL) && (!typeDef->HasAutoProperty(propertyDeclaration))) { @@ -21114,7 +21613,6 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } else if (!mCurTypeInstance->IsObject()) { - } } else if (methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS) @@ -21130,7 +21628,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, else if (!skipBody) { bool isEmptyBodied = BfNodeDynCast(methodDef->mBody) != NULL; - + bool wantsRetVal = true; if ((mIsComptimeModule) && (methodDef->mMethodType != BfMethodType_CtorCalcAppend)) wantsRetVal = false; @@ -21138,13 +21636,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, wantsRetVal = false; if ((!mCurMethodInstance->mReturnType->IsValuelessType()) && (!isEmptyBodied)) - { + { mBfIRBuilder->PopulateType(mCurMethodInstance->mReturnType); - + if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) { auto ptrType = CreatePointerType(mCurMethodInstance->mReturnType); - auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false); + auto allocaInst = AllocLocalVariable(ptrType, "__return.addr", false); auto storeInst = mBfIRBuilder->CreateAlignedStore(mBfIRBuilder->GetArgument(mCurMethodInstance->GetStructRetIdx()), allocaInst, mCurMethodInstance->mReturnType->mAlign); mBfIRBuilder->ClearDebugLocation(storeInst); mCurMethodState->mRetValAddr = allocaInst; @@ -21153,7 +21651,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { auto allocaInst = AllocLocalVariable(mCurMethodInstance->mReturnType, "__return", false); mCurMethodState->mRetVal = BfTypedValue(allocaInst, mCurMethodInstance->mReturnType, true); - } + } } if (methodDef->mMethodType == BfMethodType_CtorCalcAppend) @@ -21186,7 +21684,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, isExpressionBody = true; } else if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) - { + { auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration(); if ((propertyMethodDeclaration != NULL) && (propertyMethodDeclaration->mFatArrowToken != NULL)) isExpressionBody = true; @@ -21232,7 +21730,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, VisitCodeBlock(bodyBlock); } else if (auto expressionBody = BfNodeDynCast(methodDef->mBody)) - { + { // if ((methodDef->mMethodType != BfMethodType_Normal) && (propertyDeclaration == NULL)) // { // BF_ASSERT(methodDeclaration->mFatArrowToken != NULL); @@ -21245,7 +21743,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // { // Warn(0, "Using a 'void' return with an expression-bodied method isn't needed. Consider removing '=>' token", methodDeclaration->mFatArrowToken); // } - + BfEvalExprFlags exprEvalFlags = (BfEvalExprFlags)(BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_IsExpressionBody); if (expectingType->IsVoid()) { @@ -21262,7 +21760,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if ((unspecializedMethodInstance != NULL) && (unspecializedMethodInstance->mReturnType->IsGenericParam())) wasReturnGenericParam = true; } - + // If we the void return was from a generic specialization, allow us to return a void result, // otherwise treat expression as though it must be a statement bool isStatement = expressionBody->VerifyIsStatement(mCompiler->mPassInstance, wasReturnGenericParam); @@ -21283,7 +21781,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, EmitReturn(retVal); } } - } + } } BF_ASSERT(mCurMethodState->mCurScope == &mCurMethodState->mHeadScope); @@ -21304,7 +21802,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, UseDefaultSrcPos(); if (methodDef->mMethodType == BfMethodType_CtorCalcAppend) - { + { if (mCurMethodState->mRetVal) { mCurMethodState->SetHadReturn(true); @@ -21317,12 +21815,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (!mCurMethodState->mHadReturn) { - // Clear off the stackallocs that have occurred after a scopeData break + // Clear off the stackallocs that have occurred after a scopeData break EmitDeferredScopeCalls(false, &mCurMethodState->mHeadScope, mCurMethodState->mIRExitBlock); } - + if (mCurMethodState->mIRExitBlock) - { + { for (auto preExitBlock : mCurMethodState->mHeadScope.mAtEndBlocks) mBfIRBuilder->MoveBlockToEnd(preExitBlock); @@ -21346,16 +21844,16 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if (mCurMethodState->mIRExitBlock) { - if ((mCurMethodState->mRetVal) && + if ((mCurMethodState->mRetVal) && ((mIsComptimeModule) || (mCurMethodInstance->GetStructRetIdx() == -1))) - { + { auto loadedVal = mBfIRBuilder->CreateAlignedLoad(mCurMethodState->mRetVal.mValue, mCurMethodState->mRetVal.mType->mAlign); - - CreateReturn(loadedVal); - + + CreateReturn(loadedVal); + EmitLifetimeEnds(&mCurMethodState->mHeadScope); - - if (mCurMethodState->mDIRetVal) + + if (mCurMethodState->mDIRetVal) mBfIRBuilder->DbgLifetimeEnd(mCurMethodState->mDIRetVal); } else @@ -21366,7 +21864,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, if ((bodyBlock != NULL) && (bodyBlock->mCloseBrace != NULL)) UpdateSrcPos(bodyBlock->mCloseBrace); EmitEnsureInstructionAt(); - + if ((irParamCount == 0) && (!IsTargetingBeefBackend()) && (mCompiler->mOptions.mAllowHotSwapping)) { // This may be a case where we only emit 4 bytes, whereas we need 5 for a hot replace jump @@ -21375,13 +21873,12 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } mBfIRBuilder->CreateRetVoid(); EmitLifetimeEnds(&mCurMethodState->mHeadScope); - + if (mCurMethodState->mDIRetVal) mBfIRBuilder->DbgLifetimeEnd(mCurMethodState->mDIRetVal); } } - - + if ((mCurMethodInstance->mReturnType == NULL) || (mCurMethodInstance->mReturnType->IsValuelessType())) { if ((!mCurMethodState->mHadReturn) && (!mCurMethodState->mIRExitBlock)) @@ -21394,14 +21891,14 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->CreateRetVoid(); } - } + } else - { + { if (!mCurMethodState->mHadReturn) { - auto refNode = mCurMethodInstance->mMethodDef->GetRefNode(); + auto refNode = mCurMethodInstance->mMethodDef->GetRefNode(); if (bodyBlock != NULL) - { + { if (bodyBlock->mCloseBrace != NULL) { BfAstNode* target = bodyBlock->mCloseBrace; @@ -21418,7 +21915,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, // It's possible to not have a closing brace if the method ends in an EOF AssertErrorState(); } - } + } } } @@ -21426,13 +21923,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->MergeBlockDown(mCurMethodState->mIRInitBlock, mCurMethodState->mIREntryBlock); mBfIRBuilder->MergeBlockDown(mCurMethodState->mIRHeadBlock, mCurMethodState->mIREntryBlock); - if (((mCurMethodInstance->mIsUnspecialized) /*|| (typeDef->mIsFunction)*/ || (mCurTypeInstance->IsUnspecializedType())) && + if (((mCurMethodInstance->mIsUnspecialized) /*|| (typeDef->mIsFunction)*/ || (mCurTypeInstance->IsUnspecializedType())) && (!mIsComptimeModule)) { // Don't keep instructions for unspecialized types - mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); - } - + mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); + } + // Avoid linking any internal funcs that were just supposed to be comptime-accessible /*if ((methodDef->mHasComptime) && (!mIsComptimeModule)) wantsRemoveBody = true;*/ @@ -21454,7 +21951,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); } else if (wantsRemoveBody) - mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); + mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction); // We don't want to hold on to pointers to LLVMFunctions of unspecialized types. // This allows us to delete the mScratchModule LLVM module without rebuilding all @@ -21465,7 +21962,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, BfLogSysM("ProcessMethod Clearing IRFunction: %p\n", methodInstance); methodInstance->mIRFunction = BfIRFunction(); } - + CheckAddFailType(); if (mHadBuildError) @@ -21479,8 +21976,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, mBfIRBuilder->SetActiveFunction(prevActiveFunction); if (methodState.mHotDataReferenceBuilder != NULL) - { - AddHotDataReferences(&hotDataReferenceBuilder); + { + AddHotDataReferences(&hotDataReferenceBuilder); } else { @@ -21494,15 +21991,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, { // If there's a prev method then pull its data into the main HotMethod. // This, in effect, removes the 'hotMethod' data and rebases 'prevMethod' - // over to the main HotMethod definition to keep the HotMethod address - // invariant + // over to the main HotMethod definition to keep the HotMethod address + // invariant for (auto ref : hotMethod->mReferences) ref->Deref(); - hotMethod->mReferences.Clear(); + hotMethod->mReferences.Clear(); BF_ASSERT(prevMethod->mRefCount == 1); hotMethod->mReferences = prevMethod->mReferences; - + if (hotMethod->mSrcTypeVersion != NULL) hotMethod->mSrcTypeVersion->Deref(); hotMethod->mSrcTypeVersion = prevMethod->mSrcTypeVersion; @@ -21513,7 +22010,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, prevMethod->mPrevVersion = NULL; prevMethod->Deref(); } - + hotMethod->Deref(); methodInstance->mHotMethod = NULL; } @@ -21521,9 +22018,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup, } String BfModule::GetLocalMethodName(const StringImpl& baseName, BfAstNode* anchorNode, BfMethodState* declMethodState, BfMixinState* declMixinState) -{ +{ String name; - + bool found = false; auto checkMethodState = mCurMethodState; while (checkMethodState != NULL) @@ -21537,15 +22034,15 @@ String BfModule::GetLocalMethodName(const StringImpl& baseName, BfAstNode* ancho break; } checkMethodState = checkMethodState->mPrevMethodState; - } + } if (!found) - name += mCurMethodInstance->mMethodDef->mName; + name += mCurMethodInstance->mMethodDef->mName; int prevSepPos = (int)name.LastIndexOf('$'); if (prevSepPos != -1) - { - name.RemoveToEnd(prevSepPos); + { + name.RemoveToEnd(prevSepPos); } name += "@"; @@ -21608,7 +22105,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) auto _AllocDirectTypeRef = [&](BfType* type) { BfDirectTypeReference* directTypeRef = localMethod->mDirectTypeRefs.Alloc(); - directTypeRef->Init(type); + directTypeRef->Init(type); return directTypeRef; }; @@ -21616,7 +22113,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) if (methodDeclaration != NULL) { body = methodDeclaration->mBody; - anchorNode = methodDeclaration->mOpenParen; + anchorNode = methodDeclaration->mOpenParen; } else { @@ -21645,15 +22142,15 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) methodDef = defBuilder.CreateMethodDef(methodDeclaration, outerMethodDef); } else - { + { auto invokeMethod = localMethod->mLambdaInvokeMethodInstance; - + methodDef = new BfMethodDef(); methodDef->mName = localMethod->mMethodName; methodDef->mDeclaringType = mCurMethodInstance->mMethodDef->mDeclaringType; methodDef->mReturnTypeRef = _AllocDirectTypeRef(invokeMethod->mReturnType); methodDef->mBody = body; - + for (int paramIdx = 0; paramIdx < invokeMethod->GetParamCount(); paramIdx++) { auto paramType = invokeMethod->GetParamType(paramIdx); @@ -21662,7 +22159,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) paramName = localMethod->mLambdaBindExpr->mParams[paramIdx]->ToString(); else paramName = invokeMethod->GetParamName(paramIdx); - + auto paramDef = new BfParameterDef(); paramDef->mTypeRef = _AllocDirectTypeRef(paramType); paramDef->mName = paramName; @@ -21686,7 +22183,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) methodDef->mName = localMethod->mExpectedFullName; // methodDef->mName = GetLocalMethodName(methodDef->mName, anchorNode, declMethodState, declMixinState); - // + // // if (!localMethod->mExpectedFullName.IsEmpty()) // BF_ASSERT(methodDef->mName == localMethod->mExpectedFullName); @@ -21694,7 +22191,7 @@ BfMethodDef* BfModule::GetLocalMethodDef(BfLocalMethod* localMethod) methodDef->mIsLocalMethod = true; methodDef->mIsVirtual = false; localMethod->mMethodDef = methodDef; - + auto methodInstanceGroup = new BfMethodInstanceGroup(); localMethod->mMethodInstanceGroup = methodInstanceGroup; methodInstanceGroup->mMethodIdx = -1; @@ -21729,45 +22226,45 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth BP_ZONE_F("GetLocalMethodInstance %s", localMethod->mMethodName.c_str()); BfLogSysM("GetLocalMethodInstance %p\n", localMethod); - + auto rootMethodState = mCurMethodState->GetRootMethodState(); auto declMethodState = localMethod->mDeclMethodState; auto declMixinState = localMethod->mDeclMixinState; auto callerMethodState = mCurMethodState; - + auto typeInst = mCurTypeInstance; if (mCurMethodState->mMixinState != NULL) { typeInst = mCurMethodState->mMixinState->mMixinMethodInstance->GetOwner(); } - + auto methodDef = GetLocalMethodDef(localMethod); BfAstNode* body = NULL; - + auto methodDeclaration = localMethod->mMethodDeclaration; if (methodDeclaration != NULL) { - body = methodDeclaration->mBody; + body = methodDeclaration->mBody; } else { - body = localMethod->mLambdaBindExpr->mBody; + body = localMethod->mLambdaBindExpr->mBody; } - + bool hadConcreteInterfaceGenericArgument = false; BfTypeVector sanitizedMethodGenericArguments; - + // Ignore the outermost method's generic method arguments for the purpose of determining if we are the 'default' (ie: unspecialized) // version of this method for this pass through the outermost method int dependentGenericStartIdx = 0; if ((rootMethodState->mMethodInstance != NULL) && (rootMethodState->mMethodInstance->mMethodInfoEx != NULL)) dependentGenericStartIdx = (int)rootMethodState->mMethodInstance->mMethodInfoEx->mMethodGenericArguments.size(); - + BfMethodInstance* outerMethodInstance = mCurMethodInstance; - + if (methodGenericArguments.size() == 0) { if ((rootMethodState->mMethodInstance != NULL) && (rootMethodState->mMethodInstance->mMethodInfoEx != NULL)) @@ -21797,7 +22294,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth sanitizedMethodGenericArguments.push_back(genericArgType); } } - + bool wantPrematureMethodInstance = false; if (!force) { @@ -21805,12 +22302,12 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth } auto methodInstGroup = localMethod->mMethodInstanceGroup; - + bool isDefaultPass = true; BfTypeVector lookupMethodGenericArguments; for (int genericArgIdx = dependentGenericStartIdx; genericArgIdx < (int)methodGenericArguments.size(); genericArgIdx++) { - auto genericArgType = methodGenericArguments[genericArgIdx]; + auto genericArgType = methodGenericArguments[genericArgIdx]; BF_ASSERT(!genericArgType->IsRef()); lookupMethodGenericArguments.Add(genericArgType); @@ -21903,31 +22400,37 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth methodInfoEx->mMethodGenericArguments.push_back(genericParamType); } SetupMethodIdHash(methodInstance); - } + } auto _SetupMethodInstance = [&]() { BF_ASSERT(methodInstance->GetNumGenericParams() == 0); - + // Generic constraints for (int genericParamIdx = 0; genericParamIdx < (int)methodDef->mGenericParams.size(); genericParamIdx++) { auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx); methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance); } + + for (int externConstraintIdx = 0; externConstraintIdx < (int)methodDef->mExternalConstraints.size(); externConstraintIdx++) + { + auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, externConstraintIdx + (int)methodDef->mGenericParams.size()); + methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance); + } }; ////////////////////////////////////////////////////////////////////////// auto _VisitLambdaBody = [&]() - { + { if (localMethod->mDeclOnly) return; if (mCompiler->mCanceling) return; if (auto blockBody = BfNodeDynCast(body)) - { + { VisitCodeBlock(blockBody); } else if (auto bodyExpr = BfNodeDynCast(body)) @@ -21951,14 +22454,14 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth BfTypeInstance* outerClosure = NULL; if ((declMethodState->mClosureState != NULL) && (!declMethodState->mClosureState->mCapturing)) outerClosure = declMethodState->mClosureState->mClosureType; - - BfMethodState methodState; + + BfMethodState methodState; methodState.mPrevMethodState = declMethodState;//mCurMethodState; - BfIRFunctionType funcType; + BfIRFunctionType funcType; auto voidType = GetPrimitiveType(BfTypeCode_None); SizedArray paramTypes; - funcType = mBfIRBuilder->CreateFunctionType(mBfIRBuilder->MapType(voidType), paramTypes, methodInstance->IsVarArgs()); + funcType = mBfIRBuilder->CreateFunctionType(mBfIRBuilder->MapType(voidType), paramTypes, methodInstance->IsVarArgs()); mBfIRBuilder->SaveDebugLocation(); auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); @@ -21970,23 +22473,23 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth //TODO: Why did we do this? It can cause us to pull in local variables that don't belong to us... /*if (declMethodState->mDeferredLocalAssignData != NULL) deferredLocalAssignData.ExtendFrom(declMethodState->mDeferredLocalAssignData);*/ - SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); + SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); - methodState.mIRHeadBlock = mBfIRBuilder->CreateBlock("head", true); - methodState.mIRInitBlock = mBfIRBuilder->CreateBlock("init", true); - methodState.mIREntryBlock = mBfIRBuilder->CreateBlock("entry", true); + methodState.mIRHeadBlock = mBfIRBuilder->CreateBlock("head", true); + methodState.mIRInitBlock = mBfIRBuilder->CreateBlock("init", true); + methodState.mIREntryBlock = mBfIRBuilder->CreateBlock("entry", true); methodState.mCurScope->mDIScope = localMethod->mDeclDIScope; //declMethodState->mCurScope->mDIScope ; //methodState.mCurLocalVarId = declMethodState->mCurLocalVarId; methodState.mIRFunction = declMethodState->mIRFunction; methodState.mDeferredLocalAssignData = &deferredLocalAssignData; - + if (auto blockBody = BfNodeDynCast(body)) { methodState.mCurScope->mAstBlock = blockBody; methodState.mCurScope->mCloseNode = blockBody->mCloseBrace; } - mBfIRBuilder->SetInsertPoint(methodState.mIREntryBlock); + mBfIRBuilder->SetInsertPoint(methodState.mIREntryBlock); BfClosureState closureState; if (methodDef->mMethodType == BfMethodType_Mixin) @@ -21999,17 +22502,17 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth closureState.mReturnType = declMethodState->mMethodInstance->mReturnType; } } - + if (closureState.mReturnType == NULL) closureState.mReturnType = _SafeResolveTypeRef(methodDef->mReturnTypeRef); - closureState.mCapturing = true; + closureState.mCapturing = true; closureState.mLocalMethod = localMethod; closureState.mClosureInstanceInfo = methodInstance->mMethodInfoEx->mClosureInstanceInfo; closureState.mDeclaringMethodIsMutating = mCurMethodInstance->mMethodDef->mIsMutating; methodState.mClosureState = &closureState; closureState.mClosureType = outerClosure; - - int outerLocalsCount = (int)methodState.mLocals.size(); + + int outerLocalsCount = (int)methodState.mLocals.size(); if (!hadExistingMethodInstance) { @@ -22043,7 +22546,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth BF_ASSERT(methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState == NULL); - closureState.mCaptureStartAccessId = mCurMethodState->GetRootMethodState()->mCurAccessId; + closureState.mCaptureStartAccessId = mCurMethodState->GetRootMethodState()->mCurAccessId; methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState = &closureState; closureState.mClosureMethodDef = methodDef; @@ -22055,7 +22558,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth bool allowCapture = (methodDeclaration == NULL) || (methodDeclaration->mStaticSpecifier == NULL); if (wantsVisitBody) - { + { BP_ZONE("VisitLambdaBody"); // For generic methods, we capture for each specialization, so make sure mIsStatic is set to 'true' for @@ -22066,16 +22569,16 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth // Only generate errors once. Also there are some errors that will occur during this scanning phase // that will not occur during the actual lambda method generation, for example: returning a value // when our current method is a 'void' method. This shouldn't affect capture scanning since all - // our AST nodes will still be visited + // our AST nodes will still be visited SetAndRestoreValue ignoreError(mIgnoreErrors, true); - */ + */ SetAndRestoreValue prevMethodInstance(mCurMethodInstance, methodInstance); - + //SetAndRestoreValue wantsIgnoreWrites(mWantsISIgnoreWrites, true); mBfIRBuilder->SaveDebugLocation(); closureState.mCaptureVisitingBody = true; - - BF_ASSERT(methodInstance->mMethodInfoEx != NULL); + + BF_ASSERT(methodInstance->mMethodInfoEx != NULL); methodState.mGenericTypeBindings = &methodInstance->mMethodInfoEx->mGenericTypeBindings; methodState.mMethodInstance = methodInstance; @@ -22092,11 +22595,21 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth } } - // Keep outs for being marked as assigned + // Keep outs from being marked as assigned auto rootMethodState = mCurMethodState->GetRootMethodState(); - BfDeferredLocalAssignData deferredLocalAssignData(rootMethodState->mCurScope); + BfDeferredLocalAssignData deferredLocalAssignData(rootMethodState->mCurScope); deferredLocalAssignData.mVarIdBarrier = rootMethodState->mCurLocalVarId; - SetAndRestoreValue prevDLA(rootMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); + + auto prevDLA = rootMethodState->mDeferredLocalAssignData; + while ((prevDLA != NULL) && (prevDLA->mIsChained)) + prevDLA = prevDLA->mChainedAssignData; + if (prevDLA != NULL) + { + deferredLocalAssignData.mAssignedLocals = prevDLA->mAssignedLocals; + deferredLocalAssignData.mLeftBlockUncond = prevDLA->mLeftBlockUncond; + } + + SetAndRestoreValue sarDLA(rootMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); if (!mIgnoreErrors) localMethod->mDidBodyErrorPass = true; @@ -22119,23 +22632,23 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth // can be used by these methods (which will be necessary if any of these methods call us directly or indirectly) closureState.mClosureMethodDef = NULL; for (auto methodInstance : closureState.mLocalMethodRefs) - { + { GetLocalMethodInstance(methodInstance->mMethodInfoEx->mClosureInstanceInfo->mLocalMethod, BfTypeVector(), methodInstance); } methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureClosureState = NULL; prevIgnoreWrites.Restore(); - + std::multiset capturedEntries; - - // + + // { auto varMethodState = declMethodState; while (varMethodState != NULL) { if ((varMethodState->mMixinState != NULL) && (varMethodState->mMixinState->mLastTargetAccessId >= closureState.mCaptureStartAccessId)) - { + { BF_ASSERT(methodInstance->GetOwner() == varMethodState->mMixinState->mTarget.mType); methodDef->mIsStatic = false; if (rootMethodState->mMethodInstance->mMethodDef->mIsMutating) @@ -22221,23 +22734,23 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth } varMethodState = varMethodState->mPrevMethodState; - if ((varMethodState == NULL) || - (varMethodState->mMixinState != NULL) || + if ((varMethodState == NULL) || + (varMethodState->mMixinState != NULL) || ((varMethodState->mClosureState != NULL) && (!varMethodState->mClosureState->mCapturing))) break; } } - + for (auto& copyField : closureState.mReferencedOuterClosureMembers) - { + { auto fieldDef = copyField->GetFieldDef(); BfClosureCapturedEntry capturedEntry; - capturedEntry.mName = copyField->GetFieldDef()->mName; + capturedEntry.mName = copyField->GetFieldDef()->mName; capturedEntry.mType = copyField->mResolvedType; if (capturedEntry.mType->IsRef()) { // Keep by ref - } + } else if (!fieldDef->mIsReadOnly) { capturedEntry.mType = CreateRefType(capturedEntry.mType); @@ -22249,15 +22762,15 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth int captureIdx = 0; for (auto& capturedEntry : capturedEntries) { - methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.Add(capturedEntry); - } + methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.Add(capturedEntry); + } /*if (isDefaultPass) - { + { // Insert captured members a params at the start. If we added at the end then it would screw up varargs methods int captureIdx = 0; for (auto& capturedEntry : capturedEntries) - { + { methodInstance->mClosureInstanceInfo->mCaptureNodes.Add(BfNodeDynCast(capturedEntry.mNameNode)); BfParameterDef* paramDef = new BfParameterDef(); @@ -22295,7 +22808,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth methodInstance->mDisallowCalling = false; BfLogSysM("LocalMethod %p UndoingDeclaration %p\n", localMethod, methodInstance); - } + } auto declareModule = this; SetAndRestoreValue prevMethodInstance(declareModule->mCurMethodInstance, methodInstance); @@ -22304,15 +22817,15 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth methodInstance->mDeclModule = declareModule; _SetupMethodInstance(); BfLogSysM("LocalMethod %p DoMethodDeclaration %p\n", localMethod, methodInstance); - declareModule->DoMethodDeclaration(localMethod->mMethodDef->GetMethodDeclaration(), false, false); - + declareModule->DoMethodDeclaration(localMethod->mMethodDef->GetMethodDeclaration(), false, false); + closureState.mReturnType = methodInstance->mReturnType; mCompiler->mStats.mMethodsQueued++; mCompiler->UpdateCompletion(); declareModule->mIncompleteMethodCount++; - mCompiler->mStats.mMethodsProcessed++; + mCompiler->mStats.mMethodsProcessed++; if (!methodInstance->mIsReified) - mCompiler->mStats.mUnreifiedMethodsProcessed++; + mCompiler->mStats.mUnreifiedMethodsProcessed++; auto deferMethodState = rootMethodState; @@ -22384,9 +22897,9 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth } } } - + checkMethodState = checkMethodState->mPrevMethodState; - } + } } return BfModuleMethodInstance(methodInstance); @@ -22409,7 +22922,7 @@ int BfModule::GetLocalInferrableGenericArgCount(BfMethodDef* methodDef) BfLocalMethod* callerLocalMethod = mCurMethodInstance->mMethodInfoEx->mClosureInstanceInfo->mLocalMethod; if (callerLocalMethod == NULL) - return rootMethodGenericParamCount; + return rootMethodGenericParamCount; BfLocalMethod* calledLocalMethod = NULL; rootMethodState->mLocalMethodCache.TryGetValue(methodDef->mName, &calledLocalMethod); @@ -22419,22 +22932,25 @@ int BfModule::GetLocalInferrableGenericArgCount(BfMethodDef* methodDef) if (calledLocalMethod->mOuterLocalMethod == callerLocalMethod) return (int)callerLocalMethod->mMethodDef->mGenericParams.size(); callerLocalMethod = calledLocalMethod->mOuterLocalMethod; - } + } return rootMethodGenericParamCount; } void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance) { auto methodDef = methodInstance->mMethodDef; - - auto customAttributes = methodInstance->GetCustomAttributes(); + + auto customAttributes = methodInstance->GetCustomAttributes(); if (customAttributes != NULL) return; - + auto methodDeclaration = methodDef->GetMethodDeclaration(); auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration(); auto typeInstance = methodInstance->GetOwner(); + if (typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef)) + return; + BfTypeState typeState(typeInstance); SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); @@ -22465,10 +22981,10 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance) methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes; methodInstance->mMethodInstanceGroup->mDefaultCustomAttributes = NULL; } - else - methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = GetCustomAttributes(attributeDirective, attrTarget); + else + methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = GetCustomAttributes(attributeDirective, attrTarget); } - + if ((propertyMethodDeclaration != NULL) && (propertyMethodDeclaration->mPropertyDeclaration->mAttributes != NULL) && ((attrTarget & BfAttributeTargets_Property) == 0)) { if (methodInstance->GetMethodInfoEx()->mMethodCustomAttributes != NULL) @@ -22481,7 +22997,7 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance) methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = GetCustomAttributes(propertyMethodDeclaration->mPropertyDeclaration->mAttributes, BfAttributeTargets_Property); } } - + customAttributes = methodInstance->GetCustomAttributes(); if (customAttributes == NULL) { @@ -22528,7 +23044,7 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance) } } } - + auto delegateInfo = typeInstance->GetDelegateInfo(); if ((delegateInfo != NULL) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Normal) && (methodInstance->mMethodDef->mName == "Invoke")) methodInstance->mCallingConvention = delegateInfo->mCallingConvention; @@ -22615,12 +23131,12 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man if (takeover) mCurMethodInstance->mIRFunction = prevFunc; - + if (!mCurMethodInstance->mIRFunction) { BfLogSysM("Function collision from inner override erased prevFunc %p: %d\n", methodInstance, prevFunc.mId); if (!mIsComptimeModule) - mBfIRBuilder->Func_SafeRename(prevFunc); + mBfIRBuilder->Func_SafeRenameFrom(prevFunc, mangledName); } } else if (methodDef->mIsExtern) @@ -22632,7 +23148,7 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man { // We can have a collision of names when we have generic methods that differ only in // their constraints, but they should only collide in their unspecialized form - // since only one will be chosen for a given concrete type + // since only one will be chosen for a given concrete type if (!mIsComptimeModule) mCurMethodInstance->mMangleWithIdx = true; mangledName.Clear(); @@ -22645,7 +23161,7 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man { BfLogSysM("Function collision erased prevFunc %p: %d\n", methodInstance, prevFunc.mId); if (!mIsComptimeModule) - mBfIRBuilder->Func_SafeRename(prevFunc); + mBfIRBuilder->Func_SafeRenameFrom(prevFunc, mangledName); } } } @@ -22696,14 +23212,14 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man if (!methodInstance->mIRFunction) { BfIRFunction func; - bool wantsLLVMFunc = ((!typeInstance->IsUnspecializedType() || (mIsComptimeModule)) && + bool wantsLLVMFunc = ((!typeInstance->IsUnspecializedType() || (mIsComptimeModule)) && (!methodDef->IsEmptyPartial())) && (funcType); /*if (mCurTypeInstance->mTypeDef->mName->ToString() == "ClassA") { if (!mIsReified) wantsLLVMFunc = false; - }*/ + }*/ if (wantsLLVMFunc) { @@ -22740,53 +23256,55 @@ void BfModule::CheckHotMethod(BfMethodInstance* methodInstance, const StringImpl { if (methodInstance->mHotMethod != NULL) return; - + if ((mCompiler->mOptions.mAllowHotSwapping) && (!methodInstance->mIsUnspecialized)) - { + { auto srcTypeInst = methodInstance->GetOwner(); - + if (srcTypeInst->mHotTypeData == NULL) + return; + StringT<128> mangledName = inMangledName; if (mangledName.IsEmpty()) BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), methodInstance); - + // We always keep the current primary method at the same address BfHotMethod* hotMethod; BfHotMethod** hotMethodPtr; if (mCompiler->mHotData->mMethodMap.TryAdd(mangledName, NULL, &hotMethodPtr)) - { + { hotMethod = new BfHotMethod(); *hotMethodPtr = hotMethod; - hotMethod->mRefCount = 1; + hotMethod->mRefCount = 1; hotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_IsBound); #ifdef BF_DBG_HOTMETHOD_IDX static int sMethodIdx = 0; hotMethod->mMethodIdx = sMethodIdx++; #endif - + BfLogSysM("HotMethodData %p created for method %p %s - %s\n", hotMethod, methodInstance, MethodToString(methodInstance).c_str(), mangledName.c_str()); } else - { + { hotMethod = *hotMethodPtr; if ((hotMethod->mFlags & BfHotDepDataFlag_IsBound) != 0) { // This is a duplicate mangled name - we link to this new entry via a 'BfHotDupMethod' auto prevHotMethod = *hotMethodPtr; - - hotMethod = new BfHotMethod(); + + hotMethod = new BfHotMethod(); hotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_IsBound); - + BfHotDupMethod* hotDupMethod = new BfHotDupMethod(hotMethod); hotDupMethod->mRefCount++; prevHotMethod->mReferences.Add(hotDupMethod); - prevHotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_HasDup); + prevHotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_HasDup); BfLogSysM("HotMethodData %p (duplicate of %p) created for method %p %s - %s\n", hotMethod, prevHotMethod, methodInstance, MethodToString(methodInstance).c_str(), mangledName.c_str()); } else if (mCompiler->IsHotCompile()) { - // Link the previous version into the mPrevVersion + // Link the previous version into the mPrevVersion BfHotMethod* prevMethod = new BfHotMethod(); prevMethod->mRefCount = 1; prevMethod->mPrevVersion = hotMethod->mPrevVersion; @@ -22803,20 +23321,20 @@ void BfModule::CheckHotMethod(BfMethodInstance* methodInstance, const StringImpl BfLogSysM("HotMethodData %p created for prevmethod of %p for method %p %s\n", prevMethod, hotMethod, methodInstance, MethodToString(methodInstance).c_str()); } else - { + { BfLogSysM("HotMethodData %p used for method %p %s - %s\n", hotMethod, methodInstance, MethodToString(methodInstance).c_str(), mangledName.c_str()); hotMethod->Clear(true); hotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_IsBound); } - } + } if (methodInstance->mIsClosure) { hotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_RetainMethodWithoutBinding); } - + hotMethod->mSrcTypeVersion = srcTypeInst->mHotTypeData->GetLatestVersion(); - hotMethod->mSrcTypeVersion->mRefCount++; + hotMethod->mSrcTypeVersion->mRefCount++; hotMethod->mRefCount++; #ifdef BF_DBG_HOTMETHOD_NAME hotMethod->mMangledName = mangledName; @@ -22824,7 +23342,7 @@ void BfModule::CheckHotMethod(BfMethodInstance* methodInstance, const StringImpl if ((methodInstance->mMethodInstanceGroup->IsImplemented()) && (!IsHotCompile())) hotMethod->mFlags = (BfHotDepDataFlags)(hotMethod->mFlags | BfHotDepDataFlag_IsOriginalBuild); - methodInstance->mHotMethod = hotMethod; + methodInstance->mHotMethod = hotMethod; } } @@ -22900,7 +23418,7 @@ void BfModule::StartMethodDeclaration(BfMethodInstance* methodInstance, BfMethod methodInstance->mIsUnspecializedVariation = true; methodInstance->mIsUnspecialized = true; } - + if (methodInstance->mIsUnspecializedVariation) BF_ASSERT(methodInstance->mIsUnspecialized); @@ -22918,46 +23436,46 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { BF_ASSERT((mCompiler->mCeMachine == NULL) || (!mCompiler->mCeMachine->mDbgPaused)); - BP_ZONE("BfModule::DoMethodDeclaration"); + BP_ZONE("BfModule::DoMethodDeclaration"); // We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here // to effectively make mIgnoreWrites method-scoped SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites || mCurMethodInstance->mIsUnspecialized || mCurTypeInstance->mResolvingVarField); - SetAndRestoreValue prevIsCapturingMethodMatchInfo; + SetAndRestoreValue prevIsCapturingMethodMatchInfo; SetAndRestoreValue prevAllowLockYield(mContext->mAllowLockYield, false); BfTypeState typeState(mCurTypeInstance); SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - - if (mCompiler->IsAutocomplete()) + + if (mCompiler->IsAutocomplete()) prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false); - + if (mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) mCurMethodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingReference; BfMethodState methodState; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); methodState.mTempKind = BfMethodState::TempKind_Static; - + defer({ mCurMethodInstance->mHasBeenDeclared = true; }); // If we are doing this then we may end up creating methods when var types are unknown still, failing on splat/zero-sized info BF_ASSERT((!mCurTypeInstance->mResolvingVarField) || (mBfIRBuilder->mIgnoreWrites)); bool ignoreWrites = mBfIRBuilder->mIgnoreWrites; - + // if ((!isTemporaryFunc) && (mCurTypeInstance->mDefineState < BfTypeDefineState_Defined)) // { // BF_ASSERT(mContext->mResolvingVarField); // isTemporaryFunc = true; // } - + if ((mAwaitingInitFinish) && (!mBfIRBuilder->mIgnoreWrites)) FinishInit(); auto typeInstance = mCurTypeInstance; - auto typeDef = typeInstance->mTypeDef; - auto methodDef = mCurMethodInstance->mMethodDef; - + auto typeDef = typeInstance->mTypeDef; + auto methodDef = mCurMethodInstance->mMethodDef; + BF_ASSERT(methodDef->mName != "__ASSERTNAME"); if (methodDef->mName == "__FATALERRORNAME") BFMODULE_FATAL(this, "__FATALERRORNAME"); @@ -22965,16 +23483,16 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool StackOverflow(); if (typeInstance->IsClosure()) - { + { if (methodDef->mName == "Invoke") return; } - auto methodInstance = mCurMethodInstance; + auto methodInstance = mCurMethodInstance; if ((methodInstance->IsSpecializedByAutoCompleteMethod()) || (mCurTypeInstance->IsFunction())) addToWorkList = false; - + if (!methodInstance->mHasStartedDeclaration) StartMethodDeclaration(methodInstance, prevMethodState.mPrevVal); @@ -23010,8 +23528,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool else genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); } - - ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized, &deferredResolveTypes); + + ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized, &deferredResolveTypes); if (genericParamIdx < (int)methodDef->mGenericParams.size()) { @@ -23105,16 +23623,16 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool continue; if (!CompareMethodSignatures(defaultMethod, methodInstance)) continue; - + autoComplete->SetDefinitionLocation(defaultMethod->mMethodDef->GetRefNode(), true); autoComplete->mDefType = typeInstance->mTypeDef; - autoComplete->mDefMethod = defaultMethod->mMethodDef; + autoComplete->mDefMethod = defaultMethod->mMethodDef; } } } } } - + bool reportErrors = true; if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) reportErrors = true; @@ -23133,7 +23651,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { BfAstNode* refNode = methodDeclaration; if (refNode == NULL) - { + { // Whatever caused this ctor to be generated should have caused another failure // But that failure might not be generated until the ctor is generated } @@ -23165,10 +23683,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if ((((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) || (methodInstance->mIsAutocompleteMethod)) && (methodDef->mReturnTypeRef->IsA())) - resolvedReturnType = GetPrimitiveType(BfTypeCode_Var); + resolvedReturnType = GetPrimitiveType(BfTypeCode_Var); else - resolvedReturnType = ResolveTypeRef(methodDef->mReturnTypeRef, BfPopulateType_Declaration, flags); - + resolvedReturnType = ResolveTypeRef(methodDef->mReturnTypeRef, BfPopulateType_Declaration, flags); + if (resolvedReturnType == NULL) resolvedReturnType = GetPrimitiveType(BfTypeCode_Var); @@ -23183,16 +23701,16 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { resolvedReturnType = ResolveTypeDef(mSystem->mTypeVoid); } - - BF_ASSERT(resolvedReturnType != NULL); - mCurMethodInstance->mReturnType = resolvedReturnType; - - //TODO: We used to NOT add the return value dependency for specialized methods, but when we have types that are + + BF_ASSERT(resolvedReturnType != NULL); + mCurMethodInstance->mReturnType = resolvedReturnType; + + //TODO: We used to NOT add the return value dependency for specialized methods, but when we have types that are // specialized based on the method's generic param then they can get deleted if no one else has referred to them (yet) //if (!methodInstance->IsSpecializedGenericMethod()) - + AddDependency(resolvedReturnType, typeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue); - + if (methodDef->mExplicitInterface != NULL) { auto autoComplete = mCompiler->GetAutoComplete(); @@ -23204,7 +23722,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if (explicitType != NULL) explicitInterface = explicitType->ToTypeInstance(); if (explicitInterface != NULL) - { + { mCurMethodInstance->GetMethodInfoEx()->mExplicitInterface = explicitInterface->ToTypeInstance(); if (autoComplete != NULL) { @@ -23215,7 +23733,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool dotToken = methodDeclaration->mExplicitInterfaceDotToken; nameNode = methodDeclaration->mNameNode; } - + autoComplete->CheckExplicitInterface(explicitInterface, dotToken, nameNode); } } @@ -23225,7 +23743,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool for (auto ifaceInst : typeInstance->mInterfaces) interfaceFound |= ifaceInst.mInterfaceType == mCurMethodInstance->mMethodInfoEx->mExplicitInterface; if ((!interfaceFound) && (!typeInstance->mTypeFailed)) - { + { if (methodDef->mMethodDeclaration != NULL) Fail("Containing class has not declared to implement this interface", methodDef->mMethodDeclaration); else @@ -23233,13 +23751,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool // For property decls, we should have already given the error during type population if (mCompiler->mRevision == 1) AssertErrorState(); - } + } } } } bool isThisStruct = mCurTypeInstance->IsStruct(); - BfType* thisType = NULL; + BfType* thisType = NULL; if ((!methodDef->mIsStatic) && (!mCurTypeInstance->IsValuelessType())) { @@ -23248,31 +23766,30 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool thisType = mCurTypeInstance; if (thisType == NULL) return; - + if ((thisType->IsSplattable()) && (!methodDef->HasNoThisSplat())) { - BfTypeUtils::SplatIterate([&](BfType* checkType) - { - PopulateType(checkType, BfPopulateType_Data); + BfTypeUtils::SplatIterate([&](BfType* checkType) + { + PopulateType(checkType, BfPopulateType_Data); }, thisType); - } + } } else { thisType = mCurTypeInstance; - PopulateType(thisType, BfPopulateType_Declaration); - } + PopulateType(thisType, BfPopulateType_Declaration); + } } - + int implicitParamCount = 0; if ((mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mClosureInstanceInfo != NULL)) implicitParamCount = (int)methodInstance->mMethodInfoEx->mClosureInstanceInfo->mCaptureEntries.size(); methodInstance->mMethodDef->mParams.Reserve((int)methodDef->mParams.size()); - bool hadDelegateParams = false; - bool hadParams = false; + bool hadParams = false; for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size() + implicitParamCount; paramIdx++) { BfClosureCapturedEntry* closureCaptureEntry = NULL; @@ -23323,15 +23840,15 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } else if ((paramDef->mTypeRef != NULL) && (paramDef->mTypeRef->IsA())) { - if (methodDef->mMethodType != BfMethodType_Mixin) + if (methodDef->mMethodType != BfMethodType_Mixin) { Fail("Cannot declare var parameters", paramDef->mTypeRef); resolvedParamType = mContext->mBfObjectType; } else resolvedParamType = GetPrimitiveType(BfTypeCode_Var); - } - + } + BfType* unresolvedParamType = resolvedParamType; bool wasGenericParam = false; if (resolvedParamType == NULL) @@ -23351,15 +23868,15 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { auto boxedType = (BfBoxedType*)mCurTypeInstance; // If we failed a lookup here then we better have also failed it in the original type - BF_ASSERT(boxedType->mElementType->ToTypeInstance()->mModule->mHadBuildError || mContext->mFailTypes.Contains(boxedType->mElementType->ToTypeInstance())); + BF_ASSERT(boxedType->mElementType->ToTypeInstance()->mModule->mHadBuildError || mContext->mFailTypes.ContainsKey(boxedType->mElementType->ToTypeInstance())); } } - + BF_ASSERT(!resolvedParamType->IsDeleting()); if (!methodInstance->IsSpecializedGenericMethod()) AddDependency(resolvedParamType, typeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue); - PopulateType(resolvedParamType, BfPopulateType_Declaration); + PopulateType(resolvedParamType, BfPopulateType_Declaration); AddDependency(resolvedParamType, mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage); @@ -23373,7 +23890,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool refNode = paramDef->mParamDeclaration->mModToken; Fail("Cannot specify a default value for a 'params' parameter", refNode); } - + BfTypedValue defaultValue; if (resolvedParamType->IsConstExprValue()) { @@ -23442,7 +23959,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } if ((paramDef != NULL) && (paramDef->mParamKind == BfParamKind_Params)) - { + { bool addParams = true; bool isValid = false; @@ -23455,7 +23972,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } else if (resolvedParamType->IsArray()) { - // Array is the 'normal' params type + // Array is the 'normal' params type isValid = true; } else if (resolvedParamType->IsSizedArray()) @@ -23466,7 +23983,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { isValid = true; } - else if ((resolvedParamType->IsDelegate()) || (resolvedParamType->IsFunction())) + else if ((resolvedParamType->IsDelegate()) || (resolvedParamType->IsFunction()) || (resolvedParamType->IsMethodRef())) { hadDelegateParams = true; @@ -23483,7 +24000,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto paramType = invokeMethodInstance->GetParamType(delegateParamIdx); if (!methodInstance->IsSpecializedGenericMethod()) - AddDependency(paramType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + AddDependency(paramType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ParamOrReturnValue); } isValid = true; addParams = false; @@ -23496,16 +24013,16 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto typeInstConstraint = genericParamInstance->mTypeConstraint->ToTypeInstance(); if ((genericParamInstance->mTypeConstraint->IsArray()) || (genericParamInstance->mTypeConstraint->IsSizedArray())) { - BfMethodParam methodParam; + BfMethodParam methodParam; methodParam.mResolvedType = resolvedParamType; - methodParam.mParamDefIdx = paramDefIdx; + methodParam.mParamDefIdx = paramDefIdx; mCurMethodInstance->mParams.Add(methodParam); isValid = true; } else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) || ((genericParamInstance != NULL) && (typeInstConstraint != NULL) && ((typeInstConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (typeInstConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef))))) - { + { mCurMethodInstance->mHadGenericDelegateParams = true; isValid = true; addParams = false; @@ -23523,7 +24040,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool addParams = false; } } - + if (!isValid) { Fail("Parameters with 'params' specifiers can only be used for array, span, delegate, or function types", paramDef->mParamDeclaration->mModToken); @@ -23533,22 +24050,22 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if ((addParams) && (resolvedParamType != NULL)) { - BfMethodParam methodParam; + BfMethodParam methodParam; methodParam.mResolvedType = resolvedParamType; - methodParam.mParamDefIdx = paramDefIdx; + methodParam.mParamDefIdx = paramDefIdx; mCurMethodInstance->mParams.push_back(methodParam); } if (paramDefIdx < (int)methodDef->mParams.size() - 1) - { + { Fail("Only the last parameter can specify 'params'", paramDef->mParamDeclaration->mModToken); } } else { - BfMethodParam methodParam; + BfMethodParam methodParam; methodParam.mResolvedType = resolvedParamType; - methodParam.mParamDefIdx = paramDefIdx; + methodParam.mParamDefIdx = paramDefIdx; mCurMethodInstance->mParams.Add(methodParam); } } @@ -23561,7 +24078,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { usedNames.Add(methodParam->mName); } - + for (auto& methodParam : mCurMethodInstance->mParams) { if ((methodParam.mParamDefIdx != -1) && (methodParam.mDelegateParamIdx == 0)) @@ -23575,7 +24092,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool for (auto& methodParam : mCurMethodInstance->mParams) { if (methodParam.mDelegateParamIdx != -1) - { + { if (usedParamDefIdx[methodParam.mParamDefIdx] > 1) methodParam.mDelegateParamNameCombine = true; BfMethodInstance* invokeMethodInstance = methodParam.GetDelegateParamInvoke(); @@ -23587,10 +24104,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } int argIdx = 0; - PopulateType(methodInstance->mReturnType, BfPopulateType_Data); + PopulateType(methodInstance->mReturnType, BfPopulateType_Data); if ((!methodDef->mIsStatic) && (!methodDef->mHasExplicitThis)) { - int thisIdx = methodDef->mHasExplicitThis ? 0 : -1; + int thisIdx = methodDef->mHasExplicitThis ? 0 : -1; auto thisType = methodInstance->GetOwner(); if (methodInstance->GetParamIsSplat(thisIdx)) argIdx += methodInstance->GetParamType(thisIdx)->GetSplatCount(); @@ -23633,7 +24150,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool bool isSplat = false; auto checkTypeInstance = checkType->ToTypeInstance(); if ((checkTypeInstance != NULL) && (checkTypeInstance->mIsCRepr)) - isSplat = true; + isSplat = true; int splatCount = checkType->GetSplatCount(); if (checkArgIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs) isSplat = true; @@ -23647,7 +24164,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool else if (!checkType->IsValuelessType()) { BfTypeCode loweredTypeCode = BfTypeCode_None; - BfTypeCode loweredTypeCode2 = BfTypeCode_None; + BfTypeCode loweredTypeCode2 = BfTypeCode_None; if (!mIsComptimeModule) checkType->GetLoweredType(BfTypeUsage_Parameter, &loweredTypeCode, &loweredTypeCode2); argIdx++; @@ -23655,8 +24172,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool argIdx++; continue; } - } - + } + argIdx++; } @@ -23674,7 +24191,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { if (auto autoCtorDecl = BfNodeDynCast(methodDeclaration)) { - // + // } else AssertParseErrorState(); @@ -23692,7 +24209,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if (((methodInstance->mReturnType == typeInstance) && (methodInstance->GetParamType(0) == typeInstance->GetUnderlyingType())) || ((methodInstance->mReturnType == typeInstance->GetUnderlyingType()) && (methodInstance->GetParamType(0) == typeInstance))) { - isError = false; + isError = false; } } } @@ -23720,10 +24237,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool BF_ASSERT((actualParamCount == defaultMethodInstance->mParams.size() - defaultImplicitParamCount) || (defaultMethodInstance->mHadGenericDelegateParams)); mCurMethodInstance->mHadGenericDelegateParams = defaultMethodInstance->mHadGenericDelegateParams; - + int paramIdx = 0; int defaultParamIdx = 0; - + while (true) { bool isDone = paramIdx + implicitParamCount >= (int)methodInstance->mParams.size(); @@ -23733,8 +24250,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { paramIdx++; continue; - } - + } + if ((!isDefaultDone) && (defaultMethodInstance->mParams[defaultParamIdx + defaultImplicitParamCount].mDelegateParamIdx >= 0)) { defaultParamIdx++; @@ -23743,22 +24260,22 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if ((isDone) || (isDefaultDone)) { - // If we have generic delegate params, it's possible we will fail constraints later if we specialize with an invalid type, but we can't allow that + // If we have generic delegate params, it's possible we will fail constraints later if we specialize with an invalid type, but we can't allow that // to cause us to throw an assertion in the declaration here - if (!defaultMethodInstance->mHadGenericDelegateParams) + if ((!defaultMethodInstance->mHadGenericDelegateParams) && (!methodInstance->mHasFailed) && (!defaultMethodInstance->mHasFailed)) BF_ASSERT((isDone) && (isDefaultDone)); break; - } + } BfType* paramType = defaultMethodInstance->mParams[defaultParamIdx + defaultImplicitParamCount].mResolvedType; if (paramType->IsRef()) paramType = paramType->GetUnderlyingType(); - methodInstance->mParams[paramIdx + implicitParamCount].mWasGenericParam = paramType->IsGenericParam(); + methodInstance->mParams[paramIdx + implicitParamCount].mWasGenericParam = paramType->IsGenericParam(); paramIdx++; defaultParamIdx++; - } + } } StringT<4096> mangledName; @@ -23768,7 +24285,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { auto paramType = methodInstance->GetParamType(paramIdx); if (paramType->IsComposite()) - PopulateType(paramType, BfPopulateType_Data); + PopulateType(paramType, BfPopulateType_Data); if (!methodInstance->IsParamSkipped(paramIdx)) { @@ -23781,7 +24298,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool PopulateType(paramType, BfPopulateType_Declaration); } } - } + } // Only process method in default unspecialized mode, not in variations if (methodInstance->mIsUnspecializedVariation) @@ -23810,7 +24327,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto func = methodInstance->mIRFunction; // if (methodInstance->mIsReified) -// CheckHotMethod(methodInstance, mangledName); +// CheckHotMethod(methodInstance, mangledName); for (auto& param : methodInstance->mParams) { @@ -23818,10 +24335,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } BfLogSysM("DoMethodDeclaration %s Module: %p Type: %p MethodInst: %p Reified: %d Unspecialized: %d IRFunction: %d MethodId:%llx\n", mangledName.c_str(), this, mCurTypeInstance, methodInstance, methodInstance->mIsReified, mCurTypeInstance->IsUnspecializedType(), methodInstance->mIRFunction.mId, methodInstance->mIdHash); - - SizedArray diParams; - diParams.push_back(mBfIRBuilder->DbgGetType(resolvedReturnType)); - + + SizedArray diParams; + diParams.push_back(mBfIRBuilder->DbgGetType(resolvedReturnType)); + if ((!methodDef->mIsStatic) && (typeDef->mIsStatic) && (methodDef->mMethodDeclaration != NULL)) { //CS0708 @@ -23862,7 +24379,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool else if (methodDef->mMethodType == BfMethodType_Dtor) Warn(0, "Unnecessary 'mut' specifier, destructors are implicitly mutating", mutSpecifier); } - + if (isTemporaryFunc) { // This handles temporary methods for autocomplete types @@ -23872,13 +24389,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool return; // Bail out early for autocomplete pass } - //TODO: We used to have this (this != mContext->mExternalFuncModule) check, but it caused us to keep around + //TODO: We used to have this (this != mContext->mExternalFuncModule) check, but it caused us to keep around // an invalid mFuncRefernce (which came from GetMethodInstanceAtIdx) which later got remapped by the // autocompleter. Why did we have this check anyway? /*if ((typeInstance->mContext != mContext) && (!methodDef->IsEmptyPartial())) { AddMethodReference(methodInstance); - mFuncReferences[methodInstance] = func; + mFuncReferences[methodInstance] = func; BfLogSysM("Adding func reference (DoMethodDeclaration). Module:%p MethodInst:%p LLVMFunc:%p\n", this, methodInstance, func); }*/ @@ -23892,14 +24409,14 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool mFuncReferences[methodInstance] = func; } } - + if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) { methodInstance->mMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl; auto owningModule = methodInstance->GetOwner()->mModule; if (!owningModule->mIsScratchModule) owningModule->mOnDemandMethodCount++; - VerifyOnDemandMethods(); + VerifyOnDemandMethods(); } bool wasAwaitingDecl = methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl; @@ -23909,11 +24426,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if (addToWorkList) { if ((!methodDef->mIsAbstract) && (!methodInstance->mIgnoreBody)) - { + { AddMethodToWorkList(methodInstance); } else - { + { BfLogSysM("DoMethodDeclaration ignoring method body %d %d %d\n", hasExternSpecifier, methodDef->mIsAbstract, methodInstance->mIgnoreBody); methodInstance->mIgnoreBody = true; @@ -23923,13 +24440,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool methodInstance->mIRFunction = BfIRFunction(); } } - } + } else { //BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference); } - - if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) && + + if ((!methodInstance->IsSpecializedGenericMethodOrType()) && (!mCurTypeInstance->IsBoxed()) && (!methodDef->mIsLocalMethod) && (!CheckDefineMemberProtection(methodDef->mProtection, methodInstance->mReturnType)) && (!methodDef->mReturnTypeRef->IsTemporary())) @@ -23948,9 +24465,9 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool Fail(StrFormat("Inconsistent accessibility: return type '%s' is less accessible than method '%s'", TypeToString(methodInstance->mReturnType).c_str(), MethodToString(methodInstance).c_str()), methodDef->mReturnTypeRef, true); - } + } } - + if (typeInstance->IsInterface()) { if (methodDef->mMethodType == BfMethodType_Ctor) @@ -23961,7 +24478,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { if (methodDef->mProtection != BfProtection_Public) //TODO: MAKE AN ERROR Warn(0, "Protection specifiers can only be used with interface methods containing a default implementation body", methodDeclaration->mProtectionSpecifier); - if ((methodDeclaration->mVirtualSpecifier != NULL) && + if ((methodDeclaration->mVirtualSpecifier != NULL) && (methodDeclaration->mVirtualSpecifier->mToken != BfToken_Abstract) && (methodDeclaration->mVirtualSpecifier->mToken != BfToken_Concrete)) //TODO: MAKE AN ERROR Warn(0, "Virtual specifiers can only be used with interface methods containing a default implementation body", methodDeclaration->mVirtualSpecifier); @@ -23989,7 +24506,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool BfMemberSetEntry* entry = NULL; if (typeDef->mMethodSet.TryGet(BfMemberSetEntry(methodDef), &entry)) nextMethod = (BfMethodDef*)entry->mMemberDef; - + while (nextMethod != NULL) { auto checkMethod = nextMethod; @@ -23998,10 +24515,10 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if (checkMethod == methodDef) continue; - auto checkMethodInstance = typeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault; + auto checkMethodInstance = typeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault; if (checkMethodInstance == NULL) { - if ((methodDef->mIsNew) && (methodDef->mDeclaringType->IsExtension()) && (!checkMethod->mDeclaringType->IsExtension())) + if ((methodDef->mDeclaringType->IsExtension()) && (!checkMethod->mDeclaringType->IsExtension())) checkMethodInstance = GetRawMethodInstanceAtIdx(typeInstance, checkMethod->mIdx); if (checkMethodInstance == NULL) continue; @@ -24032,7 +24549,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { bool isBetter; bool isWorse; - CompareDeclTypes(checkMethodInstance->mMethodDef->mDeclaringType, methodInstance->mMethodDef->mDeclaringType, isBetter, isWorse); + CompareDeclTypes(typeInstance, checkMethodInstance->mMethodDef->mDeclaringType, methodInstance->mMethodDef->mDeclaringType, isBetter, isWorse); if (isBetter && !isWorse) { methodInstance->mChainType = BfMethodChainType_ChainHead; @@ -24066,16 +24583,19 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool methodInstance->mIsInnerOverride = true; CheckOverridenMethod(methodInstance, checkMethodInstance); } - else if ((methodDef->mDeclaringType->mProject != checkMethod->mDeclaringType->mProject) && - (!checkMethod->mDeclaringType->IsExtension())) + else if (!checkMethod->mDeclaringType->IsExtension()) { foundHiddenMethod = true; if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic)) silentlyAllow = true; else if (methodDef->mIsNew) - { + { silentlyAllow = true; } + else if (checkMethod->GetMethodDeclaration() == NULL) + silentlyAllow = true; + else if (methodDef->mIsOverride) + silentlyAllow = true; else extensionWarn = true; } @@ -24094,31 +24614,37 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto refNode = methodDef->GetRefNode(); BfError* bfError; if (extensionWarn) - bfError = Warn(BfWarning_CS0114_MethodHidesInherited, - StrFormat("This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional. Note that this method is not callable from project '%s'.", - checkMethod->mDeclaringType->mProject->mName.c_str()), refNode); + { + if (methodDef->mDeclaringType->mProject != checkMethod->mDeclaringType->mProject) + bfError = Warn(BfWarning_CS0114_MethodHidesInherited, + StrFormat("This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional. Note that this method is not callable from project '%s'.", + checkMethod->mDeclaringType->mProject->mName.c_str()), refNode); + else + bfError = Warn(BfWarning_CS0114_MethodHidesInherited, + "This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional.", refNode); + } else { - bfError = Fail(StrFormat("Method '%s' already declared with the same parameter types", MethodToString(checkMethodInstance).c_str()), refNode, true); + bfError = Fail(StrFormat("Method '%s' already declared with the same parameter types", MethodToString(checkMethodInstance).c_str()), refNode, true); } if ((bfError != NULL) && (checkMethod->GetRefNode() != refNode)) mCompiler->mPassInstance->MoreInfo("First declaration", checkMethod->GetRefNode()); } } } - } + } } } - // Virtual methods give their error while slotting - if ((!typeInstance->IsBoxed()) && (!methodDef->mIsVirtual) && (methodDef->mProtection != BfProtection_Private) && + // Virtual methods give their error while slotting + if ((!typeInstance->IsBoxed()) && (!methodDef->mIsVirtual) && (methodDef->mProtection != BfProtection_Private) && (!methodDef->mIsLocalMethod) && - (!methodInstance->mIsForeignMethodDef) && (typeInstance->mBaseType != NULL) && + (!methodInstance->mIsForeignMethodDef) && (typeInstance->mBaseType != NULL) && (methodDef->mMethodType == BfMethodType_Normal) && (methodDef->mMethodDeclaration != NULL)) - { + { auto baseType = typeInstance->mBaseType; while (baseType != NULL) - { + { auto baseTypeDef = baseType->mTypeDef; baseTypeDef->PopulateMemberSets(); BfMethodDef* checkMethod = NULL; @@ -24127,13 +24653,13 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool checkMethod = (BfMethodDef*)entry->mMemberDef; while (checkMethod != NULL) - { + { if (checkMethod->mMethodDeclaration == NULL) { checkMethod = checkMethod->mNextWithSameName; continue; } - + if (baseType->mMethodInstanceGroups.size() == 0) { BF_ASSERT(baseType->IsIncomplete() && mCompiler->IsAutocomplete()); @@ -24153,7 +24679,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto checkMethodInstance = GetRawMethodInstanceAtIdx(baseType, checkMethod->mIdx); if (checkMethodInstance != NULL) - { + { if ((checkMethodInstance->GetExplicitInterface() == methodInstance->GetExplicitInterface()) && (checkMethod->mProtection != BfProtection_Private) && (CompareMethodSignatures(checkMethodInstance, mCurMethodInstance))) @@ -24186,7 +24712,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool auto propertyDeclaration = methodDef->GetPropertyDeclaration(); auto tokenNode = (propertyDeclaration != NULL) ? propertyDeclaration->mNewSpecifier : methodDeclaration->mNewSpecifier; - Fail("Method does not hide an inherited member. The 'new' keyword is not required", tokenNode, true); + Fail("Method does not hide an inherited member. The 'new' keyword is not required", tokenNode, true); } } } @@ -24212,7 +24738,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool } mCompiler->mStats.mMethodDeclarations++; - mCompiler->UpdateCompletion(); + mCompiler->UpdateCompletion(); } void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance) @@ -24222,14 +24748,14 @@ void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance) auto typeInstance = mCurTypeInstance; auto methodDef = methodInstance->mMethodDef; - int virtualMethodMatchIdx = -1; + int virtualMethodMatchIdx = -1; if (typeInstance->mHotTypeData != NULL) - { + { if (typeInstance->mHotTypeData->mVTableOrigLength != -1) { BF_ASSERT(mCompiler->IsHotCompile()); - // In the 'normal' case we'd assert that mIsOverride is false, but if we can't find the declaring method then we + // In the 'normal' case we'd assert that mIsOverride is false, but if we can't find the declaring method then we // may slot this override anyway (?) int vTableStart = 0; @@ -24263,15 +24789,15 @@ void BfModule::UniqueSlotVirtualMethod(BfMethodInstance* methodInstance) } if (virtualMethodMatchIdx == -1) - { + { methodInstance->mVirtualTableIdx = typeInstance->mVirtualMethodTableSize++; BfVirtualMethodEntry entry = { methodInstance, methodInstance }; - typeInstance->mVirtualMethodTable.push_back(entry); + typeInstance->mVirtualMethodTable.push_back(entry); } } -void BfModule::CompareDeclTypes(BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse) -{ +void BfModule::CompareDeclTypes(BfTypeInstance* typeInst, BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse) +{ if ((!prevDeclType->IsExtension()) && (newDeclType->IsExtension())) { // When we provide an extension override in the same project a root type override @@ -24281,17 +24807,43 @@ void BfModule::CompareDeclTypes(BfTypeDef* newDeclType, BfTypeDef* prevDeclType, else { isBetter = newDeclType->mProject->ContainsReference(prevDeclType->mProject); - isWorse = prevDeclType->mProject->ContainsReference(newDeclType->mProject); - } + isWorse = prevDeclType->mProject->ContainsReference(newDeclType->mProject); + } + + if ((isBetter == isWorse) && (typeInst != NULL) && (newDeclType->IsExtension()) && (prevDeclType->IsExtension())) + { + if ((typeInst->mGenericTypeInfo != NULL) && (typeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)) + { + isBetter = false; + isWorse = false; + + auto newConstraints = typeInst->GetGenericParamsVector(newDeclType); + auto prevConstraints = typeInst->GetGenericParamsVector(prevDeclType); + + for (int genericIdx = 0; genericIdx < (int)newConstraints->size(); genericIdx++) + { + auto newConstraint = (*newConstraints)[genericIdx]; + auto prevConstraint = (*prevConstraints)[genericIdx]; + + bool newIsSubset = AreConstraintsSubset(newConstraint, prevConstraint); + bool prevIsSubset = AreConstraintsSubset(prevConstraint, newConstraint); + + if ((prevIsSubset) && (!newIsSubset)) + isBetter = true; + if ((!prevIsSubset) && (newIsSubset)) + isWorse = true; + } + } + } } bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityContext* ambiguityContext) { - BP_ZONE("BfModule::SlotVirtualMethod"); + BP_ZONE("BfModule::SlotVirtualMethod"); if (mCurTypeInstance->IsUnspecializedTypeVariation()) return false; - + auto _AddVirtualDecl = [&](BfMethodInstance* declMethodInstance) { if (!mCompiler->mOptions.mAllowHotSwapping) @@ -24299,8 +24851,8 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if ((!methodInstance->mIsReified) || (!declMethodInstance->mIsReified)) return; - if (methodInstance->mHotMethod == NULL) - CheckHotMethod(methodInstance, ""); + if (methodInstance->mHotMethod == NULL) + CheckHotMethod(methodInstance, ""); if (methodInstance->mHotMethod == NULL) return; @@ -24310,12 +24862,12 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo CheckHotMethod(declMethodInstance, ""); auto virtualDecl = mCompiler->mHotData->GetVirtualDeclaration(declMethodInstance->mHotMethod); virtualDecl->mRefCount++; - methodInstance->mHotMethod->mReferences.Add(virtualDecl); + methodInstance->mHotMethod->mReferences.Add(virtualDecl); }; auto typeInstance = mCurTypeInstance; auto typeDef = typeInstance->mTypeDef; - auto methodDef = methodInstance->mMethodDef; + auto methodDef = methodInstance->mMethodDef; auto methodDeclaration = methodDef->GetMethodDeclaration(); auto propertyDeclaration = methodDef->GetPropertyDeclaration(); auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration(); @@ -24326,7 +24878,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo BfAstNode* declaringNode = methodDeclaration; if (propertyMethodDeclaration != NULL) declaringNode = propertyMethodDeclaration->mNameNode; - + BfMethodInstance* methodOverriden = NULL; bool usedMethod = false; @@ -24351,13 +24903,13 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo checkBase = checkBase->mBaseType; if (typeInstance->IsValueType()) - { + { if (typeInstance->mBaseType == NULL) return false; // It's actually ValueType // We allow structs to override object methods for when they get boxed, so just ignore 'override' keyword until it gets boxed if (!methodDef->mIsOverride) - { + { Fail("Structs cannot have virtual methods", virtualToken, true); return false; } @@ -24370,7 +24922,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo } int virtualMethodMatchIdx = -1; - bool hadHidingError = false; + bool hadHidingError = false; BfMethodInstance* bestOverrideMethodInstance = NULL; BfMethodInstance* ambiguousOverrideMethodInstance = NULL; @@ -24492,10 +25044,10 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo } //TODO: - if ((checkBase != NULL) + if ((checkBase != NULL) && (false) ) - { + { auto& baseVirtualMethodTable = checkBase->mVirtualMethodTable; for (int checkMethodIdx = (int) baseVirtualMethodTable.size() - 1; checkMethodIdx >= 0; checkMethodIdx--) { @@ -24512,9 +25064,9 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo AssertErrorState(); continue; } - + if ((baseMethodInstance != NULL) && (CompareMethodSignatures(baseMethodInstance, methodInstance))) - { + { if (methodDef->mIsOverride) { BfMethodInstance* checkMethodInstance; @@ -24522,9 +25074,9 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo checkMethodInstance = checkBase->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod; else checkMethodInstance = typeInstance->mVirtualMethodTable[checkMethodIdx].mDeclaringMethod; - + auto newDeclType = checkMethodInstance->mMethodDef->mDeclaringType; - + if (!typeInstance->IsTypeMemberAccessible(newDeclType, methodDef->mDeclaringType->mProject)) continue; @@ -24542,7 +25094,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo { if (isWorse) continue; - ambiguousOverrideMethodInstance = NULL; + ambiguousOverrideMethodInstance = NULL; } } @@ -24612,7 +25164,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if ((baseVirtualMethodInstance != methodInstance) && (methodDef->mIsOverride)) { if (baseVirtualMethodInstance->mReturnType != methodInstance->mReturnType) - { + { BfTypeReference* returnTypeRef; if (auto propertyDeclaration = methodDef->GetPropertyDeclaration()) { @@ -24664,7 +25216,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo { bool isBetter = false; bool isWorse = false; - CompareDeclTypes(methodInstance->mMethodDef->mDeclaringType, methodOverriden->mMethodDef->mDeclaringType, isBetter, isWorse); + CompareDeclTypes(typeInstance, methodInstance->mMethodDef->mDeclaringType, methodOverriden->mMethodDef->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { // We have to resolve later per-project @@ -24712,13 +25264,13 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo setMethodInstance->mVirtualTableIdx = virtualMethodMatchIdx; auto& implMethodRef = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod; - if ((!mCompiler->mIsResolveOnly) && (implMethodRef.mMethodNum >= 0) && + if ((!mCompiler->mIsResolveOnly) && (implMethodRef.mMethodNum >= 0) && (implMethodRef.mTypeInstance == typeInstance) && (methodInstance->GetOwner() == typeInstance)) { auto prevImplMethodInstance = (BfMethodInstance*)implMethodRef; if (prevImplMethodInstance->mMethodDef->mDeclaringType->mProject != methodInstance->mMethodDef->mDeclaringType->mProject) { - // We may need to have to previous method reified when we must re-slot in another project during vdata creation + // We may need to have to previous method reified when we must re-slot in another project during vdata creation BfReifyMethodDependency dep; dep.mDepMethod = typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mDeclaringMethod; dep.mMethodIdx = implMethodRef.mMethodNum; @@ -24737,29 +25289,29 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo } } } - + typeInstance->mVirtualMethodTable[virtualMethodMatchIdx].mImplementingMethod = setMethodInstance; } } - + if (methodOverriden != NULL) { - CheckOverridenMethod(methodInstance, methodOverriden); + CheckOverridenMethod(methodInstance, methodOverriden); } - } + } } if ((virtualMethodMatchIdx == -1) && ((ambiguityContext == NULL) || (!ambiguityContext->mIsReslotting))) { if (methodDef->mIsOverride) - { + { BfTokenNode* overrideToken = NULL; if (auto propertyMethodDeclaration = methodDef->GetPropertyMethodDeclaration()) overrideToken = propertyMethodDeclaration->mPropertyDeclaration->mVirtualSpecifier; else if (auto methodDeclaration = methodDef->GetMethodDeclaration()) overrideToken = methodDeclaration->mVirtualSpecifier; if (overrideToken != NULL) - { + { if ((propertyDeclaration != NULL) && (propertyDeclaration->mNameNode != NULL) && ((methodDef->mMethodType == BfMethodType_PropertyGetter) || (methodDef->mMethodType == BfMethodType_PropertySetter))) Fail(StrFormat("No suitable method found to override for '%s.%s'", @@ -24767,7 +25319,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo else Fail("No suitable method found to override", overrideToken, true); } - + return usedMethod; } @@ -24776,9 +25328,9 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo else usedMethod = true; - if (typeInstance->IsValueType()) + if (typeInstance->IsValueType()) return usedMethod; - } + } bool foundInterface = false; bool hadAnyMatch = false; @@ -24789,7 +25341,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo auto ifaceInst = ifaceTypeInst.mInterfaceType; if (ifaceInst->IsIncomplete()) PopulateType(ifaceInst, BfPopulateType_DataAndMethods); - int startIdx = ifaceTypeInst.mStartInterfaceTableIdx; + int startIdx = ifaceTypeInst.mStartInterfaceTableIdx; int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size(); // See "bidirectional" rules mentioned in DoTypeInstanceMethodProcessing @@ -24802,7 +25354,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo bool hadMatch = false; BfMethodInstance* hadNameMatch = NULL; BfType* expectedReturnType = NULL; - + bool showedError = false; // We go through our VTable looking for NULL entries within the interface sections @@ -24824,7 +25376,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo BfTypeInterfaceMethodEntry* interfaceMethodEntry = &typeInstance->mInterfaceMethodTable[iTableIdx]; auto iMethodPtr = &interfaceMethodEntry->mMethodRef; bool storeIFaceMethod = false; - + if ((mCompiler->mPassInstance->HasFailed()) && (iMethodIdx >= (int)ifaceInst->mMethodInstanceGroups.size())) { checkMethodDef = checkMethodDef->mNextWithSameName; @@ -24843,7 +25395,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo if (iMethodInst->mMethodDef->mName == methodInstance->mMethodDef->mName) hadNameMatch = iMethodInst; - bool doesMethodSignatureMatch = CompareMethodSignatures(iMethodInst, methodInstance); + bool doesMethodSignatureMatch = CompareMethodSignatures(iMethodInst, methodInstance); if ((!doesMethodSignatureMatch) && (interfaceMethodEntry->mMethodRef.IsNull())) { doesMethodSignatureMatch = IsCompatibleInterfaceMethod(iMethodInst, methodInstance); @@ -24863,20 +25415,20 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo } } } - + if (doesMethodSignatureMatch) - { + { usedMethod = true; hadMatch = true; hadAnyMatch = true; storeIFaceMethod = true; - + if ((iMethodPtr->mKind != BfMethodRefKind_AmbiguousRef) && (iMethodPtr->mTypeInstance != NULL)) - { + { auto prevMethod = (BfMethodInstance*)*iMethodPtr; if ((mCompiler->mIsResolveOnly) && (prevMethod == methodInstance) && (!mIsComptimeModule)) { - // When autocompletion regenerates a single method body but not the whole type then + // When autocompletion regenerates a single method body but not the whole type then // we will see ourselves in the vtable already return usedMethod; } @@ -24886,7 +25438,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo isBetter = (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface != NULL); isWorse = (prevMethod->mMethodInfoEx != NULL) && (prevMethod->mMethodInfoEx->mExplicitInterface != NULL); if (isBetter == isWorse) - CompareDeclTypes(methodInstance->mMethodDef->mDeclaringType, prevMethod->mMethodDef->mDeclaringType, isBetter, isWorse); + CompareDeclTypes(typeInstance, methodInstance->mMethodDef->mDeclaringType, prevMethod->mMethodDef->mDeclaringType, isBetter, isWorse); if (isBetter == isWorse) { if (ambiguityContext != NULL) @@ -24903,21 +25455,21 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo ambiguityContext->Remove(~iTableIdx); storeIFaceMethod = isBetter; } - } + } } - + if (storeIFaceMethod) { if (methodInstance->GetNumGenericParams() != 0) _AddVirtualDecl(iMethodInst); *iMethodPtr = methodInstance; } - + checkMethodDef = checkMethodDef->mNextWithSameName; - } + } if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mExplicitInterface == ifaceInst) && (!hadMatch) && (!showedError)) - { + { if (expectedReturnType != NULL) Fail(StrFormat("Wrong return type, expected '%s'", TypeToString(expectedReturnType).c_str()), declaringNode, true); else if (hadNameMatch != NULL) @@ -24938,7 +25490,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo name = "this[]"; else if (propertyDecl->mNameNode != NULL) propertyDecl->mNameNode->ToString(name); - + Fail(StrFormat("Property '%s' %s accessor not defined in interface '%s'", name.c_str(), (methodDef->mMethodType == BfMethodType_PropertyGetter) ? "get" : "set", TypeToString(ifaceInst).c_str()), methodDef->GetRefNode(), true); } @@ -24990,13 +25542,13 @@ void BfModule::CheckOverridenMethod(BfMethodInstance* methodInstance, BfMethodIn } bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance) -{ +{ auto typeInstance = mCurTypeInstance; auto methodDef = methodInstance->mMethodDef; if (methodDef->mMethodType == BfMethodType_Ctor) return true; - + bool foundOverride = false; if ((methodDef->mBody == NULL) && (methodDef->mProtection == BfProtection_Private)) @@ -25015,8 +25567,8 @@ bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance) Fail("Explicit interfaces can only be specified for overrides in interface declarations", methodDef->GetMethodDeclaration()->mExplicitInterface); } - BfAstNode* declaringNode = methodDef->GetRefNode(); - + BfAstNode* declaringNode = methodDef->GetRefNode(); + for (auto& ifaceTypeInst : typeInstance->mInterfaces) { auto ifaceInst = ifaceTypeInst.mInterfaceType; @@ -25060,7 +25612,7 @@ bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance) Warn(BfWarning_CS0114_MethodHidesInherited, StrFormat("Method hides inherited member from '%s'. Use the 'new' keyword if hiding was intentional.", TypeToString(ifaceInst).c_str()), declaringNode); } } - } + } } if ((methodDef->mIsOverride) && (!foundOverride)) @@ -25083,14 +25635,13 @@ bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance) continue; if (ifaceMethod->mMethodDef->mDeclaringType == methodInstance->mMethodDef->mDeclaringType) continue; - + if (CompareMethodSignatures(ifaceMethod, methodInstance)) { - foundOverride = true; + foundOverride = true; } } - // for (int methodIdx = 0; methodIdx < typeInstance->mMethodInstanceGroups.size(); methodIdx++) // { // auto ifaceMethod = typeInstance->mMethodInstanceGroups[methodIdx].mDefault; @@ -25098,10 +25649,10 @@ bool BfModule::SlotInterfaceMethod(BfMethodInstance* methodInstance) // continue; // if (ifaceMethod->mMethodDef->mDeclaringType == methodInstance->mMethodDef->mDeclaringType) // continue; -// +// // if (CompareMethodSignatures(ifaceMethod, methodInstance)) // { -// foundOverride = true; +// foundOverride = true; // } // } } @@ -25152,11 +25703,11 @@ void BfModule::SetMethodDependency(BfMethodInstance* methodInstance) wantMinDepth = mCurTypeInstance->mDependencyMap.mMinDependDepth + 1; if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL) && (mCurMethodInstance->mMethodInfoEx->mMinDependDepth != -1)) - { + { int wantTypeMinDepth = mCurMethodInstance->mMethodInfoEx->mMinDependDepth + 1; if ((wantMinDepth == -1) || (wantTypeMinDepth < wantMinDepth)) wantMinDepth = wantTypeMinDepth; - } + } if ((methodInstance->mMethodInfoEx->mMinDependDepth == -1) || (wantMinDepth < methodInstance->mMethodInfoEx->mMinDependDepth)) methodInstance->mMethodInfoEx->mMinDependDepth = wantMinDepth; @@ -25175,7 +25726,7 @@ void BfModule::DbgFinish() String markerName; BfIRValue linkMarker; - + if (mBfIRBuilder->DbgHasInfo()) { bool needForceLinking = false; @@ -25184,7 +25735,7 @@ void BfModule::DbgFinish() bool hasConfirmedReference = false; for (auto& methodInstGroup : ownedType->mMethodInstanceGroups) { - if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) && + if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) && (!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) && ((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) && (methodInstGroup.mHasEmittedReference)) @@ -25200,7 +25751,7 @@ void BfModule::DbgFinish() { BfMethodState methodState; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); - methodState.mTempKind = BfMethodState::TempKind_Static; + methodState.mTempKind = BfMethodState::TempKind_Static; mHasForceLinkMarker = true; @@ -25216,7 +25767,7 @@ void BfModule::DbgFinish() auto firstType = mOwnedTypeInstances[0]; UpdateSrcPos(mContext->mBfObjectType->mTypeDef->GetRefNode()); - SizedArray diParamTypes; + SizedArray diParamTypes; diParamTypes.Add(mBfIRBuilder->DbgGetType(GetPrimitiveType(BfTypeCode_None))); BfIRMDNode diFuncType = mBfIRBuilder->DbgCreateSubroutineType(diParamTypes); auto diScope = mBfIRBuilder->DbgCreateFunction(mDICompileUnit, "FORCELINKMOD", linkName, mCurFilePosition.mFileInstance->mDIFile, @@ -25229,7 +25780,7 @@ void BfModule::DbgFinish() BfExprEvaluator exprEvaluator(this); for (auto& ownedType : mOwnedTypeInstances) - { + { auto alloca = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(GetPrimitiveType(BfTypeCode_Int8))); auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(diScope, "variable", mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, mBfIRBuilder->DbgGetType(ownedType)); mBfIRBuilder->DbgInsertDeclare(alloca, diVariable); @@ -25237,12 +25788,12 @@ void BfModule::DbgFinish() mBfIRBuilder->CreateRetVoid(); mBfIRBuilder->SetActiveFunction(BfIRFunction()); - } + } } } bool BfModule::Finish() -{ +{ BP_ZONE("BfModule::Finish"); BfLogSysM("BfModule finish: %p\n", this); @@ -25252,7 +25803,7 @@ bool BfModule::Finish() // the module was still queued in mFinishedModuleWorkList ClearModule(); return true; - } + } if (mUsedSlotCount != -1) { @@ -25266,8 +25817,8 @@ bool BfModule::Finish() BF_ASSERT(mAddedToCount); mAddedToCount = false; mAwaitingFinish = false; - - mCompiler->mStats.mModulesFinished++; + + mCompiler->mStats.mModulesFinished++; if (HasCompiledOutput()) { @@ -25285,8 +25836,8 @@ bool BfModule::Finish() } if (mBfIRBuilder->DbgHasInfo()) - { - mBfIRBuilder->DbgFinalize(); + { + mBfIRBuilder->DbgFinalize(); } String objOutputPath; @@ -25298,7 +25849,7 @@ bool BfModule::Finish() bool writeModule = mBfIRBuilder->HasExports(); String outputPath; - + BfCodeGenOptions codeGenOptions = mProject->mCodeGenOptions; auto& compilerOpts = mCompiler->mOptions; @@ -25316,7 +25867,7 @@ bool BfModule::Finish() mCompiler->mStats.mConstBytes += mBfIRBuilder->mTempAlloc.GetAllocSize(); bool allowWriteToLib = true; - if ((allowWriteToLib) && (codeGenOptions.mOptLevel == BfOptLevel_OgPlus) && + if ((allowWriteToLib) && (codeGenOptions.mOptLevel == BfOptLevel_OgPlus) && (!mCompiler->IsHotCompile()) && (mModuleName != "vdata")) { codeGenOptions.mWriteToLib = true; @@ -25328,12 +25879,12 @@ bool BfModule::Finish() } for (int fileIdx = 0; fileIdx <= mExtensionCount; fileIdx++) - { + { outputPath = mModuleName; outputPath = mCompiler->mOutputDirectory + "/" + mProject->mName + "/" + outputPath; BfModuleFileName moduleFileName; - + if (mParentModule != NULL) { for (auto&& checkPair : mParentModule->mSpecializedMethodModules) @@ -25341,7 +25892,7 @@ bool BfModule::Finish() if (checkPair.mValue == this) moduleFileName.mProjects = checkPair.mKey; } - } + } moduleFileName.mProjects.Add(mProject); if (fileIdx > 0) @@ -25351,11 +25902,11 @@ bool BfModule::Finish() if (mCompiler->mOptions.mGenerateObj) { objOutputPath = outputPath + BF_OBJ_EXT; - moduleFileName.mFileName = objOutputPath; + moduleFileName.mFileName = objOutputPath; } else if (mCompiler->mOptions.mWriteIR) { - moduleFileName.mFileName = irOutputPath; + moduleFileName.mFileName = irOutputPath; } else if ((!mCompiler->mOptions.mGenerateObj) && (!mCompiler->mOptions.mGenerateBitcode) && (!mCompiler->mOptions.mWriteIR)) { @@ -25367,35 +25918,34 @@ bool BfModule::Finish() if (!mOutFileNames.Contains(moduleFileName)) mOutFileNames.Add(moduleFileName); } - + if (mCompiler->IsHotCompile()) { codeGenOptions.mIsHotCompile = true; if (mParentModule != NULL) mParentModule->mHadHotObjectWrites = true; - mHadHotObjectWrites = true; + mHadHotObjectWrites = true; } - //TODO: Testing VDATA /*if (mModuleName == "vdata") { codeGenOptions.mOptLevel = 4; }*/ - - codeGenOptions.GenerateHash(); - BP_ZONE("BfModule::Finish.WriteObjectFile"); - + + codeGenOptions.GenerateHash(); + BP_ZONE("BfModule::Finish.WriteObjectFile"); + if ((writeModule) && (!mBfIRBuilder->mIgnoreWrites)) - mCompiler->mCodeGen.WriteObjectFile(this, outputPath, codeGenOptions); - mLastModuleWrittenRevision = mCompiler->mRevision; - } + mCompiler->mCodeGen.WriteObjectFile(this, outputPath, codeGenOptions); + mLastModuleWrittenRevision = mCompiler->mRevision; + } else { for (auto type : mOwnedTypeInstances) { BF_ASSERT((!type->IsIncomplete()) || (type->IsSpecializedByAutoCompleteMethod())); - } + } } for (auto& specModulePair : mSpecializedMethodModules) @@ -25426,21 +25976,21 @@ void BfModule::ReportMemory(MemReporter* memReporter) memReporter->BeginSection("IRBuilder_BFIR"); memReporter->Add("Used", (int)(mBfIRBuilder->mStream.GetSize())); - memReporter->Add("Unused", (int)(mBfIRBuilder->mStream.mPools.size() * ChunkedDataBuffer::ALLOC_SIZE) - mBfIRBuilder->mStream.GetSize()); + memReporter->Add("Unused", (int)(mBfIRBuilder->mStream.mPools.size() * ChunkedDataBuffer::ALLOC_SIZE) - mBfIRBuilder->mStream.GetSize()); memReporter->EndSection(); memReporter->Add(sizeof(BfIRBuilder)); } - + memReporter->BeginSection("FileInstanceMap"); - memReporter->AddMap(mFileInstanceMap); + memReporter->AddMap(mFileInstanceMap); memReporter->AddMap(mNamedFileInstanceMap); memReporter->Add((int)mNamedFileInstanceMap.size() * sizeof(BfFileInstance)); - memReporter->EndSection(); + memReporter->EndSection(); memReporter->AddVec(mOwnedTypeInstances, false); memReporter->AddVec(mSpecializedMethodModules, false); - memReporter->AddVec(mOutFileNames, false); + memReporter->AddVec(mOutFileNames, false); memReporter->AddMap("FuncReferences", mFuncReferences, false); memReporter->AddMap(mInterfaceSlotRefs, false); memReporter->AddMap(mStaticFieldRefs, false); @@ -25456,7 +26006,7 @@ void BfModule::ReportMemory(MemReporter* memReporter) // ClearModuleData is called immediately after the module is compiled, so don't clear out any data that needs to // be transient through the next compile void BfModule::ClearModuleData(bool clearTransientData) -{ +{ BfLogSysM("ClearModuleData %p\n", this); if (mAddedToCount) @@ -25465,9 +26015,9 @@ void BfModule::ClearModuleData(bool clearTransientData) mAddedToCount = false; } - mDICompileUnit = BfIRMDNode(); + mDICompileUnit = BfIRMDNode(); if (clearTransientData) - mIncompleteMethodCount = 0; + mIncompleteMethodCount = 0; mHasGenericMethods = false; // We don't want to clear these because we want it to persist through module extensions- @@ -25486,29 +26036,29 @@ void BfModule::ClearModuleData(bool clearTransientData) for (auto prevIRBuilder : mPrevIRBuilders) delete prevIRBuilder; - mPrevIRBuilders.Clear(); + mPrevIRBuilders.Clear(); for (auto& specPair : mSpecializedMethodModules) { auto specModule = specPair.mValue; specModule->ClearModuleData(); } - + for (int i = 0; i < BfBuiltInFuncType_Count; i++) mBuiltInFuncs[i] = BfIRFunction(); if (mNextAltModule != NULL) mNextAltModule->ClearModuleData(); - - BfLogSysM("ClearModuleData. Deleting IRBuilder: %p\n", mBfIRBuilder); + + BfLogSysM("ClearModuleData. Deleting IRBuilder: %p\n", mBfIRBuilder); mIsModuleMutable = false; delete mBfIRBuilder; - mBfIRBuilder = NULL; + mBfIRBuilder = NULL; mWantsIRIgnoreWrites = false; } void BfModule::DisownMethods() -{ +{ for (int i = 0; i < BfBuiltInFuncType_Count; i++) mBuiltInFuncs[i] = BfIRFunction(); @@ -25527,7 +26077,7 @@ void BfModule::DisownMethods() BF_ASSERT(methodGroup.mDefault->mDeclModule != NULL); if (methodGroup.mDefault->mDeclModule == this) { - methodGroup.mDefault->mIRFunction = BfIRFunction(); + methodGroup.mDefault->mIRFunction = BfIRFunction(); } } } @@ -25557,8 +26107,7 @@ void BfModule::ClearModule() { auto specModule = specPair.mValue; specModule->ClearModule(); - } + } if (mNextAltModule != NULL) mNextAltModule->ClearModule(); -} - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index f4fc6582..c3a6c099 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -47,19 +47,20 @@ enum BfPopulateType BfPopulateType_Interfaces_Direct, BfPopulateType_AllowStaticMethods, BfPopulateType_Interfaces_All, + BfPopulateType_Data_Soft, BfPopulateType_Data, BfPopulateType_DataAndMethods, BfPopulateType_Full = BfPopulateType_DataAndMethods, - + BfPopulateType_Full_Force }; -enum BfEvalExprFlags +enum BfEvalExprFlags : int64 { BfEvalExprFlags_None = 0, BfEvalExprFlags_ExplicitCast = 1, - BfEvalExprFlags_NoCast = 2, - BfEvalExprFlags_NoValueAddr = 4, + BfEvalExprFlags_NoCast = 2, + BfEvalExprFlags_NoValueAddr = 4, BfEvalExprFlags_PropogateNullConditional = 8, BfEvalExprFlags_IgnoreNullConditional = 0x10, BfEvalExprFlags_AllowSplat = 0x20, @@ -88,6 +89,9 @@ enum BfEvalExprFlags BfEvalExprFlags_FromConversionOp_Explicit = 0x10000000, BfEvalExprFlags_AllowGenericConstValue = 0x20000000, BfEvalExprFlags_IsExpressionBody = 0x40000000, + BfEvalExprFlags_AppendFieldInitializer = 0x80000000, + BfEvalExprFlags_NameOf = 0x100000000LL, + BfEvalExprFlags_NameOfSuccess = 0x200000000LL, BfEvalExprFlags_InheritFlags = BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime | BfEvalExprFlags_DeclType }; @@ -109,7 +113,8 @@ enum BfCastFlags BfCastFlags_WarnOnBox = 0x800, BfCastFlags_IsCastCheck = 0x1000, BfCastFlags_IsConstraintCheck = 0x2000, - BfCastFlags_WantsConst = 0x4000 + BfCastFlags_WantsConst = 0x4000, + BfCastFlags_FromComptimeReturn = 0x8000 }; enum BfCastResultFlags : int8 @@ -150,32 +155,32 @@ enum BfLocalVarAssignKind : int8 { BfLocalVarAssignKind_None = 0, BfLocalVarAssignKind_Conditional = 1, - BfLocalVarAssignKind_Unconditional = 2 + BfLocalVarAssignKind_Unconditional = 2 }; class BfLocalVariable { public: - int64 mUnassignedFieldFlags; + int64 mUnassignedFieldFlags; BfType* mResolvedType; BfIdentifierNode* mNameNode; String mName; BfIRValue mAddr; BfIRValue mConstValue; BfIRValue mValue; - BfIRMDNode mDbgVarInst; - BfIRValue mDbgDeclareInst; + BfIRMDNode mDbgVarInst; + BfIRValue mDbgDeclareInst; BfIRBlock mDeclBlock; int mLocalVarIdx; // Index in mLocals int mLocalVarId; // Unique Id for identification (does not get reused, unlike mLocalVarIdx) - int mCompositeCount; + int mCompositeCount; int mWrittenToId; int mReadFromId; int mParamIdx; uint8 mNamePrefixCount; bool mIsThis; bool mHasLocalStructBacking; - bool mIsStruct; + bool mIsStruct; bool mIsImplicitParam; bool mParamFailed; BfLocalVarAssignKind mAssignedKind; @@ -186,7 +191,7 @@ public: bool mIsLowered; bool mAllowAddr; bool mIsShadow; - bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can + bool mUsedImplicitly; // Passed implicitly to a local method, capture by ref if we can bool mNotCaptured; bool mIsConst; bool mIsBumpAlloc; @@ -225,11 +230,11 @@ public: mShadowedLocal = NULL; } - bool IsParam() + bool IsParam() { return mParamIdx != -2; } - void Init(); + void Init(); }; class BfMethodState; @@ -240,19 +245,19 @@ class BfLocalMethod { public: BfSystem* mSystem; - BfModule* mModule; + BfModule* mModule; BfSource* mSource; BfMethodDeclaration* mMethodDeclaration; String mExpectedFullName; - String mMethodName; - BfMethodDef* mMethodDef; + String mMethodName; + BfMethodDef* mMethodDef; BfLocalMethod* mOuterLocalMethod; - BfMethodInstanceGroup* mMethodInstanceGroup; - BfMethodInstance* mLambdaInvokeMethodInstance; - BfLambdaBindExpression* mLambdaBindExpr; + BfMethodInstanceGroup* mMethodInstanceGroup; + BfMethodInstance* mLambdaInvokeMethodInstance; + BfLambdaBindExpression* mLambdaBindExpr; BfMethodState* mDeclMethodState; BfIRMDNode mDeclDIScope; - BfMixinState* mDeclMixinState; + BfMixinState* mDeclMixinState; OwnedVector mDirectTypeRefs; bool mDeclOnly; bool mDidBodyErrorPass; @@ -269,9 +274,9 @@ public: mOuterLocalMethod = NULL; mMethodInstanceGroup = NULL; mLambdaInvokeMethodInstance = NULL; - mLambdaBindExpr = NULL; + mLambdaBindExpr = NULL; mDeclMethodState = NULL; - mDeclMixinState = NULL; + mDeclMixinState = NULL; mDeclOnly = false; mDidBodyErrorPass = false; mNextWithSameName = NULL; @@ -298,7 +303,7 @@ public: BfIRValue mDeferredAlloca; SizedArray mOrigScopeArgs; SizedArray mScopeArgs; - Array mCaptures; + Array mCaptures; BfBlock* mDeferredBlock; BfAstNode* mEmitRefNode; int64 mBlockId; @@ -308,9 +313,9 @@ public: bool mCastThis; bool mArgsNeedLoad; bool mIgnored; - + SLIList mDynList; - BfIRValue mDynCallTail; + BfIRValue mDynCallTail; public: BfDeferredCallEntry() @@ -375,7 +380,8 @@ public: bool mIsUnconditional; bool mIsIfCondition; bool mIfMayBeSkipped; - bool mLeftBlock; + bool mLeftBlock; + bool mLeftBlockUncond; public: BfDeferredLocalAssignData(BfScopeData* scopeData = NULL) @@ -391,8 +397,9 @@ public: mIsIfCondition = false; mIfMayBeSkipped = false; mLeftBlock = false; + mLeftBlockUncond = false; } - + bool Contains(const BfAssignedLocal& val) { for (int i = 0; i < (int)mAssignedLocals.mSize; i++) @@ -423,13 +430,13 @@ enum BfScopeKind class BfScopeData { public: - BfScopeData* mPrevScope; + BfScopeData* mPrevScope; BfScopeKind mScopeKind; BfIRMDNode mDIScope; - BfIRMDNode mDIInlinedAt; + BfIRMDNode mDIInlinedAt; String mLabel; BfIdentifierNode* mLabelNode; - int mLocalVarStart; + int mLocalVarStart; int mScopeDepth; int mMixinDepth; int mScopeLocalId; @@ -439,13 +446,14 @@ public: bool mOuterIsConditional; bool mInnerIsConditional; bool mHadOuterDynStack; - bool mAllowTargeting; - bool mHadScopeValueRetain; + bool mAllowTargeting; + bool mHadScopeValueRetain; bool mIsDeferredBlock; bool mAllowVariableDeclarations; bool mInInitBlock; bool mSupressNextUnreachable; bool mInConstIgnore; + bool mIsSharedTempBlock; BfMixinState* mMixinState; BfBlock* mAstBlock; BfAstNode* mCloseNode; @@ -453,16 +461,16 @@ public: SLIList mDeferredCallEntries; BfIRValue mBlock; BfIRValue mValueScopeStart; - BfIRValue mSavedStack; + BfIRValue mSavedStack; Array mSavedStackUses; Array mDeferredHandlers; // These get cleared when us our a parent gets new entries added into mDeferredCallEntries Array mAtEndBlocks; // Move these to the end after we close scope Array mDeferredLifetimeEnds; BfDeferredLocalAssignData* mExitLocalAssignData; BfIRMDNode mAltDIFile; - BfIRMDNode mAltDIScope; + BfIRMDNode mAltDIScope; -public: +public: BfScopeData() { mScopeKind = BfScopeKind_Normal; @@ -478,19 +486,20 @@ public: mIsConditional = false; mOuterIsConditional = false; mInnerIsConditional = false; - mHadOuterDynStack = false; + mHadOuterDynStack = false; mHadScopeValueRetain = false; mIsDeferredBlock = false; mSupressNextUnreachable = false; - mAllowTargeting = true; + mAllowTargeting = true; mAllowVariableDeclarations = true; mInInitBlock = false; mInConstIgnore = false; + mIsSharedTempBlock = false; mMixinDepth = 0; mScopeDepth = 0; mScopeLocalId = -1; mExitLocalAssignData = NULL; - } + } ~BfScopeData() { @@ -526,7 +535,7 @@ public: } return false; } - + bool IsDyn(BfScopeData* scopeData) { auto checkScope = this; @@ -554,7 +563,7 @@ public: return false; auto checkScope = this; while (checkScope != scopeData) - { + { checkScope = checkScope->mPrevScope; if (!checkScope->mDIInlinedAt) return true; @@ -571,7 +580,7 @@ public: if (checkScope == scopeData) break; checkScope = checkScope->mPrevScope; - } + } } int GetDepth() @@ -587,6 +596,17 @@ public: } return depth; } + + bool ExtendLifetime(BfIRValue irValue) + { + if (mDeferredLifetimeEnds.Remove(irValue)) + { + if (mPrevScope != NULL) + mPrevScope->mDeferredLifetimeEnds.Add(irValue); + return true; + } + return false; + } }; struct BfCaptureInfo @@ -656,7 +676,7 @@ class BfBreakData { public: BfBreakData* mPrevBreakData; - BfScopeData* mScope; + BfScopeData* mScope; BfIRBlock mIRContinueBlock; BfIRBlock mIRBreakBlock; BfIRBlock mIRFallthroughBlock; @@ -714,7 +734,7 @@ public: BfTypeInstance* mClosureType; BfDeferredLocalMethod* mActiveDeferredLocalMethod; Array mConstLocals; // Locals not inserted into the captured 'this' - HashSet mReferencedOuterClosureMembers; + HashSet mReferencedOuterClosureMembers; HashSet mLocalMethodRefSet; Array mLocalMethodRefs; Array mDeferredProcessLocalMethods; @@ -732,10 +752,10 @@ public: mDeclaringMethodIsMutating = false; mCapturedDelegateSelf = false; mReturnTypeInferState = BfReturnTypeInferState_None; - mActiveDeferredLocalMethod = NULL; + mActiveDeferredLocalMethod = NULL; mReturnType = NULL; mDelegateType = NULL; - mClosureType = NULL; + mClosureType = NULL; } }; @@ -762,7 +782,7 @@ public: }; class BfAttributeState -{ +{ public: enum Flags { @@ -771,19 +791,19 @@ public: Flag_HadError = 2 }; -public: +public: Flags mFlags; BfAstNode* mSrc; BfAttributeTargets mTarget; - BfCustomAttributes* mCustomAttributes; - bool mUsed; + BfCustomAttributes* mCustomAttributes; + bool mUsed; BfAttributeState() { mSrc = NULL; mFlags = Flag_None; mTarget = BfAttributeTargets_None; - mCustomAttributes = NULL; + mCustomAttributes = NULL; mUsed = false; } @@ -791,12 +811,12 @@ public: { if (mCustomAttributes != NULL) delete mCustomAttributes; - } + } }; class BfMixinState { -public: +public: BfMixinState* mPrevMixinState; BfAstNode* mSource; BfScopeData* mCallerScope; @@ -811,6 +831,7 @@ public: bool mHasDeferredUsage; bool mCheckedCircularRef; bool mDoCircularVarResult; + bool mUseMixinGenerics; BfTypedValue mTarget; int mLastTargetAccessId; @@ -828,6 +849,7 @@ public: mHasDeferredUsage = false; mCheckedCircularRef = false; mDoCircularVarResult = false; + mUseMixinGenerics = false; mLastTargetAccessId = -1; } @@ -865,8 +887,8 @@ public: public: BfErrorKind mErrorKind; BfAstNode* mRefNode; - BfTypeDef* mAmbiguousTypeDef; - + BfTypeDef* mAmbiguousTypeDef; + public: BfTypeLookupError() { @@ -907,11 +929,15 @@ class BfConstResolveState public: BfMethodInstance* mMethodInstance; BfConstResolveState* mPrevConstResolveState; + bool mInCalcAppend; + bool mFailed; BfConstResolveState() { mMethodInstance = NULL; mPrevConstResolveState = NULL; + mInCalcAppend = false; + mFailed = false; } }; @@ -938,7 +964,7 @@ struct BfLocalVarEntry class BfLambdaCaptureInfo { public: - String mName; + String mName; }; class BfLambdaInstance @@ -979,8 +1005,8 @@ public: { auto methodDef = mMethodInstance->mMethodDef; delete mMethodInstance; - delete methodDef; - + delete methodDef; + if (mDtorMethodInstance != NULL) { auto methodDef = mDtorMethodInstance->mMethodDef; @@ -1010,48 +1036,48 @@ public: public: BumpAllocator mBumpAlloc; BfMethodState* mPrevMethodState; // Only non-null for things like local methods - BfConstResolveState* mConstResolveState; - BfMethodInstance* mMethodInstance; + BfConstResolveState* mConstResolveState; + BfMethodInstance* mMethodInstance; BfHotDataReferenceBuilder* mHotDataReferenceBuilder; - BfIRFunction mIRFunction; + BfIRFunction mIRFunction; BfIRBlock mIRHeadBlock; BfIRBlock mIRInitBlock; BfIRBlock mIREntryBlock; Array > mLocals; HashSet > mLocalVarSet; - Array mLocalMethods; + Array mLocalMethods; Dictionary mLocalMethodMap; - Dictionary mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method + Dictionary mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method Array mDeferredLocalMethods; OwnedVector mMixinStates; Dictionary mLambdaCache; Array mDeferredLambdaInstances; - Array mSplatDecompAddrs; + Array mSplatDecompAddrs; BfDeferredLocalAssignData* mDeferredLocalAssignData; BfProjectSet mVisibleProjectSet; int mDeferredLoopListCount; - int mDeferredLoopListEntryCount; + int mDeferredLoopListEntryCount; HashSet mSkipObjectAccessChecks; // Indexed by BfIRValue value id - + Dictionary* mGenericTypeBindings; - + BfIRMDNode mDIFile; bool mInHeadScope; // Is in starting scope of code on entry, controls mStackAllocUncondCount BfTypedValue mRetVal; - BfIRValue mRetValAddr; + BfIRValue mRetValAddr; int mCurAppendAlign; BfIRValue mDynStackRevIdx; // Increments when we restore the stack, which can invalidate dynSize for dynamic looped allocs BfIRBlock mIRExitBlock; BfBreakData* mBreakData; - int mBlockNestLevel; // 0 = top level - bool mIgnoreObjectAccessCheck; + int mBlockNestLevel; // 0 = top level + bool mIgnoreObjectAccessCheck; bool mDisableChecks; BfMixinState* mMixinState; BfClosureState* mClosureState; BfDeferredCallEmitState* mDeferredCallEmitState; BfIteratorClassState* mIteratorClassState; BfPendingNullConditional* mPendingNullConditional; - BfTypeOptions* mMethodTypeOptions; // for [Options] attribute + BfTypeOptions* mMethodTypeOptions; // for [Options] attribute BfIRMDNode mDIRetVal; BfScopeData mHeadScope; @@ -1066,14 +1092,14 @@ public: bool mMayNeedThisAccessCheck; bool mLeftBlockUncond; // Definitely left block. mHadReturn also sets mLeftBlock bool mLeftBlockCond; // May have left block. - bool mInPostReturn; // Unreachable code + bool mInPostReturn; // Unreachable code bool mCrossingMixin; // ie: emitting dtors in response to a return in a mixin bool mNoBind; - bool mInConditionalBlock; // IE: RHS of ((A) && (B)), indicates an allocation in 'B' won't be dominated by a dtor, for example + bool mInConditionalBlock; // IE: RHS of ((A) && (B)), indicates an allocation in 'B' won't be dominated by a dtor, for example bool mAllowUinitReads; bool mDisableReturns; - bool mCancelledDeferredCall; - bool mNoObjectAccessChecks; + bool mCancelledDeferredCall; + bool mNoObjectAccessChecks; int mCurLocalVarId; // Can also refer to a label int mCurAccessId; // For checking to see if a block reads from or writes to a local @@ -1081,51 +1107,51 @@ public: BfMethodState() { mLocals.mAlloc = &mBumpAlloc; - mLocalVarSet.mAlloc = &mBumpAlloc; - - mMethodInstance = NULL; + mLocalVarSet.mAlloc = &mBumpAlloc; + + mMethodInstance = NULL; mPrevMethodState = NULL; mConstResolveState = NULL; - mHotDataReferenceBuilder = NULL; + mHotDataReferenceBuilder = NULL; mHeadScope.mIsScopeHead = true; mCurScope = &mHeadScope; mTailScope = &mHeadScope; mEmitRefNode = NULL; mOverrideScope = NULL; mHadReturn = false; - mLeftBlockUncond = false; + mLeftBlockUncond = false; mLeftBlockCond = false; mHadContinue = false; mMayNeedThisAccessCheck = false; - mTempKind = TempKind_None; + mTempKind = TempKind_None; mInHeadScope = true; mBreakData = NULL; mBlockNestLevel = 0; - mInPostReturn = false; + mInPostReturn = false; mCrossingMixin = false; - mNoBind = false; + mNoBind = false; mIgnoreObjectAccessCheck = false; mDisableChecks = false; mInConditionalBlock = false; mAllowUinitReads = false; mDisableReturns = false; mCancelledDeferredCall = false; - mNoObjectAccessChecks = false; - mInDeferredBlock = false; + mNoObjectAccessChecks = false; + mInDeferredBlock = false; mDeferredLocalAssignData = NULL; mCurLocalVarId = 0; mCurAccessId = 1; mCurAppendAlign = 0; mDeferredLoopListCount = 0; - mDeferredLoopListEntryCount = 0; - mClosureState = NULL; + mDeferredLoopListEntryCount = 0; + mClosureState = NULL; mDeferredCallEmitState = NULL; - mIteratorClassState = NULL; - + mIteratorClassState = NULL; + mGenericTypeBindings = NULL; mMixinState = NULL; mPendingNullConditional = NULL; - mMethodTypeOptions = NULL; + mMethodTypeOptions = NULL; } ~BfMethodState(); @@ -1137,11 +1163,11 @@ public: mInHeadScope = false; newScopeData->mDIScope = mCurScope->mDIScope; newScopeData->mDIInlinedAt = mCurScope->mDIInlinedAt; - newScopeData->mLocalVarStart = mCurScope->mLocalVarStart; + newScopeData->mLocalVarStart = mCurScope->mLocalVarStart; newScopeData->mExprEvaluator = mCurScope->mExprEvaluator; newScopeData->mAltDIFile = mCurScope->mAltDIFile; - newScopeData->mPrevScope = mCurScope; - newScopeData->mMixinDepth = mCurScope->mMixinDepth; + newScopeData->mPrevScope = mCurScope; + newScopeData->mMixinDepth = mCurScope->mMixinDepth; newScopeData->mScopeDepth = mCurScope->mScopeDepth + 1; newScopeData->mInConstIgnore = mCurScope->mInConstIgnore; mCurScope = newScopeData; @@ -1167,7 +1193,7 @@ public: { //TODO: Why did this require mLocalMethod to not be null? That means lambda captures we're not crossed over auto checkMethodState = this; - while ((checkMethodState->mPrevMethodState != NULL) && (checkMethodState->mClosureState != NULL) && + while ((checkMethodState->mPrevMethodState != NULL) && (checkMethodState->mClosureState != NULL) && (checkMethodState->mClosureState->mCapturing) /*&& (checkMethodState->mClosureState->mLocalMethod != NULL)*/) checkMethodState = checkMethodState->mPrevMethodState; return checkMethodState; @@ -1244,7 +1270,7 @@ public: } void LocalDefined(BfLocalVariable* localVar, int fieldIdx = -1, BfLocalVarAssignKind assignKind = BfLocalVarAssignKind_None, bool isFromDeferredAssignData = false); - void ApplyDeferredLocalAssignData(const BfDeferredLocalAssignData& deferredLocalAssignData); + void ApplyDeferredLocalAssignData(const BfDeferredLocalAssignData& deferredLocalAssignData); void Reset(); int GetLocalStartIdx() @@ -1272,19 +1298,19 @@ enum BfBuiltInFuncType { BfBuiltInFuncType_PrintF, BfBuiltInFuncType_Malloc, - BfBuiltInFuncType_Free, + BfBuiltInFuncType_Free, BfBuiltInFuncType_LoadSharedLibraries, BfBuiltInFuncType_Count }; -// These are the options that can be applied to individual methods that cause AltModules -// to be build, since they are exclusive to an LLVMModule; LLVM optimization-related +// These are the options that can be applied to individual methods that cause AltModules +// to be build, since they are exclusive to an LLVMModule; LLVM optimization-related // options always apply to entire LLVM modules struct BfModuleOptions { public: - BfSIMDSetting mSIMDSetting; + BfSIMDSetting mSIMDSetting; int mEmitDebugInfo; BfOptLevel mOptLevel; @@ -1349,7 +1375,7 @@ public: class BfAmbiguityContext { -public: +public: class Entry { public: @@ -1363,7 +1389,7 @@ public: BfTypeInstance* mTypeInstance; bool mIsProjectSpecific; bool mIsReslotting; - Dictionary mEntries; + Dictionary mEntries; public: BfAmbiguityContext() @@ -1456,7 +1482,7 @@ public: struct BfCEParseContext { int mFailIdx; - int mWarnIdx; + int mWarnIdx; }; class BfModule : public BfStructuralVisitor @@ -1478,12 +1504,12 @@ public: String mModuleName; #endif Array mOutFileNames; - // SpecializedModules contain method specializations with types that come from other projects - Dictionary, BfModule*> mSpecializedMethodModules; + // SpecializedModules contain method specializations with types that come from other projects + Dictionary, BfModule*> mSpecializedMethodModules; BfModule* mParentModule; - BfModule* mNextAltModule; // Linked - BfModuleOptions* mModuleOptions; // Only in altModules - + BfModule* mNextAltModule; // Linked + BfModuleOptions* mModuleOptions; // Only in altModules + BfSystem* mSystem; BfCompiler* mCompiler; BfContext* mContext; @@ -1493,36 +1519,36 @@ public: BfTypeInstance* mCurTypeInstance; Dictionary mFileInstanceMap; Dictionary mNamedFileInstanceMap; - Array mOwnedTypeInstances; - + Array mOwnedTypeInstances; + Dictionary mStringObjectPool; Dictionary mStringCharPtrPool; - Array mStringPoolRefs; + Array mStringPoolRefs; HashSet mUnreifiedStringPoolRefs; - - Array mPrevIRBuilders; // Before extensions - BfIRBuilder* mBfIRBuilder; - - BfMethodState* mCurMethodState; - BfAttributeState* mAttributeState; + + Array mPrevIRBuilders; // Before extensions + BfIRBuilder* mBfIRBuilder; + + BfMethodState* mCurMethodState; + BfAttributeState* mAttributeState; BfFilePosition mCurFilePosition; BfMethodInstance* mCurMethodInstance; BfParentNodeEntry* mParentNodeEntry; - BfIRFunction mBuiltInFuncs[BfBuiltInFuncType_Count]; + BfIRFunction mBuiltInFuncs[BfBuiltInFuncType_Count]; Array mDllImportEntries; Array mImportFileNames; - Dictionary mFuncReferences; + Dictionary mFuncReferences; Dictionary mStaticFieldRefs; - Dictionary mInterfaceSlotRefs; + Dictionary mInterfaceSlotRefs; Dictionary mClassVDataRefs; Dictionary mClassVDataExtRefs; Dictionary mTypeDataRefs; Dictionary mDbgRawAllocDataRefs; Dictionary mDeferredMethodCallData; HashSet mDeferredMethodIds; - HashSet mModuleRefs; + HashSet mModuleRefs; BfIRMDNode mDICompileUnit; int mRevision; @@ -1545,14 +1571,14 @@ public: bool mIsComptimeModule; bool mIsScratchModule; bool mIsSpecializedMethodModuleRoot; - bool mIsModuleMutable; // Set to false after writing module to disk, can be set back to true after doing extension module + bool mIsModuleMutable; // Set to false after writing module to disk, can be set back to true after doing extension module bool mWroteToLib; bool mHadBuildError; - bool mHadBuildWarning; - bool mIgnoreErrors; + bool mHadBuildWarning; + bool mIgnoreErrors; bool mHadIgnoredError; - bool mIgnoreWarnings; - bool mSetIllegalSrcPosition; + bool mIgnoreWarnings; + bool mSetIllegalSrcPosition; bool mReportErrors; // Still puts system in error state when set to false bool mIsInsideAutoComplete; bool mIsHotModule; @@ -1564,14 +1590,14 @@ public: bool mNoResolveGenericParams; bool mHadHotObjectWrites; -public: +public: void FatalError(const StringImpl& error, const char* file = NULL, int line = -1); - void NotImpl(BfAstNode* astNode); + void NotImpl(BfAstNode* astNode); void AddMethodReference(const BfMethodRef& methodRef, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None); bool CheckProtection(BfProtection protection, BfTypeDef* checkType, bool allowProtected, bool allowPrivate); void GetAccessAllowed(BfTypeInstance* checkType, bool& allowProtected, bool& allowPrivate); bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType); - void SetElementType(BfAstNode* astNode, BfSourceElementType elementType); + void SetElementType(BfAstNode* astNode, BfSourceElementType elementType); bool PreFail(); void SetFail(); void VerifyOnDemandMethods(); @@ -1580,27 +1606,27 @@ public: CeDbgState* GetCeDbgState(); BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false); BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL); - BfError* FailAfter(const StringImpl& error, BfAstNode* refNode); + BfError* FailAfter(const StringImpl& error, BfAstNode* refNode); BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false, bool showInSpecialized = false); void CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc); void CheckRangeError(BfType* type, BfAstNode* refNode); - bool CheckCircularDataError(); + bool CheckCircularDataError(bool failTypes = true); BfFileInstance* GetFileFromNode(BfAstNode* astNode); - //void UpdateSrcPos(BfAstNode* astNode, bool setDebugLoc = true, int debugLocOffset = 0, bool force = false); + //void UpdateSrcPos(BfAstNode* astNode, bool setDebugLoc = true, int debugLocOffset = 0, bool force = false); void UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags = BfSrcPosFlag_None, int debugLocOffset = 0); - void UseDefaultSrcPos(BfSrcPosFlags flags = BfSrcPosFlag_None, int debugLocOffset = 0); + void UseDefaultSrcPos(BfSrcPosFlags flags = BfSrcPosFlag_None, int debugLocOffset = 0); void UpdateExprSrcPos(BfAstNode* astNode, BfSrcPosFlags flags = BfSrcPosFlag_None); void SetIllegalSrcPos(BfSrcPosFlags flags = BfSrcPosFlag_None); void SetIllegalExprSrcPos(BfSrcPosFlags flags = BfSrcPosFlag_None); - void GetConstClassValueParam(BfIRValue classVData, SizedArrayImpl& typeValueParams); + void GetConstClassValueParam(BfIRValue classVData, SizedArrayImpl& typeValueParams); BfIRValue GetConstValue(int64 val); BfIRValue GetConstValue(int64 val, BfType* type); BfIRValue GetConstValue8(int val); BfIRValue GetConstValue32(int32 val); - BfIRValue GetConstValue64(int64 val); - BfIRValue GetDefaultValue(BfType* type); + BfIRValue GetConstValue64(int64 val); + BfIRValue GetDefaultValue(BfType* type); BfTypedValue GetFakeTypedValue(BfType* type); - BfTypedValue GetDefaultTypedValue(BfType* type, bool allowRef = false, BfDefaultValueKind defaultValueKind = BfDefaultValueKind_Const); + BfTypedValue GetDefaultTypedValue(BfType* type, bool allowRef = false, BfDefaultValueKind defaultValueKind = BfDefaultValueKind_Const); void FixConstValueParams(BfTypeInstance* typeInst, SizedArrayImpl& valueParams, bool fillInPadding = false); BfIRValue CreateStringObjectValue(const StringImpl& str, int stringId, bool define); BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define); @@ -1611,18 +1637,19 @@ public: BfIRValue GetStringCharPtr(const StringImpl& str, bool force = false); BfIRValue GetStringObjectValue(int idx, bool define, bool force); BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false, bool force = false); - BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external); + BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external); void VariantToString(StringImpl& str, const BfVariant& variant); StringT<128> TypeToString(BfType* resolvedType, Array* genericMethodParamNameOverrides = NULL); - StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array* genericMethodParamNameOverrides = NULL); + StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array* genericMethodParamNameOverrides = NULL); void DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None, Array* genericMethodParamNameOverrides = NULL); StringT<128> MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags = BfMethodNameFlag_ResolveGenericParamNames, BfTypeVector* typeGenericArgs = NULL, BfTypeVector* methodGenericArgs = NULL); void pt(BfType* type); void pm(BfMethodInstance* type); + BfIRType CurrentAddToConstHolder(BfIRType irType); void CurrentAddToConstHolder(BfIRValue& irVal); 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 allowUnactualized = false); void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget); void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL); @@ -1630,39 +1657,39 @@ public: BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef); void FinishAttributeState(BfAttributeState* attributeState); void ProcessTypeInstCustomAttributes(int& packing, bool& isUnion, bool& isCRepr, bool& isOrdered, int& alignOverride, BfType*& underlyingArrayType, int& underlyingArraySize); - void ProcessCustomAttributeData(); + void ProcessCustomAttributeData(); bool TryGetConstString(BfIRConstHolder* constHolder, BfIRValue irValue, StringImpl& str); BfVariant TypedValueToVariant(BfAstNode* refNode, const BfTypedValue& value, bool allowUndef = false); - BfTypedValue FlushNullConditional(BfTypedValue result, bool ignoreNullable = false); + BfTypedValue FlushNullConditional(BfTypedValue result, bool ignoreNullable = false); void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue()); BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL); BfDeferredCallEntry* AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false, BfIRBlock valBlock = BfIRBlock()); void RestoreScoreState_LocalVariables(); - void RestoreScopeState(); + void RestoreScopeState(); void MarkDynStack(BfScopeData* scope); void SaveStackState(BfScopeData* scope); BfIRValue ValueScopeStart(); void ValueScopeEnd(BfIRValue valueScopeStart); BfProjectSet* GetVisibleProjectSet(); - void AddBasicBlock(BfIRBlock bb, bool activate = true); + void AddBasicBlock(BfIRBlock bb, bool activate = true); void VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator = NULL, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None); void VisitCodeBlock(BfBlock* block); - void VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn = NULL, BfLabelNode* labelNode = NULL, bool closeScope = false); + void VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn = NULL, BfLabelNode* labelNode = NULL, bool closeScope = false, BfEmbeddedStatementFlags flags = BfEmbeddedStatementFlags_None); void DoForLess(BfForEachStatement* forEachStmt); // Util - void CreateReturn(BfIRValue val); + void CreateReturn(BfIRValue val); void EmitReturn(const BfTypedValue& val); void EmitDefaultReturn(); void EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl& llvmArgs, BfDeferredBlockFlags flags = BfDeferredBlockFlag_None); bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope); BfDeferredCallEntry* AddDeferredBlock(BfBlock* block, BfScopeData* scope, Array* captures = NULL); - BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false); + BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false); void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks); - void EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail); + void EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail); bool CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None); bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting); BfType* GetClosestNumericCastType(const BfTypedValue& typedVal, BfType* wantType); @@ -1679,33 +1706,34 @@ public: void CleanupFileInstances(); void AssertErrorState(); void AssertParseErrorState(); - void InitTypeInst(BfTypedValue typedValue, BfScopeData* scope, bool zeroMemory, BfIRValue dataSize); + void InitTypeInst(BfTypedValue typedValue, BfScopeData* scope, bool zeroMemory, BfIRValue dataSize); + bool IsAllocatorAligned(); BfIRValue AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTarget, BfType* type, BfIRValue sizeValue, BfIRValue alignValue, BfAllocFlags allocFlags/*bool zeroMemory, bool defaultToMalloc*/); BfIRValue GetMarkFuncPtr(BfType* type); BfIRValue GetDbgRawAllocData(BfType* type); BfIRValue AllocFromType(BfType* type, const BfAllocTarget& allocTarget, BfIRValue appendSizeValue = BfIRValue(), BfIRValue arraySize = BfIRValue(), int arrayDim = 0, /*bool isRawArrayAlloc = false, bool zeroMemory = true*/BfAllocFlags allocFlags = BfAllocFlags_ZeroMemory, int alignOverride = -1); void ValidateAllocation(BfType* type, BfAstNode* refNode); bool IsOptimized(); - void EmitAlign(BfIRValue& appendCurIdx, int align); void EmitAppendAlign(int align, int sizeMultiple = 0); - BfIRValue AppendAllocFromType(BfType* type, BfIRValue appendSizeValue = BfIRValue(), int appendAllocAlign = 0, BfIRValue arraySize = BfIRValue(), int arrayDim = 0, bool isRawArrayAlloc = false, bool zeroMemory = true); + BfIRValue AppendAllocFromType(BfType* type, BfIRValue appendSizeValue = BfIRValue(), int appendAllocAlign = 0, BfIRValue arraySize = BfIRValue(), int arrayDim = 0, bool isRawArrayAlloc = false, bool zeroMemory = true); bool IsTargetingBeefBackend(); bool WantsLifetimes(); bool HasCompiledOutput(); bool HasExecutedOutput(); void SkipObjectAccessCheck(BfTypedValue typedVal); - void EmitObjectAccessCheck(BfTypedValue typedVal); + void EmitObjectAccessCheck(BfTypedValue typedVal); void EmitEnsureInstructionAt(); void EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds = false); void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull); - void CheckStaticAccess(BfTypeInstance* typeInstance); + void CheckStaticAccess(BfTypeInstance* typeInstance); BfTypedValue RemoveRef(BfTypedValue typedValue); + BfTypedValue SanitizeAddr(BfTypedValue typedValue); BfTypedValue ToRef(BfTypedValue typedValue, BfRefType* refType = NULL); BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue); - BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false); + BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false); BfTypedValue PrepareConst(BfTypedValue& typedValue); void AggregateSplatIntoAddr(BfTypedValue typedValue, BfIRValue addrVal); - BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL); + BfTypedValue AggregateSplat(BfTypedValue typedValue, BfIRValue* valueArrPtr = NULL); BfTypedValue MakeAddressable(BfTypedValue typedValue, bool forceMutable = false, bool forceAddressable = false); BfTypedValue RemoveReadOnly(BfTypedValue typedValue); BfTypedValue CopyValue(const BfTypedValue& typedValue); @@ -1735,13 +1763,13 @@ public: virtual void Visit(BfIdentifierNode* identifierNode) override; virtual void Visit(BfTypeReference* typeRef) override; virtual void Visit(BfEmptyStatement* astNode) override; - virtual void Visit(BfExpression* expressionStmt) override; + virtual void Visit(BfExpression* expressionStmt) override; virtual void Visit(BfExpressionStatement* expressionStmt) override; virtual void Visit(BfVariableDeclaration* varDecl) override; virtual void Visit(BfLocalMethodDeclaration* methodDecl) override; virtual void Visit(BfAttributedStatement* attribStmt) override; virtual void Visit(BfThrowStatement* throwStmt) override; - virtual void Visit(BfDeleteStatement* deleteStmt) override; + virtual void Visit(BfDeleteStatement* deleteStmt) override; virtual void Visit(BfSwitchStatement* switchStmt) override; virtual void Visit(BfTryStatement* tryStmt) override; virtual void Visit(BfCatchStatement* catchStmt) override; @@ -1749,7 +1777,7 @@ public: virtual void Visit(BfCheckedStatement* checkedStmt) override; virtual void Visit(BfUncheckedStatement* uncheckedStmt) override; void DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool includeFalseStmt); - virtual void Visit(BfIfStatement* ifStmt) override; + virtual void Visit(BfIfStatement* ifStmt) override; virtual void Visit(BfReturnStatement* returnStmt) override; virtual void Visit(BfYieldStatement* yieldStmt) override; virtual void Visit(BfBreakStatement* breakStmt) override; @@ -1768,7 +1796,7 @@ public: virtual void Visit(BfRootNode* rootNode) override; virtual void Visit(BfInlineAsmStatement* asmStmt) override; - // Type helpers + // Type helpers BfGenericExtensionEntry* BuildGenericExtensionInfo(BfTypeInstance* genericTypeInst, BfTypeDef* partialTypeDef); bool InitGenericParams(BfType* resolvedTypeRef); bool FinishGenericParams(BfType* resolvedTypeRef); @@ -1782,12 +1810,12 @@ public: void InitType(BfType* resolvedTypeRef, BfPopulateType populateType); BfProtection FixProtection(BfProtection protection, BfProject* defProject); bool CheckAccessMemberProtection(BfProtection protection, BfTypeInstance* memberType); - bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType); - void CheckMemberNames(BfTypeInstance* typeInst); + bool CheckDefineMemberProtection(BfProtection protection, BfType* memberType); + void CheckMemberNames(BfTypeInstance* typeInst); void AddDependency(BfType* usedType, BfType* userType, BfDependencyMap::DependencyFlags flags, BfDepContext* depContext = NULL); void AddDependency(BfGenericParamInstance* genericParam, BfTypeInstance* usingType); void AddCallDependency(BfMethodInstance* methodInstance, bool devirtualized = false); - void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType); + void AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType); void TypeFailed(BfTypeInstance* typeInstance); bool IsAttribute(BfTypeInstance* typeInst); void PopulateGlobalContainersList(const BfGlobalLookup& globalLookup); @@ -1813,11 +1841,12 @@ public: void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred); void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred); void DoCEEmit(BfMethodInstance* methodInstance); + void PopulateUsingFieldData(BfTypeInstance* typeInstance); void DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias); void DoPopulateType_InitSearches(BfTypeInstance* typeInstance); - void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance); + void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance); void DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType); - void DoPopulateType_CeCheckEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred); + void DoPopulateType_CeCheckEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred); void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data); static BfModule* GetModuleFor(BfType* type); void DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance); @@ -1826,9 +1855,10 @@ public: void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false); void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = false); BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL, bool doStore = false); + void AppendedObjectInit(BfFieldInstance* fieldInstance); void MarkFieldInitialized(BfFieldInstance* fieldInstance); bool IsThreadLocal(BfFieldInstance* fieldInstance); - BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field); + BfType* ResolveVarFieldType(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field); void FindSubTypes(BfTypeInstance* classType, SizedArrayImpl* outVals, SizedArrayImpl* exChecks, bool isInterfacePass); BfType* CheckUnspecializedGenericType(BfTypeInstance* genericTypeInst, BfPopulateType populateType); BfTypeInstance* GetUnspecializedTypeInstance(BfTypeInstance* typeInst); @@ -1847,7 +1877,7 @@ public: BfConcreteInterfaceType* CreateConcreteInterfaceType(BfTypeInstance* interfaceType); BfTypeInstance* GetWrappedStructType(BfType* type, bool allowSpecialized = true); BfTypeInstance* GetPrimitiveStructType(BfTypeCode typeCode); - BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode); + BfPrimitiveType* GetPrimitiveType(BfTypeCode typeCode); BfIRType GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode loweredTypeCode2); BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false); BfType* FixIntUnknown(BfType* type); @@ -1863,7 +1893,7 @@ public: BfIRValue AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd = true); void DoAddLocalVariable(BfLocalVariable* localVar); void DoLocalVariableDebugInfo(BfLocalVariable* localVar, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); - BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); + BfLocalVariable* AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo = false, bool doAliasValue = false, BfIRValue declareBefore = BfIRValue(), BfIRInitType initType = BfIRInitType_NotSet); bool TryLocalVariableInit(BfLocalVariable* localVar); void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit); void CreateRetValLocal(); @@ -1872,29 +1902,30 @@ public: void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType); void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock = NULL); void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl); - void HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart, + void HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart, BfIRBlock& matchedBlockEnd, BfIRBlock& falseBlockStart, BfIRBlock& falseBlockEnd, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough); BfTypedValue TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpression* tupleExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough); BfTypedValue TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVal, BfExpression* expr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int& uncondTagId, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough); BfTypedValue HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock = NULL, BfIRBlock* notEqBlock = NULL, BfIRBlock* matchBlock = NULL, int* outEnumIdx = NULL); void TryInitVar(BfAstNode* checkNode, BfLocalVariable* varDecl, BfTypedValue initValue, BfTypedValue& checkResult); BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfExprEvaluator* exprEvaluator = NULL); + BfLocalVariable* HandleVariableDeclaration(BfType* type, BfAstNode* nameNode, BfTypedValue val, bool updateSrcLoc = true, bool forceAddr = false); BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc = true, bool forceAddr = false); - void CheckVariableDef(BfLocalVariable* variableDef); + void CheckVariableDef(BfLocalVariable* variableDef); BfScopeData* FindScope(BfAstNode* scopeName, BfMixinState* curMixinState, bool allowAcrossDeferredBlock); BfScopeData* FindScope(BfAstNode* scopeName, bool allowAcrossDeferredBlock); BfBreakData* FindBreakData(BfAstNode* scopeName); void EmitLifetimeEnds(BfScopeData* scopeData); void ClearLifetimeEnds(); - bool HasDeferredScopeCalls(BfScopeData* scope); - void EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scope, BfIRBlock doneBlock = BfIRBlock()); + bool HasDeferredScopeCalls(BfScopeData* scope); + void EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scope, BfIRBlock doneBlock = BfIRBlock()); void MarkScopeLeft(BfScopeData* scopeData, bool isNoReturn = false); BfGenericParamType* GetGenericParamType(BfGenericParamKind paramKind, int paramIdx); BfType* ResolveGenericType(BfType* unspecializedType, BfTypeVector* typeGenericArguments, BfTypeVector* methodGenericArguments, BfType* selfType, bool allowFail = false); BfType* ResolveSelfType(BfType* type, BfType* selfType); bool IsUnboundGeneric(BfType* type); BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx); - BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type); + BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false); void GetActiveTypeGenericParamInstances(SizedArray& genericParamInstance); BfGenericParamInstance* GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint); BfTypeInstance* GetBaseType(BfTypeInstance* typeInst); @@ -1904,8 +1935,8 @@ public: bool ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef); BfType* ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTypeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags); void ShowAmbiguousTypeError(BfAstNode* refNode, BfTypeDef* typeDef, BfTypeDef* otherTypeDef); - void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams); - BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call + void ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericParams); + BfTypeDef* GetActiveTypeDef(BfTypeInstance* typeInstanceOverride = NULL, bool useMixinDecl = false); // useMixinDecl is useful for type lookup, but we don't want the decl project to limit what methods the user can call BfTypeDef* FindTypeDefRaw(const BfAtomComposite& findName, int numGenericArgs, BfTypeInstance* typeInstance, BfTypeDef* useTypeDef, BfTypeLookupError* error, BfTypeLookupResultCtx* lookupResultCtx = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfTypeInstance* typeInstanceOverride = NULL, BfTypeLookupError* error = NULL, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); @@ -1914,7 +1945,7 @@ public: void CheckTypeRefFixit(BfAstNode* typeRef, const char* appendName = NULL); void CheckIdentifierFixit(BfAstNode* node); void TypeRefNotFound(BfTypeReference* typeRef, const char* appendName = NULL); - bool ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef); + bool ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef); void GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention); BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, int numGenericArgs = 0); BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool resolveGenericParam = true); @@ -1922,23 +1953,23 @@ public: BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); BfType* ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); - BfType* ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false, int numGenericArgs = 0); + BfType* ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool ignoreErrors = false, int numGenericArgs = 0, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); BfTypeDef* GetCombinedPartialTypeDef(BfTypeDef* type); BfTypeInstance* GetOuterType(BfType* type); - bool IsInnerType(BfType* checkInnerType, BfType* checkOuterType); + bool IsInnerType(BfType* checkInnerType, BfType* checkOuterType); bool IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType); bool TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* checkParentTypeDef); - BfTypeDef* FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2); + BfTypeDef* FindCommonOuterType(BfTypeDef* type, BfTypeDef* type2); bool TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType, bool checkAccessibility = true); bool TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeDef* wantType); int GetTypeDistance(BfType* fromType, BfType* toType); - bool IsTypeMoreSpecific(BfType* leftType, BfType* rightType); + bool IsTypeMoreSpecific(BfType* leftType, BfType* rightType); bool GetBasePropertyDef(BfPropertyDef*& propDef, BfTypeInstance*& typeInst); - + // Method helpers - void CheckInterfaceMethod(BfMethodInstance* methodInstance); + void CheckInterfaceMethod(BfMethodInstance* methodInstance); void CreateDelegateInvokeMethod(); - BfType* GetDelegateReturnType(BfType* delegateType); + BfType* GetDelegateReturnType(BfType* delegateType); BfMethodInstance* GetDelegateInvokeMethod(BfTypeInstance* typeInstance); String GetLocalMethodName(const StringImpl& baseName, BfAstNode* anchorNode, BfMethodState* declMethodState, BfMixinState* declMixinState); BfMethodDef* GetLocalMethodDef(BfLocalMethod* localMethod); @@ -1952,20 +1983,21 @@ public: void AddMethodToWorkList(BfMethodInstance* methodInstance); bool IsInterestedInMethod(BfTypeInstance* typeInstance, BfMethodDef* methodDef); void CalcAppendAlign(BfMethodInstance* methodInst); - BfTypedValue TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl& args); + BfTypedValue TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl& args, bool force = false); BfTypedValue CallBaseCtorCalc(bool constOnly); - void EmitCtorCalcAppend(); - void CreateStaticCtor(); + void EmitCtorCalcAppend(); + void CreateStaticCtor(); BfIRValue CreateDllImportGlobalVar(BfMethodInstance* methodInstance, bool define = false); - void CreateDllImportMethod(); + void CreateDllImportMethod(); BfIRCallingConv GetIRCallingConvention(BfMethodInstance* methodInstance); void SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined); void EmitInitBlocks(const std::function& initBlockCallback); void EmitCtorBody(bool& skipBody); void EmitDtorBody(); void EmitEnumToStringBody(); - void EmitTupleToStringBody(); - void EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int memberDepth, int curOffset, HashSet& objectOffsets, BfModuleMethodInstance markFromGCThreadMethodInstance); + void EmitTupleToStringBody(); + void EmitGCMarkAppended(BfTypedValue markVal); + void EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int memberDepth, int curOffset, HashSet& objectOffsets, BfModuleMethodInstance markFromGCThreadMethodInstance, bool isAppendObject = false); void EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance markFromGCThreadMethodInstance); void EmitGCMarkMembers(); void EmitGCFindTLSMembers(); @@ -1982,7 +2014,7 @@ public: void CreateValueTypeEqualsMethod(bool strictEquals); BfIRFunction GetIntrinsic(BfMethodInstance* methodInstance, bool reportFailure = false); BfIRFunction GetBuiltInFunc(BfBuiltInFuncType funcType); - BfIRValue CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined); + BfIRValue CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined); void EvaluateWithNewConditionalScope(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfEvalExprFlags flags); BfTypedValue CreateValueFromExpression(BfExprEvaluator& exprEvaluator, BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL); BfTypedValue CreateValueFromExpression(BfExpression* expr, BfType* wantTypeRef = NULL, BfEvalExprFlags flags = BfEvalExprFlags_None, BfType** outOrigType = NULL); @@ -1990,9 +2022,9 @@ public: BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL); BfMethodInstance* GetRawMethodInstance(BfTypeInstance* typeInstance, BfMethodDef* methodDef); BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false); - BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType = true); // Unspecialized owner type and unspecialized method type - int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance); - BfModule* GetSpecializedMethodModule(const SizedArrayImpl& projectList); + BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType = true); // Unspecialized owner type and unspecialized method type + int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance); + BfModule* GetSpecializedMethodModule(const SizedArrayImpl& projectList); BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None); BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false); BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, const Array& paramTypes, bool checkBase = false); @@ -2004,15 +2036,15 @@ public: bool CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstance* methodB); // Doesn't compare return types nor static bool StrictCompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstance* methodB); // Compares return types and static bool IsCompatibleInterfaceMethod(BfMethodInstance* methodA, BfMethodInstance* methodB); - void UniqueSlotVirtualMethod(BfMethodInstance* methodInstance); - void CompareDeclTypes(BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse); - bool SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityContext* ambiguityContext = NULL); + void UniqueSlotVirtualMethod(BfMethodInstance* methodInstance); + void CompareDeclTypes(BfTypeInstance* typeInst, BfTypeDef* newDeclType, BfTypeDef* prevDeclType, bool& isBetter, bool& isWorse); + bool SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityContext* ambiguityContext = NULL); void CheckOverridenMethod(BfMethodInstance* methodInstance, BfMethodInstance* methodOverriden); - bool SlotInterfaceMethod(BfMethodInstance* methodInstance); + bool SlotInterfaceMethod(BfMethodInstance* methodInstance); void SetMethodDependency(BfMethodInstance* methodInstance); BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None); BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance); - BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL); + BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL); BfModuleMethodInstance GetMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None); BfMethodInstance* GetOuterMethodInstance(BfMethodInstance* methodInstance); // Only useful for local methods void SetupMethodIdHash(BfMethodInstance* methodInstance); @@ -2032,7 +2064,7 @@ public: BfModule(BfContext* context, const StringImpl& moduleName); virtual ~BfModule(); - void Init(bool isFullRebuild = true); + void Init(bool isFullRebuild = true); bool WantsFinishModule(); bool IsHotCompile(); void FinishInit(); @@ -2048,7 +2080,7 @@ public: BfIRValue CreateForceLinkMarker(BfModule* module, String* outName); void ClearModuleData(bool clearTransientData = true); void DisownMethods(); - void ClearModule(); + void ClearModule(); void StartExtension(); // For new method specializations bool Finish(); void RemoveModuleData(); @@ -2074,7 +2106,6 @@ public: } }; - class BfVDataModule : public BfModule { public: @@ -2117,5 +2148,5 @@ namespace std { return std::hash()(val.mLocalVar->mName); } - }; + }; } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 222db82e..19222aa2 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -11,6 +11,7 @@ #include "BfMangler.h" #include "BeefySysLib/util/PerfTimer.h" #include "BeefySysLib/util/BeefPerf.h" +#include "BeefySysLib/util/StackHelper.h" #include "BfSourceClassifier.h" #include "BfAutoComplete.h" #include "BfDemangler.h" @@ -88,7 +89,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen if (autoComplete != NULL) autoComplete->CheckTypeRef(genericConstraint.mTypeRef, false); - if (genericParamInstance->mExternType == NULL) + if (genericParamInstance->mExternType == NULL) genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var); ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType()); @@ -108,7 +109,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen } for (auto genericParam : genericExEntry->mGenericParams) - AddDependency(genericParam, mCurTypeInstance); + AddDependency(genericParam, mCurTypeInstance); ValidateGenericParams(BfGenericParamKind_Type, Span((BfGenericParamInstance**)genericExEntry->mGenericParams.mVals, @@ -123,7 +124,7 @@ bool BfModule::InitGenericParams(BfType* resolvedTypeRef) typeState.mPrevState = mContext->mCurTypeState; typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams; typeState.mType = resolvedTypeRef; - SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); + SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); BF_ASSERT(mCurMethodInstance == NULL); @@ -145,14 +146,14 @@ bool BfModule::InitGenericParams(BfType* resolvedTypeRef) auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, paramIdx); genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx); genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance); - } + } for (int externConstraintIdx = 0; externConstraintIdx < (int)typeDef->mExternalConstraints.size(); externConstraintIdx++) { auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, externConstraintIdx + (int)typeDef->mGenericParamDefs.size()); genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance); } - + return true; } @@ -247,7 +248,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) genericExtensionInfo->mConstraintsPassedSet.Resize(typeDef->mPartials.mSize); extensionCount++; - + if (!genericTypeInst->IsUnspecializedType()) { SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); @@ -280,7 +281,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) genericExtensionInfo->mConstraintsPassedSet.Set(partialTypeDef->mPartialIdx); BfLogSysM("BfModule::FinishGenericParams %p partialTypeDef:%p passed:%d\n", resolvedTypeRef, partialTypeDef, genericExEntry->mConstraintsPassed); - } + } } auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo; @@ -330,19 +331,19 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef) for (auto typeRef : deferredResolveTypes) auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None); - - ValidateGenericParams(BfGenericParamKind_Type, - Span((BfGenericParamInstance**)genericTypeInst->mGenericTypeInfo->mGenericParams.mVals, + + ValidateGenericParams(BfGenericParamKind_Type, + Span((BfGenericParamInstance**)genericTypeInst->mGenericTypeInfo->mGenericParams.mVals, genericTypeInst->mGenericTypeInfo->mGenericParams.mSize)); - for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams) - AddDependency(genericParam, mCurTypeInstance); + for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams) + AddDependency(genericParam, mCurTypeInstance); return true; } void BfModule::ValidateGenericParams(BfGenericParamKind genericParamKind, Span genericParams) -{ +{ std::function&)> _CheckType = [&](BfType* type, Array& foundParams) { if (type == NULL) @@ -352,11 +353,11 @@ void BfModule::ValidateGenericParams(BfGenericParamKind genericParamKind, SpanmGenericParamKind != genericParamKind) return; - + auto genericParam = genericParams[genericParamType->mGenericParamIdx]; if (genericParam->mTypeConstraint == NULL) return; - + if (foundParams.Contains(genericParamType)) { String error = "Circular constraint dependency between "; @@ -384,7 +385,7 @@ void BfModule::ValidateGenericParams(BfGenericParamKind genericParamKind, SpanmTypeConstraint != NULL) { Array foundParams; @@ -432,8 +433,8 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge if (genericArg != NULL) genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->mGenericTypeInfo->mMaxGenericDepth + 1); } - - auto typeDef = genericTypeInst->mTypeDef; + + auto typeDef = genericTypeInst->mTypeDef; int startGenericParamIdx = 0; if (typeDef->mOuterType != NULL) @@ -441,14 +442,14 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize; auto outerType = GetOuterType(genericTypeInst); PopulateType(outerType, BfPopulateType_Declaration); - if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors)) + if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors)) genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true; } for (int paramIdx = startGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++) { auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx]; - + BfType* genericArg; if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size()) { @@ -465,8 +466,8 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge if (!genericTypeInst->IsUnspecializedTypeVariation()) genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true; return false; - } - } + } + } return true; } @@ -514,7 +515,7 @@ bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGeneri outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Struct); else if (checkOuter->mTypeConstraint->IsStructOrStructPtr()) outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_StructPtr); - else if (checkOuter->mTypeConstraint->IsObject()) + else if ((checkOuter->mTypeConstraint->IsObject()) && (!checkOuter->mTypeConstraint->IsDelegate())) outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Class); else if (checkOuter->mTypeConstraint->IsEnum()) outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Enum | BfGenericParamFlag_Struct); @@ -533,13 +534,13 @@ bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGeneri if (checkInner->mTypeConstraint != NULL) { if (checkOuter->mTypeConstraint == NULL) - return false; + return false; if (!TypeIsSubTypeOf(checkOuter->mTypeConstraint->ToTypeInstance(), checkInner->mTypeConstraint->ToTypeInstance())) - return false; + return false; } - + for (auto innerIFace : checkInner->mInterfaceConstraints) - { + { if (checkOuter->mInterfaceConstraints.IsEmpty()) return false; @@ -554,10 +555,10 @@ bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGeneri for (auto& ifaceEntry : ifaceType->mInterfaces) _AddInterface(ifaceEntry.mInterfaceType); }; - + checkOuter->mInterfaceConstraintSet = new HashSet(); - for (auto outerIFace : checkOuter->mInterfaceConstraints) - _AddInterface(outerIFace); + for (auto outerIFace : checkOuter->mInterfaceConstraints) + _AddInterface(outerIFace); } if (!checkOuter->mInterfaceConstraintSet->Contains(innerIFace)) @@ -642,7 +643,7 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance) { if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL)) { - auto typeDef = typeInstance->mTypeDef; + auto typeDef = typeInstance->mTypeDef; if (typeDef->mEmitParent != NULL) typeDef = typeDef->mEmitParent; if (typeDef->mNextRevision != NULL) @@ -678,7 +679,7 @@ void BfModule::CheckInjectNewRevision(BfTypeInstance* typeInstance) void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) { BP_ZONE("BfModule::InitType"); - + if (auto depType = resolvedTypeRef->ToDependedType()) { if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodInfoEx != NULL)) @@ -717,7 +718,7 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) typeInst->mIsReified = mIsReified; //BF_ASSERT(typeInst->mTypeDef->mTypeCode != BfTypeCode_Extension); - + typeInst->mRevision = mCompiler->mRevision; if (typeInst->mTypeDef != NULL) BF_ASSERT(typeInst->mTypeDef->mDefState != BfTypeDef::DefState_Deleted); @@ -726,7 +727,7 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) { auto tupleType = (BfTypeInstance*)resolvedTypeRef; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) - { + { auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx]; // We need to make sure dependencies get set immediately since we already resolved the types AddFieldDependency(typeInst, fieldInstance, fieldInstance->mResolvedType); @@ -739,7 +740,7 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) auto genericTypeInst = (BfTypeInstance*)resolvedTypeRef; for (auto typeGenericArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments) { - BF_ASSERT((typeGenericArg->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0); + BF_ASSERT((typeGenericArg->mRebuildFlags & BfTypeRebuildFlag_Deleted) == 0); if (mIsReified) { // Try to reify any generic args @@ -785,7 +786,7 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) resolvedTypeRef->mContext = mContext; if (resolvedTypeRef->IsGenericTypeInstance()) { - auto genericTypeInstance = (BfTypeInstance*)resolvedTypeRef; + auto genericTypeInstance = (BfTypeInstance*)resolvedTypeRef; #ifdef _DEBUG for (auto genericArg : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments) @@ -809,16 +810,19 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) { BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc(); typeProcessRequest->mType = resolvedTypeRef; - BF_ASSERT(resolvedTypeRef->mContext == mContext); + BF_ASSERT(resolvedTypeRef->mContext == mContext); mCompiler->mStats.mTypesQueued++; mCompiler->UpdateCompletion(); } - PopulateType(resolvedTypeRef, populateType); + PopulateType(resolvedTypeRef, populateType); } void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfType* fieldType) { auto depFlag = fieldType->IsValueType() ? BfDependencyMap::DependencyFlag_ValueTypeMemberData : BfDependencyMap::DependencyFlag_PtrMemberData; + if (fieldInstance->IsAppendedObject()) + depFlag = BfDependencyMap::DependencyFlag_ValueTypeMemberData; + AddDependency(fieldType, typeInstance, depFlag); if ((fieldType->IsStruct()) && (fieldType->IsGenericTypeInstance())) @@ -860,12 +864,12 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) BfTypeInstance* mTypeInst; BfAstNode* mNameNode; BfProtection mProtection; - BfTypeDef* mDeclaringType; + BfTypeDef* mDeclaringType; bool mIsOverride; }; SizedArray memberList; - + // Check base types first and then current type auto checkType = typeInst; while (checkType != NULL) @@ -938,10 +942,10 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) if (memberMap.TryGetValue(memberRef.mName, &prevMemberRef)) { //auto& prevMemberRef = itr->second; - + MemberRef* firstMemberRef = &memberRef; MemberRef* secondMemberRef = prevMemberRef; - bool showPrevious = false; + bool showPrevious = false; BfError* error = NULL; if (prevMemberRef->mTypeInst != typeInst) @@ -983,7 +987,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) { std::swap(firstMemberRef, secondMemberRef); } - + if (typeInst->mTypeDef->mIsCombinedPartial) { if ((firstMemberRef->mKindName == "property") && (secondMemberRef->mKindName == "property")) @@ -1017,7 +1021,7 @@ void BfModule::TypeFailed(BfTypeInstance* typeInstance) typeInstance->mTypeFailed = true; // Punt on field types - just substitute 'var' where we have NULLs for (auto& fieldInstance : typeInstance->mFieldInstances) - { + { if ((fieldInstance.mResolvedType == NULL) || (fieldInstance.mResolvedType->IsNull())) { if (fieldInstance.mDataIdx >= 0) @@ -1030,12 +1034,12 @@ void BfModule::TypeFailed(BfTypeInstance* typeInstance) typeInstance->mAlign = 1; if (typeInstance->mSize == -1) typeInstance->mSize = 1; - mContext->mFailTypes.Add(typeInstance); + mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal); mHadBuildError = true; } -bool BfModule::CheckCircularDataError() -{ +bool BfModule::CheckCircularDataError(bool failTypes) +{ // Find two loops of mCurTypeInstance. Just finding one loop can give some false errors. BfTypeState* circularTypeStateEnd = NULL; @@ -1100,10 +1104,13 @@ bool BfModule::CheckCircularDataError() ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance()))) return hadError; + hadError = true; + if (!failTypes) + return hadError; + // We only get one chance to fire off these errors, they can't be ignored. SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, false); - hadError = true; if (checkTypeState->mCurAttributeTypeRef != NULL) { Fail(StrFormat("Attribute type '%s' causes a data cycle", BfTypeUtils::TypeToString(checkTypeState->mCurAttributeTypeRef).c_str()), checkTypeState->mCurAttributeTypeRef, true); @@ -1144,7 +1151,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType return; if ((resolvedTypeRef->mRebuildFlags & BfTypeRebuildFlag_PendingGenericArgDep) != 0) - { + { BfLogSysM("PopulateType handling BfTypeRebuildFlag_PendingGenericArgDep for type %p\n", resolvedTypeRef); // Reinit dependencies resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~BfTypeRebuildFlag_PendingGenericArgDep); @@ -1165,14 +1172,14 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType BfLogSysM("Reifying type %p in scratch module in PopulateType\n", resolvedTypeRef); // It's important for unspecialized types to be in the correct module -- - // when we process their methods, new types will be determined as + // when we process their methods, new types will be determined as // resolve-only or reified based on the module the unresolved type is in BF_ASSERT(typeInst->mModule == mContext->mUnreifiedModule); typeInst->mIsReified = true; typeInst->mModule = mContext->mScratchModule; - // Why did we need to do this at all? Why is just marking the type as reified not enough? - // This causes issues where we may delete a method instance that is currently being used as the generic bindings for + // Why did we need to do this at all? Why is just marking the type as reified not enough? + // This causes issues where we may delete a method instance that is currently being used as the generic bindings for // a method of a specialized generic type // if (typeInst->IsOnDemand()) // { @@ -1192,7 +1199,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType } } else - { + { if ((typeModule != NULL) && (!typeModule->mIsReified) && (!typeModule->mReifyQueued)) { bool canFastReify = false; @@ -1209,7 +1216,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule); typeModule->mIsReified = true; typeModule->CalcGeneratesCode(); - typeModule->mWantsIRIgnoreWrites = false; + typeModule->mWantsIRIgnoreWrites = false; for (auto ownedTypes : typeModule->mOwnedTypeInstances) { ownedTypes->mIsReified = true; @@ -1234,7 +1241,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType typeModule->SetupIRBuilder(false); } else - typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance()); + typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance()); } else { @@ -1253,6 +1260,22 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType } } } + else + { + // If we're a type like "A*", make sure we reify "A" if necessary + auto checkUnderlying = resolvedTypeRef->GetUnderlyingType(); + while (checkUnderlying != NULL) + { + auto checkTypeInst = checkUnderlying->ToTypeInstance(); + if (checkTypeInst != NULL) + { + if (!checkTypeInst->mIsReified) + PopulateType(checkTypeInst, BfPopulateType_BaseType); + break; + } + checkUnderlying = checkUnderlying->GetUnderlyingType(); + } + } } if (!resolvedTypeRef->IsIncomplete()) @@ -1260,9 +1283,9 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (populateType <= BfPopulateType_TypeDef) return; - + auto typeInstance = resolvedTypeRef->ToTypeInstance(); - CheckInjectNewRevision(typeInstance); + CheckInjectNewRevision(typeInstance); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); @@ -1329,7 +1352,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType return; } - if (resolvedTypeRef->IsTypeAlias()) + if (resolvedTypeRef->IsTypeAlias()) { // Always populate these all the way if (populateType != BfPopulateType_IdentityNoRemapAlias) @@ -1337,7 +1360,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType } if (resolvedTypeRef->IsSizedArray()) - { + { resolvedTypeRef->mRevision = mRevision; bool typeFailed = false; @@ -1362,7 +1385,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType PopulateType(arrayType->mElementType, BfPopulateType_Identity); } resolvedTypeRef->mDefineState = arrayType->mElementType->mDefineState; - AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_ValueTypeMemberData); + AddDependency(elementType, resolvedTypeRef, BfDependencyMap::DependencyFlag_ValueTypeMemberData); } else { @@ -1405,8 +1428,8 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType bool isValueless = arrayType->IsValuelessType(); return; - } - + } + if (isNew) { BfTypeDef* typeDef = NULL; @@ -1443,7 +1466,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType if (resolvedTypeRef->IsModifiedTypeType()) { BfModifiedTypeType* retTypeType = (BfModifiedTypeType*)resolvedTypeRef; - BF_ASSERT(retTypeType->mElementType->IsGenericParam()); + BF_ASSERT(retTypeType->mElementType->IsGenericParam()); resolvedTypeRef->mSize = mContext->mBfObjectType->mSize; resolvedTypeRef->mAlign = mContext->mBfObjectType->mAlign; resolvedTypeRef->mDefineState = BfTypeDefineState_Defined; @@ -1467,7 +1490,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType resolvedTypeRef->mDefineState = BfTypeDefineState_Defined; return; } - + // The autocomplete pass doesn't need to do the method processing, allow type to be (partially) incomplete if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (typeInstance != NULL) && (typeInstance->mNeedsMethodProcessing) && (!typeInstance->IsDelegate())) @@ -1497,7 +1520,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType case BfTypeCode_Let: { primitiveType->mSize = mSystem->mPtrSize; - primitiveType->mAlign = mSystem->mPtrSize; + primitiveType->mAlign = mSystem->mPtrSize; resolvedTypeRef->mDefineState = BfTypeDefineState_Defined; } return; @@ -1552,7 +1575,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType PRIMITIVE_TYPE("uintptr", Int64, 8, DW_ATE_unsigned); } return; - case BfTypeCode_IntUnknown: + case BfTypeCode_IntUnknown: case BfTypeCode_UIntUnknown: return; case BfTypeCode_Char8: @@ -1573,24 +1596,24 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType case BfTypeCode_Object: case BfTypeCode_Struct: case BfTypeCode_Interface: - case BfTypeCode_Enum: + case BfTypeCode_Enum: case BfTypeCode_TypeAlias: // Implemented below break; case BfTypeCode_Extension: - // This can only happen if we didn't actually find the type the extension referred to + // This can only happen if we didn't actually find the type the extension referred to break; default: //NotImpl(resolvedTypeRef->mTypeRef); BFMODULE_FATAL(this, "Invalid type"); return; } - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// BF_ASSERT(typeInstance != NULL); if (!typeInstance->IsArray()) - { + { BF_ASSERT(typeInstance->mTypeDef != mContext->mCompiler->mArray1TypeDef); } @@ -1618,7 +1641,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType return; } - typeInstance->mModule->DoPopulateType(typeInstance, populateType); + typeInstance->mModule->DoPopulateType(typeInstance, populateType); } BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) @@ -1629,7 +1652,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) } Array matchedIndices; - + if (!mCompiler->mAttributeTypeOptionMap.IsEmpty()) { auto customAttributes = typeDef->mTypeDeclaration->mAttributes; @@ -1663,7 +1686,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) } int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size(); - + auto _CheckTypeName = [&](const StringImpl& typeName) { for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++) @@ -1773,7 +1796,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) // if (typeInstance->IsTypedPrimitive()) // { // auto underlyingType = typeInstance->GetUnderlyingType(); -// if (underlyingType != NULL) +// if (underlyingType != NULL) // { // String typeName = TypeToString(underlyingType); // _CheckTypeName(typeName); @@ -1783,7 +1806,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) // // Can this only happen for functions that are being extended? // } // } -// +// // if ((!typeInstance->IsBoxed()) && (typeInstance->mTypeDef == mCompiler->mPointerTTypeDef)) // { // BF_ASSERT(typeInstance->IsGenericTypeInstance()); @@ -1794,7 +1817,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) // } String typeName = BfTypeUtils::TypeToString(typeDef); - _CheckTypeName(typeName); + _CheckTypeName(typeName); int matchedIdx = -1; if (matchedIndices.size() == 1) @@ -1823,8 +1846,8 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) mergedTypeOptions.mOptimizationLevel = first.mOptimizationLevel; mergedTypeOptions.mEmitDebugInfo = first.mEmitDebugInfo; mergedTypeOptions.mAndFlags = first.mAndFlags; - mergedTypeOptions.mOrFlags = first.mOrFlags; - mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth; + mergedTypeOptions.mOrFlags = first.mOrFlags; + mergedTypeOptions.mAllocStackTraceDepth = first.mAllocStackTraceDepth; mergedTypeOptions.mReflectMethodFilters = first.mReflectMethodFilters; mergedTypeOptions.mReflectMethodAttributeFilters = first.mReflectMethodAttributeFilters; @@ -1838,13 +1861,13 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) mergedTypeOptions.mOptimizationLevel = typeOptions.mOptimizationLevel; if (typeOptions.mEmitDebugInfo != -1) mergedTypeOptions.mEmitDebugInfo = typeOptions.mEmitDebugInfo; - + mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags | typeOptions.mOrFlags); mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | typeOptions.mOrFlags); mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags & typeOptions.mAndFlags); - mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags); - + mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & typeOptions.mAndFlags); + if (mergedTypeOptions.HasReflectMethodFilters()) { // If merging filter has non-default method flags but no filter then we need to append it as a filtered modification @@ -1856,7 +1879,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) } mergedTypeOptions.mAndFlags = (BfOptionFlags)(mergedTypeOptions.mAndFlags | BfOptionFlags_Reflect_MethodMask); - mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & ~BfOptionFlags_Reflect_MethodMask); + mergedTypeOptions.mOrFlags = (BfOptionFlags)(mergedTypeOptions.mOrFlags & ~BfOptionFlags_Reflect_MethodMask); } if (typeOptions.mAllocStackTraceDepth != -1) @@ -1864,7 +1887,7 @@ BfTypeOptions* BfModule::GetTypeOptions(BfTypeDef* typeDef) for (auto filter : typeOptions.mReflectMethodFilters) mergedTypeOptions.mReflectMethodFilters.Add(filter); for (auto filter : typeOptions.mReflectMethodAttributeFilters) - mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter); + mergedTypeOptions.mReflectMethodAttributeFilters.Add(filter); } matchedIdx = typeOptionsCount + (int)mContext->mSystem->mMergedTypeOptions.size(); mContext->mSystem->mMergedTypeOptions.push_back(mergedTypeOptions); @@ -1900,7 +1923,7 @@ bool BfModule::ApplyTypeOptionMethodFilters(bool includeMethod, BfMethodDef* met if ((filter.mAndFlags | findFlag) != 0) includeMethod = true; } - } + } } return includeMethod; @@ -1948,9 +1971,9 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn int typeOptionsCount = (int)mContext->mSystem->mTypeOptions.size(); if (checkTypeName) - { + { auto _CheckType = [&](BfType* type) - { + { StringImpl typeName = TypeToString(type); for (int optionIdx = 0; optionIdx < (int)mContext->mSystem->mTypeOptions.size(); optionIdx++) @@ -1991,7 +2014,7 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn } if (matched) break; - } + } } else if (BfCheckWildcard(filter, typeName)) { @@ -2009,7 +2032,7 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn { auto underlyingType = typeInstance->GetUnderlyingType(); if (underlyingType != NULL) - { + { _CheckType(underlyingType); } else @@ -2022,10 +2045,10 @@ int BfModule::GenerateTypeOptions(BfCustomAttributes* customAttributes, BfTypeIn { BF_ASSERT(typeInstance->IsGenericTypeInstance()); auto innerType = typeInstance->mGenericTypeInfo->mTypeGenericArguments[0]; - auto ptrType = CreatePointerType(innerType); + auto ptrType = CreatePointerType(innerType); _CheckType(ptrType); } - + _CheckType(typeInstance); } @@ -2101,23 +2124,23 @@ void BfModule::SetTypeOptions(BfTypeInstance* typeInstance) BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* declaringType, const StringImpl& src, BfAstNode* refNode, BfCeTypeEmitSourceKind emitSourceKind) { if (mCompiler->mResolvePassData != NULL) - mCompiler->mResolvePassData->mHadEmits = true; - + mCompiler->mResolvePassData->mHadEmits = true; + BfCEParseContext ceParseContext; ceParseContext.mFailIdx = mCompiler->mPassInstance->mFailedIdx; ceParseContext.mWarnIdx = mCompiler->mPassInstance->mWarnIdx; bool createdParser = false; int startSrcIdx = 0; - + BfParser* emitParser = NULL; - int64 emitSourceMapKey = ((int64)declaringType->mPartialIdx << 32) | refNode->mSrcStart; + int64 emitSourceMapKey = ((int64)declaringType->mPartialIdx << 32) | refNode->mSrcStart; if (typeInstance->mCeTypeInfo == NULL) typeInstance->mCeTypeInfo = new BfCeTypeInfo(); auto ceTypeInfo = typeInstance->mCeTypeInfo; if (ceTypeInfo->mNext != NULL) - ceTypeInfo = ceTypeInfo->mNext; + ceTypeInfo = ceTypeInfo->mNext; BfCeTypeEmitSource* ceEmitSource = NULL; if ((mCurMethodState != NULL) && (mCurMethodState->mClosureState != NULL) && (mCurMethodState->mClosureState->mCapturing)) { @@ -2152,35 +2175,35 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* } ceEmitSource->mKind = emitSourceKind; } - + BfLogSysM("CEEmitParse type %p ceTypeInfo %p\n", typeInstance, ceTypeInfo); int emitSrcStart = 0; BfEmitEmbedEntry* emitEmbedEntry = NULL; - + if (typeInstance->mTypeDef->mEmitParent == NULL) { BF_ASSERT(typeInstance->mTypeDef->mNextRevision == NULL); - + BfTypeDef* emitTypeDef = new BfTypeDef(); emitTypeDef->mEmitParent = typeInstance->mTypeDef; mSystem->CopyTypeDef(emitTypeDef, typeInstance->mTypeDef); emitTypeDef->mDefState = BfTypeDef::DefState_Emitted; - typeInstance->mTypeDef = emitTypeDef; - - createdParser = true; + typeInstance->mTypeDef = emitTypeDef; + + createdParser = true; emitParser = new BfParser(mSystem, typeInstance->mTypeDef->mProject); emitParser->mIsEmitted = true; - + BfLogSys(mSystem, "Emit typeDef for type %p created %p parser %p typeDecl %p\n", typeInstance, emitTypeDef, emitParser, emitTypeDef->mTypeDeclaration); String typeName = TypeToString(typeInstance, BfTypeNameFlag_AddProjectName); - + if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty())) mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(typeName, &emitEmbedEntry); - + emitParser->mFileName = "$Emit$"; emitParser->mFileName += typeName; @@ -2192,7 +2215,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* { emitEmbedEntry->mRevision = typeInstance->mRevision; emitEmbedEntry->mParser = emitParser; - emitEmbedEntry->mParser->mSourceClassifier = new BfSourceClassifier(emitEmbedEntry->mParser, NULL); + emitEmbedEntry->mParser->mSourceClassifier = new BfSourceClassifier(emitEmbedEntry->mParser, NULL); mCompiler->mPassInstance->mFilterErrorsTo.Add(emitEmbedEntry->mParser->mParserData); if (emitEmbedEntry->mCursorIdx != -1) @@ -2207,7 +2230,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* { if (methodInstance == NULL) return; - methodInstance->mMethodDef = emitTypeDef->mMethods[methodInstance->mMethodDef->mIdx]; + methodInstance->mMethodDef = emitTypeDef->mMethods[methodInstance->mMethodDef->mIdx]; }; for (auto& methodInstanceGroup : typeInstance->mMethodInstanceGroups) @@ -2225,7 +2248,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* emitParser = typeInstance->mTypeDef->mSource->ToParser(); if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mEmitEmbedEntries.IsEmpty())) - { + { int dollarPos = (int)emitParser->mFileName.LastIndexOf('$'); if (dollarPos != -1) mCompiler->mResolvePassData->mEmitEmbedEntries.TryGetValue(emitParser->mFileName.Substring(dollarPos + 1), &emitEmbedEntry); @@ -2253,7 +2276,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* { // Add the warning changes occur before the start of the buffer. // We use this conservatively now - any temporary disabling will permanently disable - for (auto& warning : parserData->mWarningEnabledChanges) + for (auto& warning : parserData->mWarningEnabledChanges) { if (!warning.mValue.mEnable) emitParser->mParserData->mWarningEnabledChanges[-warning.mValue.mWarningNumber] = warning.mValue; @@ -2285,7 +2308,7 @@ BfCEParseContext BfModule::CEEmitParse(BfTypeInstance* typeInstance, BfTypeDef* charDataPtr[i].mDisplayFlags = 0; } - emitEmbedEntry->mParser->mSourceClassifier->mCharData = emitEmbedEntry->mCharData.mVals; + emitEmbedEntry->mParser->mSourceClassifier->mCharData = emitEmbedEntry->mCharData.mVals; } if (createdParser) @@ -2317,21 +2340,21 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn if (ceEmitContext->mEmitData.IsEmpty()) return; - + String src; - + // if (typeInstance->mTypeDef->mEmitParent != NULL) // src += "\n\n"; // src += "// Code emission in "; // src += ctxString; // src += "\n\n"; - src += ceEmitContext->mEmitData; + src += ceEmitContext->mEmitData; ceEmitContext->mEmitData.Clear(); - BfCEParseContext ceParseContext = CEEmitParse(typeInstance, declaringType, src, refNode, emitSourceKind); + BfCEParseContext ceParseContext = CEEmitParse(typeInstance, declaringType, src, refNode, emitSourceKind); auto emitParser = typeInstance->mTypeDef->mSource->ToParser(); - + auto typeDeclaration = emitParser->mAlloc->Alloc(); BfReducer bfReducer; @@ -2348,11 +2371,6 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn defBuilder.mCurTypeDef = typeInstance->mTypeDef; defBuilder.mCurDeclaringTypeDef = typeInstance->mTypeDef; - if (typeInstance->mTypeDef->mIsCombinedPartial) - { - // Always define generated methods on the primary type declaration - defBuilder.mCurDeclaringTypeDef = typeInstance->mTypeDef->mPartials[0]->GetLatest(); - } defBuilder.mPassInstance = mCompiler->mPassInstance; defBuilder.mIsComptime = true; defBuilder.DoVisitChild(typeDeclaration->mDefineNode); @@ -2363,8 +2381,8 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn if (emitParser->mSourceClassifier != NULL) { emitParser->mSourceClassifier->VisitChild(emitParser->mRootNode); - emitParser->mSourceClassifier->VisitChild(emitParser->mSidechannelRootNode); - emitParser->mSourceClassifier->VisitChild(emitParser->mErrorRootNode); + emitParser->mSourceClassifier->DeferNodes(emitParser->mSidechannelRootNode); + emitParser->mSourceClassifier->DeferNodes(emitParser->mErrorRootNode); } if (typeInstance->mTypeDef->mEmitParent != NULL) @@ -2377,9 +2395,9 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, Dictionary& prevAttrInstances, bool underlyingTypeDeferred) { for (auto& customAttribute : customAttributes->mAttributes) - { + { auto attrType = customAttribute.mType; - + BfMethodInstance* methodInstance = NULL; bool isFieldApply = false; BfIRValue irValue; @@ -2395,7 +2413,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* { isFieldApply = false; isFieldApply = (ceEmitContext != NULL) && (fieldInstance != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnFieldInitTypeDef)); - + if ((isFieldApply) || ((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIComptimeTypeApply))) || ((ceEmitContext != NULL) && (ifaceEntry.mInterfaceType->IsInstanceOf(mCompiler->mIOnTypeInitTypeDef))) || @@ -2403,7 +2421,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* { // Passes } - else + else continue; prevAttrInstances.TryGetValue(checkAttrType, &irValue); @@ -2422,7 +2440,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* SetAndRestoreValue prevEmitContext(mCompiler->mCeMachine->mCurEmitContext, ceEmitContext); auto ceContext = mCompiler->mCeMachine->AllocContext(); - + BfIRValue attrVal =ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute); for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++) attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0); @@ -2437,7 +2455,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* { SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); SizedArray fieldData = - { + { mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(fieldInfoType->ToTypeInstance()->mBaseType, BfIRPopulateType_Identity)), mBfIRBuilder->CreateTypeOf(mCurTypeInstance), // mTypeInstance CreateFieldData(fieldInstance, -1) @@ -2464,7 +2482,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* continue; } - DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred); + DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred); if (fieldInstance != NULL) mCompiler->mCeMachine->mFieldInstanceSet.Add(fieldInstance); BfTypedValue result; @@ -2499,7 +2517,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* continue; if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted) - return; + return; if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit) { @@ -2554,7 +2572,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* } } - mCompiler->mCeMachine->ReleaseContext(ceContext); + mCompiler->mCeMachine->ReleaseContext(ceContext); } } @@ -2567,27 +2585,27 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code) { Fail("Invalid code mixin", refNode); return; - } + } auto activeTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; //auto emitParser = activeTypeDef->mEmitParser; - + String src; // if (mCurTypeInstance->mTypeDef->mEmitParent != NULL) // src += "\n\n"; -// src += "// Code emission in "; -// src += MethodToString(mCurMethodInstance); +// src += "// Code emission in "; +// src += MethodToString(mCurMethodInstance); // src += "\n"; src += code; - BfReducer bfReducer; + BfReducer bfReducer; bfReducer.mPassInstance = mCompiler->mPassInstance; bfReducer.mSystem = mSystem; bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration; bfReducer.mCurMethodDecl = BfNodeDynCast(mCurMethodInstance->mMethodDef->mMethodDeclaration); - + SetAndRestoreValue prevCustomAttribute(mCurMethodState->mEmitRefNode, refNode); - + EmitEnsureInstructionAt(); BfCEParseContext ceParseContext = CEEmitParse(mCurTypeInstance, activeTypeDef, src, refNode, BfCeTypeEmitSourceKind_Method); @@ -2611,9 +2629,9 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code) } void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred) -{ +{ Dictionary prevAttrInstances; - + if (typeInstance->mCustomAttributes != NULL) HandleCEAttributes(ceEmitContext, typeInstance, NULL, typeInstance->mCustomAttributes, prevAttrInstances, underlyingTypeDeferred); @@ -2656,7 +2674,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* if (!typeInstance->IsTypeMemberIncluded(methodDef->mDeclaringType, mCurTypeInstance->mTypeDef, this)) continue; } - + if (methodDef->mIdx >= typeInstance->mMethodInstanceGroups.mSize) continue; @@ -2671,7 +2689,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* } HandleCEAttributes(ceEmitContext, typeInstance, NULL, methodInstanceGroup.mDefaultCustomAttributes, prevAttrInstances, underlyingTypeDeferred); } - } + } int methodCount = (int)typeInstance->mTypeDef->mMethods.size(); for (int methodIdx = 0; methodIdx < methodCount; methodIdx++) @@ -2688,7 +2706,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeState.mForceActiveTypeDef = methodDef->mDeclaringType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - bool wantsAttributes = false; + bool wantsAttributes = false; BfAttributeDirective* checkAttributes = methodDeclaration->mAttributes; while (checkAttributes != NULL) { @@ -2705,13 +2723,13 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* checkAttributes = checkAttributes->mNextAttribute; } - + if (!wantsAttributes) continue; auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method); defer({ delete customAttributes; }); - + auto onCompileAttribute = customAttributes->Get(mCompiler->mOnCompileAttributeTypeDef); if (onCompileAttribute == NULL) continue; @@ -2738,7 +2756,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* continue; } - SetAndRestoreValue prevEmitContext(mCompiler->mCeMachine->mCurEmitContext); + SetAndRestoreValue prevEmitContext(mCompiler->mCeMachine->mCurEmitContext); if (onCompileKind == BfCEOnCompileKind_TypeInit) { mCompiler->mCeMachine->mCurEmitContext = ceEmitContext; @@ -2747,10 +2765,10 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred); auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx); auto result = mCompiler->mCeMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL); - + if ((onCompileKind == BfCEOnCompileKind_TypeDone) && (typeInstance->mDefineState > BfTypeDefineState_CETypeInit)) { - // Type done, okay + // Type done, okay } else if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit) { @@ -2758,7 +2776,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* AssertErrorState(); } else - { + { if ((!result) && (mCompiler->mFastFinish)) { if ((typeInstance->mCeTypeInfo != NULL) && (typeInstance->mCeTypeInfo->mNext == NULL)) @@ -2787,7 +2805,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* } else if ((ceEmitContext->mFailed) && (typeInstance->mCeTypeInfo != NULL)) typeInstance->mCeTypeInfo->mFailed = true; - + if (!ceEmitContext->mEmitData.IsEmpty()) { String ctxStr = "OnCompile execution of "; @@ -2801,7 +2819,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* if (mCompiler->mCanceling) { DeferRebuildType(typeInstance); - } + } } // if ((!typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef)) && @@ -2819,6 +2837,14 @@ void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool { BfLogSysM("BfModule::DoCEEmit %p\n", typeInstance); + if (((typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef))) || + ((typeInstance->IsInstanceOf(mCompiler->mEnumTypeDef))) || + ((typeInstance->IsInstanceOf(mCompiler->mAttributeTypeDef)))) + { + // These are not allowed to emit + return; + } + CeEmitContext ceEmitContext; ceEmitContext.mType = typeInstance; ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit, underlyingTypeDeferred); @@ -2838,13 +2864,13 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) CeEmitContext ceEmitContext; ceEmitContext.mMethodInstance = methodInstance; - + Dictionary prevAttrInstances; for (auto& customAttribute : customAttributes->mAttributes) { auto attrType = customAttribute.mType; - + BfMethodInstance* applyMethodInstance = NULL; BfIRValue irValue; int checkDepth = 0; @@ -2875,7 +2901,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) } if (applyMethodInstance == NULL) - continue; + continue; SetAndRestoreValue prevEmitContext(mCompiler->mCeMachine->mCurEmitContext, &ceEmitContext); auto ceContext = mCompiler->mCeMachine->AllocContext(); @@ -2887,14 +2913,13 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) SizedArray args; if (!attrType->IsValuelessType()) args.Add(attrVal); - + auto methodInfoType = ResolveTypeDef(mCompiler->mReflectMethodInfoTypeDef); SizedArray methodData = { mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(methodInfoType->ToTypeInstance()->mBaseType, BfIRPopulateType_Identity)), mBfIRBuilder->CreateTypeOf(mCurTypeInstance), // mTypeInstance GetConstValue((int64)methodInstance, GetPrimitiveType(BfTypeCode_Int64)), // mNativeMethodInstance - }; FixConstValueParams(methodInfoType->ToTypeInstance(), methodData, true); auto fieldDataAgg = mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(methodInfoType, BfIRPopulateType_Identity), methodData); @@ -2915,8 +2940,8 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) } mCompiler->mCeMachine->mMethodInstanceSet.Add(methodInstance); - auto activeTypeDef = typeInstance->mTypeDef; - + auto activeTypeDef = typeInstance->mTypeDef; + BfTypedValue result; /// { @@ -2926,7 +2951,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) callSource.mRefNode = customAttribute.mRef; callSource.mKind = CeCallSource::Kind_MethodInit; result = ceContext->Call(callSource, this, applyMethodInstance, args, CeEvalFlags_ForceReturnThis, NULL); - } + } if (result.mType == methodInstance->GetOwner()) prevAttrInstances[methodInstance->GetOwner()] = result.mValue; @@ -2937,7 +2962,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) if ((!ceEmitContext.mEmitData.IsEmpty()) || (!ceEmitContext.mExitEmitData.IsEmpty())) { - String src; + String src; // src += "// Code emission in comptime ApplyToMethod of "; // src += TypeToString(attrType); // src += " to "; @@ -2945,7 +2970,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) // src += " "; // src += customAttribute.mRef->LocationToString(); // src += "\n"; - + //auto emitTypeDef = typeInstance->mCeTypeInfo->mNext->mTypeDef; //auto emitParser = emitTypeDef->mSource->ToParser(); @@ -2953,12 +2978,12 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) BfReducer bfReducer; //bfReducer.mSource = emitParser; - bfReducer.mPassInstance = mCompiler->mPassInstance; + bfReducer.mPassInstance = mCompiler->mPassInstance; bfReducer.mSystem = mSystem; bfReducer.mCurTypeDecl = activeTypeDef->mTypeDeclaration; bfReducer.mCurMethodDecl = BfNodeDynCast(methodInstance->mMethodDef->mMethodDeclaration); - BfAstNode* bodyNode = NULL; + BfAstNode* bodyNode = NULL; if (auto methodDecl = BfNodeDynCast(methodInstance->mMethodDef->mMethodDeclaration)) bodyNode = methodDecl->mBody; @@ -2973,7 +2998,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) if (!ceEmitContext.mEmitData.IsEmpty()) { - SetAndRestoreValue prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef); + SetAndRestoreValue prevCustomAttribute(mCurMethodState->mEmitRefNode, customAttribute.mRef); String entrySrc = src; // if (mCurTypeInstance->mTypeDef->mEmitParent != NULL) // entrySrc += "\n\n"; @@ -3029,10 +3054,196 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance) } } - mCompiler->mCeMachine->ReleaseContext(ceContext); + mCompiler->mCeMachine->ReleaseContext(ceContext); } } +void BfModule::PopulateUsingFieldData(BfTypeInstance* typeInstance) +{ + if (typeInstance->mTypeInfoEx == NULL) + typeInstance->mTypeInfoEx = new BfTypeInfoEx(); + + BfUsingFieldData* usingFieldData; + if (typeInstance->mTypeInfoEx->mUsingFieldData != NULL) + { + usingFieldData = typeInstance->mTypeInfoEx->mUsingFieldData; + Array populatedTypes; + + for (auto checkType : usingFieldData->mAwaitingPopulateSet) + { + if (checkType->mDefineState >= BfTypeDefineState_Defined) + populatedTypes.Add(checkType); + } + + if (populatedTypes.IsEmpty()) + return; + + for (auto type : populatedTypes) + usingFieldData->mAwaitingPopulateSet.Remove(type); + usingFieldData->mEntries.Clear(); + usingFieldData->mMethods.Clear(); + } + else + { + usingFieldData = new BfUsingFieldData(); + typeInstance->mTypeInfoEx->mUsingFieldData = usingFieldData; + } + + HashSet checkedTypeSet; + Array memberRefs; + std::function _CheckType = [&](BfTypeInstance* usingType, bool staticOnly) + { + if (!checkedTypeSet.Add(usingType)) + return; + defer( + { + checkedTypeSet.Remove(usingType); + }); + + for (auto fieldDef : usingType->mTypeDef->mFields) + { + if ((staticOnly) && (!fieldDef->mIsStatic)) + continue; + + memberRefs.Add(BfUsingFieldData::MemberRef(usingType, fieldDef)); + defer( + { + memberRefs.pop_back(); + }); + + if (memberRefs.Count() > 1) + { + BfUsingFieldData::Entry* entry = NULL; + usingFieldData->mEntries.TryAdd(fieldDef->mName, NULL, &entry); + SizedArray lookup; + for (auto entry : memberRefs) + lookup.Add(entry); + entry->mLookups.Add(lookup); + } + + if (fieldDef->mUsingProtection == BfProtection_Hidden) + continue; + + if (usingType->mDefineState < BfTypeDefineState_Defined) + { + bool isPopulatingType = false; + + auto checkTypeState = mContext->mCurTypeState; + while (checkTypeState != NULL) + { + if ((checkTypeState->mType == usingType) && (checkTypeState->mPopulateType >= BfPopulateType_Data)) + { + isPopulatingType = true; + break; + } + + checkTypeState = checkTypeState->mPrevState; + } + + if (!isPopulatingType) + { + // We need to populate this type now + PopulateType(usingType, BfPopulateType_Data_Soft); + } + + if (usingType->mDefineState < BfTypeDefineState_Defined) + typeInstance->mTypeInfoEx->mUsingFieldData->mAwaitingPopulateSet.Add(usingType); + } + + auto fieldInstance = &usingType->mFieldInstances[fieldDef->mIdx]; + auto fieldTypeInst = fieldInstance->mResolvedType->ToTypeInstance(); + if (fieldTypeInst != NULL) + _CheckType(fieldTypeInst, fieldDef->mIsStatic); + } + + for (auto propDef : usingType->mTypeDef->mProperties) + { + if ((staticOnly) && (!propDef->mIsStatic)) + continue; + + memberRefs.Add(BfUsingFieldData::MemberRef(usingType, propDef)); + defer( + { + memberRefs.pop_back(); + }); + + if (memberRefs.Count() > 1) + { + BfUsingFieldData::Entry* entry = NULL; + usingFieldData->mEntries.TryAdd(propDef->mName, NULL, &entry); + SizedArray lookup; + for (auto entry : memberRefs) + lookup.Add(entry); + entry->mLookups.Add(lookup); + } + + if (propDef->mUsingProtection == BfProtection_Hidden) + continue; + + if (usingType->mDefineState < BfTypeDefineState_Defined) + { + // We need to populate this type now + PopulateType(usingType); + } + + BfType* propType = NULL; + for (auto methodDef : propDef->mMethods) + { + auto methodInstance = GetRawMethodInstance(usingType, methodDef); + if (methodInstance == NULL) + continue; + if (methodDef->mMethodType == BfMethodType_PropertyGetter) + { + propType = methodInstance->mReturnType; + break; + } + if (methodDef->mMethodType == BfMethodType_PropertySetter) + { + if (methodInstance->GetParamCount() > 0) + { + propType = methodInstance->GetParamType(0); + break; + } + } + } + if ((propType != NULL) && (propType->IsTypeInstance())) + _CheckType(propType->ToTypeInstance(), propDef->mIsStatic); + } + + for (auto methodDef : usingType->mTypeDef->mMethods) + { + if ((staticOnly) && (!methodDef->mIsStatic)) + continue; + + //TODO: Support mixins as well + if (methodDef->mMethodType != BfMethodType_Normal) + continue; + + // No auto methods + if (methodDef->mMethodDeclaration == NULL) + continue; + + memberRefs.Add(BfUsingFieldData::MemberRef(usingType, methodDef)); + defer( + { + memberRefs.pop_back(); + }); + + if (memberRefs.Count() > 1) + { + BfUsingFieldData::Entry* entry = NULL; + usingFieldData->mMethods.TryAdd(methodDef->mName, NULL, &entry); + SizedArray lookup; + for (auto entry : memberRefs) + lookup.Add(entry); + entry->mLookups.Add(lookup); + } + } + }; + + _CheckType(typeInstance, false); +} + void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance) { SetAndRestoreValue prevTypeInstance(mCurTypeInstance, genericTypeInstance); @@ -3079,7 +3290,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeAlias); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); SetAndRestoreValue prevMethodState(mCurMethodState, NULL); - + BF_ASSERT(mCurMethodInstance == NULL); auto typeDef = typeAlias->mTypeDef; auto typeAliasDecl = (BfTypeAliasDeclaration*)typeDef->mTypeDeclaration; @@ -3087,10 +3298,10 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) if (typeAlias->mBaseType == NULL) typeAlias->mBaseType = ResolveTypeDef(mCompiler->mValueTypeTypeDef)->ToTypeInstance(); - + if ((typeAlias->mGenericTypeInfo != NULL) && (!typeAlias->mGenericTypeInfo->mFinishedGenericParams)) FinishGenericParams(typeAlias); - + BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); typeState.mPopulateType = BfPopulateType_Data; typeState.mCurBaseTypeRef = typeAliasDecl->mAliasToType; @@ -3107,7 +3318,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) if (!CheckCircularDataError()) { if (typeAliasDecl->mAliasToType != NULL) - aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias, + aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGenericParamConstValue | BfResolveTypeRefFlag_AllowImplicitConstExpr)); } @@ -3123,14 +3334,14 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) } if (aliasToType != NULL) - { + { AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom); } else - mContext->mFailTypes.Add(typeAlias); + mContext->mFailTypes.TryAdd(typeAlias, BfFailKind_Normal); if (typeAlias->mTypeFailed) - aliasToType = NULL; + aliasToType = NULL; if ((typeAlias->mAliasToType != NULL) && (typeAlias->mAliasToType != aliasToType) && (!typeAlias->mDependencyMap.IsEmpty())) mContext->QueueMidCompileRebuildDependentTypes(typeAlias, "type alias remapped"); @@ -3150,7 +3361,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) typeAlias->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, BfAttributeTargets_Alias); if (typeAlias->mGenericTypeInfo != NULL) - { + { DoPopulateType_SetGenericDependencies(typeAlias); } } @@ -3158,7 +3369,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) void BfModule::DoPopulateType_InitSearches(BfTypeInstance* typeInstance) { auto typeDef = typeInstance->mTypeDef; - + auto _AddStaticSearch = [&](BfTypeDef* typeDef) { if (!typeDef->mStaticSearch.IsEmpty()) @@ -3426,9 +3637,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if ((populateType <= BfPopulateType_Data) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Defined)) return; - + auto typeInstance = resolvedTypeRef->ToTypeInstance(); - auto typeDef = typeInstance->mTypeDef; + auto typeDef = typeInstance->mTypeDef; BF_ASSERT((typeInstance->mTypeDef->mNextRevision == NULL) || (mCompiler->IsAutocomplete())); @@ -3442,7 +3653,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (!typeInstance->mTypeIncomplete) return; } - typeInstance->mBaseTypeMayBeIncomplete = false; + typeInstance->mBaseTypeMayBeIncomplete = false; BF_ASSERT(mIsModuleMutable); @@ -3457,7 +3668,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (typeInstance->mResolvingConstField) return; - + // Partial population break out point if ((populateType >= BfPopulateType_Identity) && (populateType <= BfPopulateType_IdentityNoRemapAlias)) return; @@ -3483,7 +3694,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy BfLogSysM("DoPopulateType %p bailing due to IsCePaused\n", resolvedTypeRef); return; } - + auto _CheckTypeDone = [&]() { if (typeInstance->mNeedsMethodProcessing) @@ -3505,7 +3716,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize; } - + BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mCeTypeInfo != NULL) || (typeInstance->IsBoxed())); typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size()); for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++) @@ -3514,24 +3725,24 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mMethodInstanceGroups[i].mMethodIdx = i; } - AutoDisallowYield disableYield(mSystem); + AutoDisallowYield disableYield(mSystem); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); SetAndRestoreValue prevMethodState(mCurMethodState, NULL); - // WHY were we clearing these values? + // WHY were we clearing these values? //SetAndRestoreValue prevHadError(mHadBuildError, false); //SetAndRestoreValue prevHadWarning(mHadBuildWarning, false); BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState); typeState.mPopulateType = populateType; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - + if (typeInstance->IsGenericTypeInstance()) { auto genericTypeInst = (BfTypeInstance*)typeInstance; if (!genericTypeInst->mGenericTypeInfo->mInitializedGenericParams) - InitGenericParams(resolvedTypeRef); + InitGenericParams(resolvedTypeRef); } if (resolvedTypeRef->IsTypeAlias()) @@ -3559,7 +3770,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy // If we're not the defining context then we don't report errors for this type, but errors will still put the system // into an errored state SetAndRestoreValue prevReportErrors(mReportErrors, reportErrors); - + if (typeInstance->mIsFinishingType) { if (typeInstance->mTypeFailed) @@ -3567,7 +3778,15 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } if (!typeInstance->mTypeFailed) + { + if (populateType == BfPopulateType_Data_Soft) + { + if (CheckCircularDataError(false)) + return; + } + CheckCircularDataError(); + } if (typeInstance->mDefineState < BfTypeDefineState_Declaring) { @@ -3575,10 +3794,27 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy DoPopulateType_InitSearches(typeInstance); } + // + { + BP_ZONE("DoPopulateType:CheckStack"); + StackHelper stackHelper; + if (!stackHelper.CanStackExpand(128 * 1024)) + { + if (!stackHelper.Execute([&]() + { + DoPopulateType(resolvedTypeRef, populateType); + })) + { + Fail("Stack exhausted in DoPopulateType", typeDef->GetRefNode()); + } + return; + } + } + bool underlyingTypeDeferred = false; - BfType* underlyingType = NULL; + BfType* underlyingType = NULL; if (typeInstance->mBaseType != NULL) - { + { if (typeInstance->IsTypedPrimitive()) underlyingType = typeInstance->GetUnderlyingType(); if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0) @@ -3597,7 +3833,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } if (!hasPayloads) - { + { bool hadType = false; BfAstNode* deferredErrorNode = NULL; @@ -3607,7 +3843,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef); SetAndRestoreValue prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType); - SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); SetAndRestoreValue prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true); auto baseType = ResolveTypeRef(baseTypeRef, BfPopulateType_Declaration); @@ -3657,7 +3893,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy (!typeInstance->mTypeFailed)) { for (auto baseTypeRef : typeDef->mBaseTypes) - { + { auto declTypeDef = typeDef; if (typeDef->mIsCombinedPartial) declTypeDef = typeDef->mPartials.front(); @@ -3715,7 +3951,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy // so we need to take care not to truncate their fieldInstance vector here (thus the 'wantFieldCount' check above) typeInstance->mFieldInstances.Resize(wantFieldCount); } - + if (underlyingType != NULL) { auto fieldInstance = &typeInstance->mFieldInstances.back(); @@ -3728,19 +3964,19 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mAlign = underlyingType->mAlign; typeInstance->mInstSize = underlyingType->mSize; typeInstance->mInstAlign = underlyingType->mAlign; - typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles(); + typeInstance->mHasPackingHoles = underlyingType->HasPackingHoles(); } // Partial population break out point - if (typeInstance->mDefineState < BfTypeDefineState_Declared) + if (typeInstance->mDefineState < BfTypeDefineState_Declared) typeInstance->mDefineState = BfTypeDefineState_Declared; - + if (populateType == BfPopulateType_Declaration) { return; } - + if ((!mCompiler->mIsResolveOnly) && (!typeInstance->HasBeenInstantiated())) { for (auto& dep : typeInstance->mDependencyMap) @@ -3770,7 +4006,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy Fail("Global blocks cannot contain type declarations", typeDef->mTypeDeclaration->mTypeNode); } - /// Create DI data + /// Create DI data SizedArray llvmFieldTypes; int curFieldDataIdx = 0; @@ -3852,7 +4088,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy baseType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance(); } else - { + { for (auto checkTypeRef : typeDef->mBaseTypes) { if ((typeInstance->mDefineState == BfTypeDefineState_ResolvingBaseType) && (typeInstance->mTypeFailed)) @@ -3863,7 +4099,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy declTypeDef = typeDef->mPartials.front(); SetAndRestoreValue prevTypeDef(mContext->mCurTypeState->mCurTypeDef, declTypeDef); SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, checkTypeRef); - SetAndRestoreValue prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType); + SetAndRestoreValue prevDefineState(typeInstance->mDefineState, BfTypeDefineState_ResolvingBaseType); bool populateBase = !typeInstance->mTypeFailed; BfType* checkType = checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration); @@ -3881,7 +4117,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } if (checkType != NULL) - { + { if (auto genericTypeInst = checkType->ToGenericTypeInstance()) { // Specialized type variations don't need to validate their constraints @@ -3964,14 +4200,13 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy Fail(StrFormat("Type '%s' cannot be declare inner type '%s' as a base type", TypeToString(typeInstance).c_str(), TypeToString(checkTypeInst).c_str()), checkTypeRef, true); - checkTypeInst = NULL; + checkTypeInst = NULL; break; } checkOuter = GetOuterType(checkOuter); } } - if (checkTypeInst != NULL) { baseType = checkTypeInst; @@ -3990,10 +4225,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy AssertErrorState(); // Why did we go around setting mTypeFailed on all these things? //typeInstance->mTypeFailed = true; - } + } } - wantPopulateInterfaces = true; + wantPopulateInterfaces = true; } if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty())) @@ -4014,7 +4249,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy ifaceDecl.mDeclaringType = typeDef->GetDefinition(); interfaces.Add(ifaceDecl); } - } + } } if (_CheckTypeDone()) @@ -4037,9 +4272,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } AddDependency(boxedType->mElementType, typeInstance, BfDependencyMap::DependencyFlag_ValueTypeMemberData); - + baseType = mContext->mBfObjectType; - } + } BfTypeInstance* baseTypeInst = NULL; @@ -4052,11 +4287,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { BF_ASSERT(typeInstance->mBaseType == baseTypeInst); } - + if (auto genericTypeInst = typeInstance->ToGenericTypeInstance()) { if ((genericTypeInst->IsSpecializedType()) && (!genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints) && (!typeInstance->IsBoxed())) - { + { deferredTypeValidateList.Add({ NULL, genericTypeInst, true }); } } @@ -4229,7 +4464,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInterfaceInst.mStartInterfaceTableIdx = -1; typeInterfaceInst.mStartVirtualIdx = -1; typeInterfaceInst.mIsRedeclared = false; - typeInstance->mInterfaces.push_back(typeInterfaceInst); + typeInstance->mInterfaces.push_back(typeInterfaceInst); AddDependency(checkInterface, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface); @@ -4254,9 +4489,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } if ((mCompiler->mOptions.mAllowHotSwapping) && - (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces_Direct) && + (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces_Direct) && (typeInstance->mDefineState != BfTypeDefineState_ResolvingBaseType)) - { + { if (typeInstance->mHotTypeData == NULL) { typeInstance->mHotTypeData = new BfHotTypeData(); @@ -4288,13 +4523,13 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy hotTypeVersion->mRefCount++; typeInstance->mHotTypeData->mTypeVersions.Add(hotTypeVersion); - BfLogSysM("BfHotTypeVersion %p created for type %p\n", hotTypeVersion, typeInstance); + BfLogSysM("BfHotTypeVersion %p created for type %p\n", hotTypeVersion, typeInstance); } BF_ASSERT(!typeInstance->mNeedsMethodProcessing); if (typeInstance->mDefineState < BfTypeDefineState_HasInterfaces_Direct) - typeInstance->mDefineState = BfTypeDefineState_HasInterfaces_Direct; - + typeInstance->mDefineState = BfTypeDefineState_HasInterfaces_Direct; + for (auto& validateEntry : deferredTypeValidateList) { SetAndRestoreValue prevAttributeTypeRef(typeState.mCurAttributeTypeRef, validateEntry.mTypeRef); @@ -4302,6 +4537,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false); } + bool isRootSystemType = typeInstance->IsInstanceOf(mCompiler->mValueTypeTypeDef) || + typeInstance->IsInstanceOf(mCompiler->mAttributeTypeDef) || + typeInstance->IsInstanceOf(mCompiler->mEnumTypeDef); + if (!typeInstance->IsBoxed()) { if ((typeInstance->mCustomAttributes == NULL) && (typeDef->mTypeDeclaration != NULL) && (typeDef->HasCustomAttributes())) @@ -4320,7 +4559,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (!typeInstance->mTypeFailed) { BfTypeState typeState; - typeState.mPrevState = mContext->mCurTypeState; + typeState.mPrevState = mContext->mCurTypeState; typeState.mResolveKind = BfTypeState::ResolveKind_Attributes; typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); @@ -4335,7 +4574,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { if (partialTypeDef->mTypeDeclaration->mAttributes == NULL) continue; - + typeState.mCurTypeDef = partialTypeDef; GetCustomAttributes(customAttributes, partialTypeDef->mTypeDeclaration->mAttributes, attrTarget); } @@ -4355,21 +4594,21 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy delete customAttributes; } } - } + } } if (typeInstance->mTypeOptionsIdx == -2) { - SetTypeOptions(typeInstance); + SetTypeOptions(typeInstance); } if (populateType <= BfPopulateType_AllowStaticMethods) - return; + return; prevSkipTypeProtectionChecks.Restore(); typeInstance->mInstSize = std::max(0, typeInstance->mInstSize); - typeInstance->mInstAlign = std::max(0, typeInstance->mInstAlign); - + typeInstance->mInstAlign = std::max(0, typeInstance->mInstAlign); + ProcessCustomAttributeData(); int packing = 0; bool isUnion = false; @@ -4382,7 +4621,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (underlyingArraySize > 0) { typeInstance->mHasUnderlyingArray = true; - curFieldDataIdx = 0; + curFieldDataIdx = 0; } if (packing > 0) // Packed infers ordered isOrdered = true; @@ -4391,12 +4630,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mIsUnion = true; typeInstance->mPacking = (uint8)packing; typeInstance->mIsCRepr = isCRepr; - + if (typeInstance->mTypeOptionsIdx >= 0) { auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx); if (typeOptions != NULL) - { + { typeInstance->mHasBeenInstantiated = typeOptions->Apply(typeInstance->HasBeenInstantiated(), BfOptionFlags_ReflectAssumeInstantiated); bool alwaysInclude = typeInstance->mAlwaysIncludeFlags != 0; @@ -4422,7 +4661,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (boxedType->IsBoxedStructPtr()) innerType = CreatePointerType(innerType); if (innerType->IsIncomplete()) - PopulateType(innerType, BfPopulateType_Data); + PopulateType(innerType, BfPopulateType_Data); auto innerTypeInst = innerType->ToTypeInstance(); if (innerTypeInst != NULL) @@ -4487,13 +4726,13 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy curFieldDataIdx++; } } - + struct DeferredResolveEntry { BfFieldDef* mFieldDef; int mTypeArrayIdx; }; - + BfSizedVector deferredVarResolves; for (auto field : typeDef->mFields) @@ -4530,11 +4769,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, field); SetAndRestoreValue prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_FieldType); - + BfType* resolvedFieldType = NULL; - + auto initializer = field->GetInitializer(); + if ((field->mIsAppend) && (!resolvedTypeRef->IsObject())) + Fail("Appended objects can only be declared in class types", field->GetFieldDeclaration()->mExternSpecifier, true); + + if ((field->mIsAppend) && (isUnion)) + Fail("Appended objects cannot be declared in unions", field->GetFieldDeclaration()->mExternSpecifier, true); + if (field->IsEnumCaseEntry()) { if (typeInstance->IsEnum()) @@ -4577,7 +4822,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy // For 'let', make read-only } else - { + { BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_NoResolveGenericParam; if (initializer != NULL) resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowInferredSizedArray); @@ -4604,7 +4849,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy deferredVarResolves.push_back(resolveEntry); fieldInstance->mIsInferredType = true; - } + } else { AssertErrorState(); @@ -4623,12 +4868,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (field->mIsConst) { - // Resolve in ResolveConstField after we finish populating entire FieldInstance list + // Resolve in ResolveConstField after we finish populating entire FieldInstance list } else if (field->mIsStatic) { // Don't allocate this until after we're finished populating entire FieldInstance list, - // because we may have re-entry and create multiple instances of this static field + // because we may have re-entry and create multiple instances of this static field } } } @@ -4657,6 +4902,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (typeInstance->mResolvingConstField) return; + bool hadSoftFail = false; + for (auto& fieldInstanceRef : typeInstance->mFieldInstances) { auto fieldInstance = &fieldInstanceRef; @@ -4670,7 +4917,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { // Already handled } - else if ((fieldDef != NULL) && (fieldDef->GetFieldDeclaration() != NULL) && (fieldDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed)) + else if ((fieldDef != NULL) && (fieldDef->GetFieldDeclaration() != NULL) && (fieldDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed) && (!isRootSystemType)) { if (auto propDecl = BfNodeDynCast(fieldDef->mFieldDeclaration)) { @@ -4679,7 +4926,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy else { SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); - + fieldInstance->mCustomAttributes = GetCustomAttributes(fieldDef->GetFieldDeclaration()->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field); for (auto customAttr : fieldInstance->mCustomAttributes->mAttributes) { @@ -4710,9 +4957,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); bool populateChildType = !typeInstance->mTypeFailed; //bool populateChildType = true; - PopulateType(resolvedFieldType, populateChildType ? BfPopulateType_Data : BfPopulateType_Declaration); + PopulateType(resolvedFieldType, populateChildType ? ((populateType == BfPopulateType_Data_Soft) ? BfPopulateType_Data_Soft : BfPopulateType_Data) : BfPopulateType_Declaration); - if (populateChildType) + if (populateType == BfPopulateType_Data_Soft) + { + if (resolvedFieldType->IsDataIncomplete()) + hadSoftFail = true; + } + else if (populateChildType) { if (resolvedFieldType->IsFinishingType()) { @@ -4734,16 +4986,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } } } - - } - + + if (hadSoftFail) + return; + bool tryCE = true; if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit) { if (populateType <= BfPopulateType_AllowStaticMethods) return; - + int foundTypeCount = 0; auto typeState = mContext->mCurTypeState; while (typeState != NULL) @@ -4774,17 +5027,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy tryCE = false; } } - + if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE)) { BF_ASSERT(!typeInstance->mTypeDef->IsEmitted()); - if (typeInstance->mCeTypeInfo != NULL) + if (typeInstance->mCeTypeInfo != NULL) typeInstance->mCeTypeInfo->mPendingInterfaces.Clear(); typeInstance->mDefineState = BfTypeDefineState_CETypeInit; bool hadNewMembers = false; - DoCEEmit(typeInstance, hadNewMembers, underlyingTypeDeferred); + DoCEEmit(typeInstance, hadNewMembers, underlyingTypeDeferred); if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) typeInstance->mDefineState = BfTypeDefineState_CEPostTypeInit; @@ -4846,7 +5099,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mCeTypeInfo->mTypeIFaceMap.Clear(); typeInstance->mCeTypeInfo->mHash = Val128(); } - + if (((typeInstance->mCeTypeInfo->mFailed) || (typeInstance->mTypeDef->HasParsingFailed())) && (prevHadEmissions)) { @@ -4858,7 +5111,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty())) hadNewMembers = true; - + if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL)) { BF_ASSERT(mCompiler->mCanceling); @@ -4874,7 +5127,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (hadNewMembers) { - DoPopulateType(resolvedTypeRef, populateType); + // We need to avoid passing in BfPopulateType_Interfaces_All because it could cause us to miss out on new member processing, + // including resizing the method group table + DoPopulateType(resolvedTypeRef, BF_MAX(populateType, BfPopulateType_Data)); return; } @@ -4889,7 +5144,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (_CheckTypeDone()) return; - + BF_ASSERT(mContext->mCurTypeState == &typeState); //BF_ASSERT(!typeInstance->mIsFinishingType); @@ -4899,7 +5154,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy BfSizedVector diFieldTypes; HashContext dataMemberHashCtx; - + if (!resolvedTypeRef->IsBoxed()) { for (auto propDef : typeDef->mProperties) @@ -4915,7 +5170,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (propDef->IsExpressionBodied()) target = (BfAttributeTargets)(target | BfAttributeTargets_Method); - if ((propDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed)) + if ((propDef->GetFieldDeclaration()->mAttributes != NULL) && (!typeInstance->mTypeFailed) && (!isRootSystemType)) { auto customAttrs = GetCustomAttributes(propDef->GetFieldDeclaration()->mAttributes, target); delete customAttrs; @@ -4952,7 +5207,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } } - bool isGlobalContainer = typeDef->IsGlobalsContainer(); + bool isGlobalContainer = typeDef->IsGlobalsContainer(); if (typeInstance->mBaseType != NULL) { @@ -4971,7 +5226,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy int maxDataPos = dataPos; BfSizedVector dataFieldVec; - + bool allowInstanceFields = (underlyingType == NULL); if (typeInstance->IsTypedPrimitive()) allowInstanceFields = false; @@ -5002,18 +5257,18 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy AddDependency(resolvedFieldType, typeInstance, BfDependencyMap::DependencyFlag_StaticValue); } - auto fieldDef = fieldInstance->GetFieldDef(); + auto fieldDef = fieldInstance->GetFieldDef(); if (fieldInstance->mResolvedType != NULL) { - auto resolvedFieldType = fieldInstance->GetResolvedType(); + auto resolvedFieldType = fieldInstance->GetResolvedType(); if ((!typeInstance->IsBoxed()) && (fieldDef != NULL)) { - if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsStruct()) && (!resolvedFieldType->IsObject())) + if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsStruct())) Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier); if (fieldInstance->mIsEnumPayloadCase) - { + { PopulateType(resolvedFieldType, BfPopulateType_Data); if (resolvedFieldType->WantsGCMarking()) typeInstance->mWantsGCMarking = true; @@ -5073,28 +5328,114 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (!mCompiler->mIsResolveOnly) { - dataMemberHashCtx.MixinStr(fieldDef->mName); + dataMemberHashCtx.MixinStr(fieldDef->mName); dataMemberHashCtx.Mixin(resolvedFieldType->mTypeId); } int dataSize = resolvedFieldType->mSize; int alignSize = resolvedFieldType->mAlign; + + if (fieldInstance->IsAppendedObject()) + { + SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); + SetAndRestoreValue prevResolveKind(mContext->mCurTypeState->mResolveKind, BfTypeState::ResolveKind_FieldType); + + PopulateType(resolvedFieldType, BfPopulateType_Data); + + auto fieldTypeInst = resolvedFieldType->ToTypeInstance(); + dataSize = BF_MAX(fieldTypeInst->mInstSize, 0); + alignSize = BF_MAX(fieldTypeInst->mInstAlign, 1); + + if (fieldTypeInst->mTypeFailed) + { + TypeFailed(fieldTypeInst); + fieldInstance->mResolvedType = GetPrimitiveType(BfTypeCode_Var); + continue; + } + + if ((typeInstance != NULL) && (fieldTypeInst->mTypeDef->mIsAbstract)) + { + Fail("Cannot create an instance of an abstract class", nameRefNode); + } + + SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); + BfMethodState methodState; + SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); + methodState.mTempKind = BfMethodState::TempKind_NonStatic; + + BfTypedValue appendIndexValue; + BfExprEvaluator exprEvaluator(this); + + BfResolvedArgs resolvedArgs; + + auto fieldDecl = fieldDef->GetFieldDeclaration(); + if (auto invocationExpr = BfNodeDynCast(fieldDecl->mInitializer)) + { + resolvedArgs.Init(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen); + exprEvaluator.ResolveArgValues(resolvedArgs, BfResolveArgsFlag_DeferParamEval); + } + + BfFunctionBindResult bindResult; + bindResult.mSkipThis = true; + bindResult.mWantsArgs = true; + SetAndRestoreValue prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult); + + BfTypedValue emptyThis(mBfIRBuilder->GetFakeVal(), resolvedTypeRef, resolvedTypeRef->IsStruct()); + + exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime; + auto ctorResult = exprEvaluator.MatchConstructor(nameRefNode, NULL, emptyThis, fieldTypeInst, resolvedArgs, false, true); + + if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend)) + { + auto calcAppendMethodModule = GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND); + + SizedArray irArgs; + if (bindResult.mIRArgs.size() > 1) + irArgs.Insert(0, &bindResult.mIRArgs[1], bindResult.mIRArgs.size() - 1); + BfTypedValue appendSizeTypedValue = TryConstCalcAppend(calcAppendMethodModule.mMethodInstance, irArgs, true); + if (appendSizeTypedValue) + { + int appendAlign = calcAppendMethodModule.mMethodInstance->mAppendAllocAlign; + dataSize = BF_ALIGN(dataSize, appendAlign); + alignSize = BF_MAX(alignSize, appendAlign); + + auto constant = mBfIRBuilder->GetConstant(appendSizeTypedValue.mValue); + if (constant != NULL) + { + dataSize += constant->mInt32; + } + } + else + { + Fail(StrFormat("Append constructor '%s' does not result in a constant size", MethodToString(bindResult.mMethodInstance).c_str()), nameRefNode); + } + } + } + else if (fieldDef->mIsAppend) + { + if (typeInstance->IsObject()) + Fail("Append fields can only be declared in classes", nameRefNode, true); + else if ((!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsGenericParam())) + Fail("Append fields must be classes", nameRefNode, true); + } + + BF_ASSERT(dataSize >= 0); fieldInstance->mDataSize = dataSize; if (!isUnion) { if (!resolvedFieldType->IsValuelessType()) { - dataFieldVec.push_back(fieldInstance); + dataFieldVec.push_back(fieldInstance); } } else { - BF_ASSERT(resolvedFieldType->mSize >= 0); + BF_ASSERT(resolvedFieldType->mSize >= 0); if (alignSize > 1) dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1); fieldInstance->mDataOffset = dataPos; - + typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize); dataPos += dataSize; @@ -5103,13 +5444,19 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy maxDataPos = dataPos; } dataPos = startDataPos; - } + } auto fieldTypeInst = resolvedFieldType->ToTypeInstance(); if (fieldTypeInst != NULL) { if ((fieldTypeInst->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred) != 0) { + if (populateType < BfPopulateType_Data) + { + // We don't actually need the data - bail out + return; + } + BfAstNode* refNode = fieldDef->mFieldDeclaration; String failStr; failStr = StrFormat("Circular data reference detected between '%s' and '%s'", TypeToString(mCurTypeInstance).c_str(), TypeToString(fieldTypeInst).c_str()); @@ -5146,9 +5493,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy else { BF_ASSERT(typeInstance->mIsUnion); - } + } } - + if ((!fieldDef->mIsStatic) && (!resolvedFieldType->IsValuelessType())) { if (isUnion) @@ -5196,7 +5543,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy alignBuckets.pop_back(); } - int alignBits = GetNumLowZeroBits(curSize) + 1; + int alignBits = GetNumLowZeroBits(curSize) + 1; alignBits = BF_MIN(alignBits, (int)alignBuckets.size() - 1); bool foundEntry = false; @@ -5209,12 +5556,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } bool isHighestBucket = alignBits == alignBuckets.size() - 1; - + auto fieldInst = alignBuckets[alignBits][0]; alignBuckets[alignBits].RemoveAt(0); dataFieldVec.push_back(fieldInst); curSize = BF_ALIGN(curSize, fieldInst->GetAlign(packing)); - curSize += fieldInst->mResolvedType->mSize; + curSize += fieldInst->mDataSize; foundEntry = true; if (!isHighestBucket) @@ -5223,19 +5570,19 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy break; } } - + if (!foundEntry) { // If no entries will fit, then force an entry of the smallest alignment for (int alignBits = 0; alignBits < alignBuckets.size(); alignBits++) { if (!alignBuckets[alignBits].IsEmpty()) - { + { auto fieldInst = alignBuckets[alignBits][0]; alignBuckets[alignBits].RemoveAt(0); dataFieldVec.push_back(fieldInst); curSize = BF_ALIGN(curSize, fieldInst->GetAlign(packing)); - curSize += fieldInst->mResolvedType->mSize; + curSize += fieldInst->mDataSize; break; } } @@ -5245,17 +5592,20 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy bool needsExplicitAlignment = true; - for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++) + for (int fieldIdx = 0; fieldIdx < (int)dataFieldVec.size(); fieldIdx++) { auto fieldInstance = dataFieldVec[fieldIdx]; auto resolvedFieldType = fieldInstance->GetResolvedType(); BF_ASSERT(resolvedFieldType->mSize >= 0); - int dataSize = resolvedFieldType->mSize; - int alignSize = fieldInstance->GetAlign(packing); - fieldInstance->mDataSize = dataSize; - int nextDataPos = dataPos; + if (fieldInstance->mDataSize == 0) + fieldInstance->mDataSize = resolvedFieldType->mSize; + + int dataSize = fieldInstance->mDataSize; + int alignSize = fieldInstance->GetAlign(packing); + + int nextDataPos = dataPos; nextDataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1); int padding = nextDataPos - dataPos; if ((alignSize > 1) && (needsExplicitAlignment) && (padding > 0)) @@ -5265,9 +5615,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy dataPos = nextDataPos; fieldInstance->mDataOffset = dataPos; fieldInstance->mDataIdx = curFieldDataIdx++; - + typeInstance->mInstAlign = std::max(typeInstance->mInstAlign, alignSize); - dataPos += dataSize; + dataPos += dataSize; } if (unionInnerType != NULL) @@ -5276,7 +5626,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mInstAlign = BF_MAX(unionInnerType->mAlign, typeInstance->mInstAlign); } - // Old dataMemberHash location + // Old dataMemberHash location CheckMemberNames(typeInstance); @@ -5297,7 +5647,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { typeInstance->mInstSize = dataPos; typeInstance->mIsCRepr = false; - } + } if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) { @@ -5306,7 +5656,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy mCompiler->mResolvePassData->mAutoComplete->CheckProperty(BfNodeDynCast(propDef->mFieldDeclaration)); } } - + if (typeInstance->IsObjectOrInterface()) typeInstance->mWantsGCMarking = true; if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!typeInstance->mWantsGCMarking)) @@ -5321,15 +5671,15 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mWantsGCMarking = true; } } - + if (typeInstance->IsValueType()) { typeInstance->mSize = typeInstance->mInstSize; typeInstance->mAlign = typeInstance->mInstAlign; - } - + } + if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined)) - { + { if (typeInstance->mHotTypeData == NULL) { BF_ASSERT(typeInstance->mTypeFailed); @@ -5385,7 +5735,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy mHadBuildError = true; CheckAddFailType(); - + BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting); BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotted); @@ -5409,7 +5759,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if ((typeInstance->mBaseType == NULL) || (typeInstance->mBaseType->IsSplattable())) { int dataCount = 0; - + std::function splatIterate; splatIterate = [&](BfType* checkType) { @@ -5418,7 +5768,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (checkType->IsMethodRef()) { - // For simplicity, any methodRef inside a struct makes the struct non-splattable. This reduces cases of needing to + // For simplicity, any methodRef inside a struct makes the struct non-splattable. This reduces cases of needing to // handle embedded methodRefs hadNonSplattable = true; } @@ -5427,7 +5777,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy hadNonSplattable = true; } else if (checkType->IsStruct()) - { + { auto checkTypeInstance = checkType->ToTypeInstance(); if (checkTypeInstance->mBaseType != NULL) splatIterate(checkTypeInstance->mBaseType); @@ -5458,7 +5808,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { if (checkType->IsSizedArray()) hadNonSplattable = true; - + dataCount += checkType->GetSplatCount(); } }; @@ -5481,7 +5831,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeInstance->mIsSplattable = true; if (typeInstance->mTypeDef->mIsOpaque) typeInstance->mIsSplattable = false; - + BF_ASSERT(mContext->mCurTypeState == &typeState); // This is only required for autocomplete and finding type references @@ -5497,7 +5847,13 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy typeState.mCurTypeDef = propDef->mDeclaringType; typeState.mType = typeInstance; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef); + + if (BfNodeIsA(propDef->mTypeRef)) + { + // This is only valid for ConstEval properties + } + else + ResolveTypeRef(propDef->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowRef); } } @@ -5540,7 +5896,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } } } - + if ((typeInstance->IsEnum()) && (!typeInstance->IsPayloadEnum())) { BfLogSysM("Setting underlying type %p %d\n", typeInstance, underlyingTypeDeferred); @@ -5560,7 +5916,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (typeInstance->mHotTypeData != NULL) { - auto newHotTypeVersion = typeInstance->mHotTypeData->GetLatestVersion(); + auto newHotTypeVersion = typeInstance->mHotTypeData->GetLatestVersion(); newHotTypeVersion->mDataHash = dataMemberHash; if (mCompiler->mHotState != NULL) @@ -5575,7 +5931,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy if (!typeInstance->mHotTypeData->mPendingDataChange) { mCompiler->mHotState->mPendingDataChanges.Add(typeInstance->mTypeId); - typeInstance->mHotTypeData->mPendingDataChange = true; + typeInstance->mHotTypeData->mPendingDataChange = true; } else { @@ -5649,7 +6005,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) -{ +{ if (typeInstance->IsDeleting()) { BF_ASSERT(typeInstance->IsOnDemand()); @@ -5658,13 +6014,30 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (typeInstance->IsSpecializedByAutoCompleteMethod()) return; - + if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotting) { BfLogSysM("DoTypeInstanceMethodProcessing %p re-entrancy exit\n", typeInstance); return; } + // + { + BP_ZONE("DoTypeInstanceMethodProcessing:CheckStack"); + StackHelper stackHelper; + if (!stackHelper.CanStackExpand(128 * 1024)) + { + if (!stackHelper.Execute([&]() + { + DoTypeInstanceMethodProcessing(typeInstance); + })) + { + Fail("Stack exhausted in DoPopulateType", typeInstance->mTypeDef->GetRefNode()); + } + return; + } + } + BF_ASSERT_REL(typeInstance->mNeedsMethodProcessing); BF_ASSERT_REL(typeInstance->mDefineState == BfTypeDefineState_Defined); typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotting; @@ -5677,7 +6050,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) AutoDisallowYield disableYield(mSystem); SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); - SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, NULL); BfLogSysM("DoTypeInstanceMethodProcessing: %p %s Revision:%d DefineState:%d\n", typeInstance, TypeToString(typeInstance).c_str(), typeInstance->mRevision, typeInstance->mDefineState); @@ -5721,21 +6094,20 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) //BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)); } - if (typeInstance == mContext->mBfObjectType) { BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 0); } int newIntefaceStartIdx = 0; - auto implBaseType = typeInstance->GetImplBaseType(); + auto implBaseType = typeInstance->GetImplBaseType(); if (implBaseType != NULL) { auto baseTypeInst = implBaseType->ToTypeInstance(); if (implBaseType->IsIncomplete()) PopulateType(implBaseType, BfPopulateType_Full_Force); - typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable; + typeInstance->mInterfaceMethodTable = baseTypeInst->mInterfaceMethodTable; typeInstance->mVirtualMethodTable = implBaseType->mVirtualMethodTable; typeInstance->mVirtualMethodTableSize = implBaseType->mVirtualMethodTableSize; if ((!mCompiler->IsHotCompile()) && (!mCompiler->mPassInstance->HasFailed()) && ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL))) @@ -5746,18 +6118,18 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { BF_ASSERT(typeInstance->mVirtualMethodTableSize >= (int)typeInstance->mVirtualMethodTable.size()); } - } + } - // Add new interfaces + // Add new interfaces for (int iFaceIdx = 0; iFaceIdx < (int)typeInstance->mInterfaces.size(); iFaceIdx++) { - BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx]; + BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx]; auto checkInterface = typeInterfaceInst.mInterfaceType; - if (checkInterface->IsIncomplete()) + if (checkInterface->IsIncomplete()) PopulateType(checkInterface, BfPopulateType_Full_Force); - - typeInterfaceInst.mStartInterfaceTableIdx = (int)typeInstance->mInterfaceMethodTable.size(); + + typeInterfaceInst.mStartInterfaceTableIdx = (int)typeInstance->mInterfaceMethodTable.size(); // We don't add to the vtable for interface declarations, we just reference the listed interfaces if (!typeInstance->IsInterface()) @@ -5766,17 +6138,17 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) BF_ASSERT(interfaceTypeDef->mMethods.size() == checkInterface->mMethodInstanceGroups.size()); // Reserve empty entries - for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++) + for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++) typeInstance->mInterfaceMethodTable.push_back(BfTypeInterfaceMethodEntry()); - } + } } auto checkTypeInstance = typeInstance; while (checkTypeInstance != NULL) { // These may have been already added - for (auto&& interfaceEntry : checkTypeInstance->mInterfaces) - AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface); + for (auto&& interfaceEntry : checkTypeInstance->mInterfaces) + AddDependency(interfaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface); checkTypeInstance = checkTypeInstance->GetImplBaseType(); } @@ -5786,7 +6158,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { BF_ASSERT(typeInstance->mInterfaceMethodTable.size() == 1); } - + // Slot interfaces method blocks in vtable { int ifaceVirtIdx = 0; @@ -5837,16 +6209,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((mCompiler->mOptions.mHasVDataExtender) && (!typeInstance->IsInterface())) { // This is the vExt entry for this type instance - BfVirtualMethodEntry entry; + BfVirtualMethodEntry entry; entry.mDeclaringMethod.mMethodNum = -1; entry.mDeclaringMethod.mTypeInstance = typeInstance; typeInstance->mVirtualMethodTable.push_back(entry); - typeInstance->mVirtualMethodTableSize++; + typeInstance->mVirtualMethodTableSize++; } // Fill out to correct size if (typeInstance->mHotTypeData != NULL) - { + { //auto hotLatestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead(); int wantVTableSize = typeInstance->GetImplBaseVTableSize() + (int)typeInstance->mHotTypeData->mVTableEntries.size(); while ((int)typeInstance->mVirtualMethodTable.size() < wantVTableSize) @@ -5855,12 +6227,12 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) typeInstance->mVirtualMethodTableSize++; } } - + BfAmbiguityContext ambiguityContext; ambiguityContext.mTypeInstance = typeInstance; ambiguityContext.mModule = this; ambiguityContext.mIsProjectSpecific = false; - + bool wantsOnDemandMethods = false; //TODO: Testing having interface methods be "on demand"... //if (!typeInstance->IsInterface()) @@ -5875,7 +6247,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) //if (typeDef->mName->ToString() != "AttributeUsageAttribute") auto attributeDef = mCompiler->mAttributeTypeDef; - auto attributeType = mContext->mUnreifiedModule->ResolveTypeDef(attributeDef, BfPopulateType_Identity)->ToTypeInstance(); + auto attributeType = mContext->mUnreifiedModule->ResolveTypeDef(attributeDef, BfPopulateType_Identity)->ToTypeInstance(); if (!TypeIsSubTypeOf(mCurTypeInstance, attributeType, false)) { wantsOnDemandMethods = true; @@ -5895,13 +6267,13 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) auto parser = typeDef->mTypeDeclaration->GetParser(); if (parser != NULL) if (mCompiler->mResolvePassData->GetSourceClassifier(parser) != NULL) - isCurrentEntry = true; + isCurrentEntry = true; }; _CheckEntry(typeInstance->mTypeDef); for (auto& partial : typeInstance->mTypeDef->mPartials) _CheckEntry(partial); - + if (isCurrentEntry) { String typeName = TypeToString(typeInstance, BfTypeNameFlag_AddProjectName); @@ -5928,7 +6300,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) BfTypeInterfaceEntry& typeInterfaceInst = typeInstance->mInterfaces[iFaceIdx]; for (auto checkMethodDef : typeInterfaceInst.mInterfaceType->mTypeDef->mMethods) { - ifaceMethodNameSet.Add(checkMethodDef->mName); + ifaceMethodNameSet.Add(checkMethodDef->mName); } } } @@ -5940,7 +6312,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) isFailedType = true; } - bool typeOptionsIncludeAll = false; + bool typeOptionsIncludeAll = false; bool typeOptionsIncludeFiltered = false; if (typeOptions != NULL) { @@ -5950,8 +6322,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) // Generate all methods. Pass 1 for (auto methodDef : typeDef->mMethods) - { - auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx]; + { + auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx]; if (typeOptions != NULL) { @@ -5959,7 +6331,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (methodDef->mMethodType == BfMethodType_Ctor) optionFlags = BfOptionFlags_ReflectConstructors; else if (methodDef->mIsStatic) - optionFlags = BfOptionFlags_ReflectStaticMethods; + optionFlags = BfOptionFlags_ReflectStaticMethods; methodInstanceGroup->mExplicitlyReflected = typeOptions->Apply(false, optionFlags); methodInstanceGroup->mExplicitlyReflected = ApplyTypeOptionMethodFilters(methodInstanceGroup->mExplicitlyReflected, methodDef, typeOptions); } @@ -5969,17 +6341,17 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) continue; if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_InWorkList) - continue; + continue; if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Referenced) continue; - + if (isFailedType) { // We don't want method decls from failed generic types to clog up our type system continue; } - - BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || + + BF_ASSERT((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference)); @@ -5988,7 +6360,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (methodDef->mIsStatic) continue; bool boxedRequired = false; - if (((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.size() == 0)) || + if (((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mParams.size() == 0)) || (methodDef->mMethodType == BfMethodType_Dtor) || ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) || (methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) || (methodDef->mName == BF_METHODNAME_INVOKE) || (methodDef->mName == BF_METHODNAME_DYNAMICCAST)) || (methodDef->mGenericParams.size() != 0)) @@ -6005,11 +6377,11 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } if (methodDef->mMethodType == BfMethodType_Ignore) - continue; + continue; if ((methodDef->mName == BF_METHODNAME_DYNAMICCAST) && (typeInstance->IsValueType())) continue; // This is just a placeholder for boxed types - + bool doAlwaysInclude = false; if (wantsOnDemandMethods) @@ -6064,7 +6436,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) attributes = attributes->mNextAttribute; } if ((mProject != NULL) && (mProject->mAlwaysIncludeAll) && (methodDef->mBody != NULL)) - { + { implRequired = true; declRequired = true; } @@ -6075,7 +6447,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (((typeInstance->mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0) && (methodDef->IsDefaultCtor())) implRequired = true; - + if ((typeOptionsIncludeAll || typeOptionsIncludeFiltered) && (ApplyTypeOptionMethodFilters(typeOptionsIncludeAll, methodDef, typeOptions))) implRequired = true; @@ -6093,7 +6465,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) // Any interface with the same name causes us to not be on-demand if (ifaceMethodNameSet.Contains(methodDef->mName)) declRequired = true; - } + } // Is this strictly necessary? It will reduce our compilation speed in order to ensure methods are available for debug info if (allDeclsRequired) @@ -6114,7 +6486,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } if (!implRequired) - { + { if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) { if (!mIsScratchModule) @@ -6137,9 +6509,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } else { - doAlwaysInclude = true; + doAlwaysInclude = true; } - } + } else doAlwaysInclude = true; @@ -6147,7 +6519,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { bool wasDeclared = (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingDecl) || (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference); - + methodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_AlwaysInclude; if (wasDeclared) @@ -6164,10 +6536,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount); // Def passes. First non-overrides then overrides (for in-place overrides in methods) - for (int pass = 0; pass < 2; pass++) + for (int pass = 0; pass < 2; pass++) { for (auto methodDef : typeDef->mMethods) - { + { if ((pass == 1) != (methodDef->mIsOverride)) continue; @@ -6290,7 +6662,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } // This is important for reducing latency of autocomplete popup, but it's important we don't allow the autocomplete - // thread to cause any reentry issues by re-populating a type at an "inopportune time". We do allow certain + // thread to cause any reentry issues by re-populating a type at an "inopportune time". We do allow certain // reentries in PopulateType, but not when we're resolving fields (for example) if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField)) { @@ -6301,7 +6673,6 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } } - BF_ASSERT(typeInstance->mVirtualMethodTable.size() == typeInstance->mVirtualMethodTableSize); if ((isBoxed) && (!typeInstance->IsUnspecializedTypeVariation())) @@ -6355,7 +6726,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None; methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly); - + auto moduleMethodInstance = GetMethodInstance(typeInstance, matchedMethodDef, BfTypeVector(), methodFlags, matchedMethod->GetForeignType()); @@ -6372,7 +6743,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (typeInstance->mHotTypeData != NULL) { auto latestVersion = typeInstance->mHotTypeData->GetLatestVersion(); - auto latestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead(); + auto latestVersionHead = typeInstance->mHotTypeData->GetLatestVersionHead(); if (typeInstance->mHotTypeData->mVTableOrigLength != -1) { bool hasSlotError = false; @@ -6409,7 +6780,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { latestVersion->mInterfaceMapping = ifaceMapping; } - hasSlotError = true; + hasSlotError = true; } else if (hasSlotError) { @@ -6428,10 +6799,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) mCompiler->mHotState->mPendingFailedSlottings.Remove(typeInstance->mTypeId); } } - + if ((typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedType()) && (typeInstance->mIsReified) && (typeInstance->mSlotNum == -1) && (mCompiler->IsHotCompile())) { - mCompiler->mHotState->mHasNewInterfaceTypes = true; + mCompiler->mHotState->mHasNewInterfaceTypes = true; } if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed) && (!isFailedType)) @@ -6510,7 +6881,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((methodInstance->mMethodDef->mProtection != BfProtection_Private) && (!methodInstance->mMethodDef->mIsOverride) && (missingIFaceMethodNames.find(methodInstance->mMethodDef->mName) != missingIFaceMethodNames.end())) - { + { SlotVirtualMethod(methodInstance, &ambiguityContext); } } @@ -6520,7 +6891,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } for (auto& ifaceTypeInst : typeInstance->mInterfaces) - { + { auto ifaceInst = ifaceTypeInst.mInterfaceType; int startIdx = ifaceTypeInst.mStartInterfaceTableIdx; int iMethodCount = (int)ifaceInst->mMethodInstanceGroups.size(); @@ -6548,7 +6919,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) continue; // Don't consider overrides here // If we have "ProjA depends on LibBase", "ProjB depends on LibBase", then a type ClassC in LibBase implementing IFaceD, - // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC -- + // where IFaceD gets extended with MethodE in ProjA, an implementing MethodE is still required to exist on ClassC -- // the visibility is bidirectional. A type ClassF implementing IFaceD inside ProjB will not be required to implement // MethodE, however if ((!ifaceInst->IsTypeMemberAccessible(ifaceMethodInst->mMethodDef->mDeclaringType, ifaceTypeInst.mDeclaringType)) && @@ -6568,7 +6939,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((matchedMethod->GetExplicitInterface() == NULL) && (matchedMethod->mMethodDef->mProtection != BfProtection_Public)) { hadMatch = false; - hadPubFailure = true; + hadPubFailure = true; } if (matchedMethod->mMethodDef->mIsStatic != ifaceMethodInst->mMethodDef->mIsStatic) @@ -6576,7 +6947,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) hadMatch = false; hadStaticFailure = true; } - + if (ifaceMethodInst->mVirtualTableIdx != -1) { if (matchedMethod->mReturnType != iReturnType) @@ -6588,18 +6959,18 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if (!CanCast(GetFakeTypedValue(matchedMethod->mReturnType), iReturnType)) hadMatch = false; } - - // If we have mExplicitInterface set then we already gave a mut error (if needed) + + // If we have mExplicitInterface set then we already gave a mut error (if needed) if ((typeInstance->IsValueType()) && (matchedMethod->GetExplicitInterface() == NULL) && (matchedMethod->mMethodDef->mIsMutating) && (!ifaceMethodInst->mMethodDef->mIsMutating)) { hadMutFailure = true; hadMatch = false; - } + } } if (!hadMatch) - { + { if (!typeInstance->IsUnspecializedTypeVariation()) { auto bestMethodInst = ifaceMethodInst; @@ -6609,7 +6980,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { bool searchFailed = false; for (auto& checkIFaceTypeInst : typeInstance->mInterfaces) - { + { auto checkIFaceInst = checkIFaceTypeInst.mInterfaceType; int checkStartIdx = checkIFaceTypeInst.mStartInterfaceTableIdx; int checkIMethodCount = (int)checkIFaceInst->mMethodInstanceGroups.size(); @@ -6618,14 +6989,14 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) auto checkIFaceMethodInst = checkIFaceInst->mMethodInstanceGroups[checkIMethodIdx].mDefault; if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride)) { - bool cmpResult = CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst); + bool cmpResult = CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst); if (cmpResult) { bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface); bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst); if (isBetter == isWorse) { - CompareDeclTypes(checkIFaceMethodInst->mMethodDef->mDeclaringType, bestMethodInst->mMethodDef->mDeclaringType, isBetter, isWorse); + CompareDeclTypes(NULL, checkIFaceMethodInst->mMethodDef->mDeclaringType, bestMethodInst->mMethodDef->mDeclaringType, isBetter, isWorse); } if ((isBetter) && (!isWorse)) { @@ -6645,7 +7016,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' is a candidate", MethodToString(checkIFaceMethodInst).c_str()), checkIFaceMethodInst->mMethodDef->GetRefNode()); } - //candidate implementations include '%s' and '%s'", + //candidate implementations include '%s' and '%s'", //TypeToString(checkIFaceInst).c_str(), TypeToString(bestInterface).c_str()), ); } } @@ -6679,13 +7050,13 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) *matchedMethodRef = methodInst.mMethodInstance; BfMethodInstance* newMethodInstance = methodInst.mMethodInstance; - BF_ASSERT(newMethodInstance->mIsForeignMethodDef); + BF_ASSERT(newMethodInstance->mIsForeignMethodDef); if (newMethodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) { if (!mIsScratchModule) mOnDemandMethodCount++; - } - + } + continue; } } @@ -6708,19 +7079,19 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) // It's possible const eval was supposed to generate this method. We're rebuilding the type anyway. } else - { + { String methodString; /// { BfTypeState typeState; - typeState.mPrevState = mContext->mCurTypeState; + typeState.mPrevState = mContext->mCurTypeState; typeState.mForceActiveTypeDef = declTypeDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); - + SetAndRestoreValue prevMethodInstance(mCurMethodInstance, ifaceMethodInst); methodString = MethodToString(ifaceMethodInst); } - + BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration; BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true); if ((matchedMethod != NULL) && (error != NULL)) @@ -6748,7 +7119,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it does not have a concrete return type that implements '%s'", methodString.c_str(), TypeToString(ifaceMethodInst->mReturnType).c_str()), matchedMethod->mMethodDef->mReturnTypeRef); - } + } else if (hadMutFailure) { mCompiler->mPassInstance->MoreInfo(StrFormat("'%s' cannot match because it's market as 'mut' but interface method does not allow it", @@ -6762,14 +7133,14 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) if ((ifaceMethodInst->mVirtualTableIdx != -1) && (ifaceMethodInst->mReturnType->IsInterface())) mCompiler->mPassInstance->MoreInfo("Declare the interface method as 'concrete' to allow matching concrete return values", ifaceMethodInst->mMethodDef->GetMethodDeclaration()->mVirtualSpecifier); } - } + } } } // Clear out the entry *matchedMethodRef = BfMethodRef(); } - } + } } } @@ -6779,7 +7150,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) CheckAddFailType(); typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted; - mCompiler->mStats.mTypesPopulated++; + mCompiler->mStats.mTypesPopulated++; mCompiler->UpdateCompletion(); BF_ASSERT_REL(!typeInstance->mNeedsMethodProcessing); @@ -6788,10 +7159,10 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance) } void BfModule::RebuildMethods(BfTypeInstance* typeInstance) -{ +{ if (typeInstance->IsIncomplete()) return; - + BfLogSysM("RebuildMethods setting mNeedsMethodProcessing=true on %p\n", typeInstance); BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting); @@ -6804,13 +7175,13 @@ void BfModule::RebuildMethods(BfTypeInstance* typeInstance) delete methodInstanceGroup.mDefault; methodInstanceGroup.mDefault = NULL; delete methodInstanceGroup.mMethodSpecializationMap; - methodInstanceGroup.mMethodSpecializationMap = NULL; + methodInstanceGroup.mMethodSpecializationMap = NULL; methodInstanceGroup.mOnDemandKind = BfMethodOnDemandKind_NotSet; } BfTypeProcessRequest* typeProcessRequest = mContext->mPopulateTypeWorkList.Alloc(); typeProcessRequest->mType = typeInstance; - BF_ASSERT(typeInstance->mContext == mContext); + BF_ASSERT(typeInstance->mContext == mContext); mCompiler->mStats.mTypesQueued++; mCompiler->UpdateCompletion(); } @@ -6829,7 +7200,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) if (methodInstance->IsSpecializedByAutoCompleteMethod()) return; - + BF_ASSERT(mCompiler->mCompileState != BfCompiler::CompileState_VData); if ((methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized)) { @@ -6874,7 +7245,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) { auto module = GetOrCreateMethodModule(methodInstance); methodInstance->mDeclModule = module; - + BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline); methodInstance->mIRFunction = func; @@ -6886,20 +7257,20 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) if ((!methodInstance->mIRFunction) && (methodInstance->mIsReified) && (!methodInstance->mIsUnspecialized) && (methodInstance->GetImportCallKind() == BfImportCallKind_None)) - { + { if (!mIsModuleMutable) PrepareForIRWriting(methodInstance->GetOwner()); - + SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mWantsIRIgnoreWrites); - BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline); + BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline); if (func) { methodInstance->mIRFunction = func; mFuncReferences[methodInstance] = func; } } - + BF_ASSERT(methodInstance->mDeclModule == this); if (defaultMethod == methodInstance) @@ -6910,13 +7281,13 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) BF_ASSERT(methodInstance->mMethodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Referenced); if (!mIsScratchModule) - { + { auto onDemandModule = owningModule; if (owningModule->mParentModule != NULL) onDemandModule = owningModule->mParentModule; owningModule->VerifyOnDemandMethods(); - + if (methodInstance->mMethodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet) owningModule->mOnDemandMethodCount++; BF_ASSERT(onDemandModule->mOnDemandMethodCount > 0); @@ -6937,7 +7308,6 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) specMethodInstance->mDeclModule->AddMethodToWorkList(specMethodInstance); } } - } } else @@ -6948,7 +7318,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) BF_ASSERT(methodInstance->mDeclModule != NULL); auto typeInstance = methodInstance->GetOwner(); - + BfMethodProcessRequest* methodProcessRequest = mContext->mMethodWorkList.Alloc(); if (mCompiler->mCompileState == BfCompiler::CompileState_Unreified) { @@ -6960,7 +7330,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) } //BF_ASSERT(!methodInstance->mIsReified); methodProcessRequest->mType = typeInstance; - methodProcessRequest->mMethodInstance = methodInstance; + methodProcessRequest->mMethodInstance = methodInstance; methodProcessRequest->mRevision = typeInstance->mRevision; methodProcessRequest->mFromModuleRebuildIdx = mRebuildIdx; methodProcessRequest->mFromModule = this; @@ -6991,7 +7361,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) mIncompleteMethodCount++; if (methodInstance->GetNumGenericArguments() != 0) mHasGenericMethods = true; - + methodInstance->mMethodProcessRequest = methodProcessRequest; } @@ -7085,13 +7455,13 @@ BfConstExprValueType* BfModule::CreateConstExprValueType(const BfTypedValue& typ } } - if (variant.mTypeCode == BfTypeCode_None) + if (variant.mTypeCode == BfTypeCode_None) return NULL; auto constExprValueType = mContext->mConstExprValueTypePool.Get(); constExprValueType->mContext = mContext; constExprValueType->mType = typedValue.mType; - constExprValueType->mValue = variant; + constExprValueType->mValue = variant; auto resolvedConstExprValueType = (BfConstExprValueType*)ResolveType(constExprValueType, populateType, resolveFlags); if (resolvedConstExprValueType != constExprValueType) @@ -7104,7 +7474,7 @@ BfConstExprValueType* BfModule::CreateConstExprValueType(const BfTypedValue& typ } BfConstExprValueType* BfModule::CreateConstExprValueType(const BfVariant& variant, BfType* type, bool allowCreate) -{ +{ BfPopulateType populateType = allowCreate ? BfPopulateType_Data : BfPopulateType_Identity; BfResolveTypeRefFlags resolveFlags = allowCreate ? BfResolveTypeRefFlag_None : BfResolveTypeRefFlag_NoCreate; @@ -7160,7 +7530,7 @@ BfTypeInstance* BfModule::GetWrappedStructType(BfType* type, bool allowSpecializ { BfUnknownSizedArrayType* sizedArrayType = (BfUnknownSizedArrayType*)type; BfTypeVector typeVector; - typeVector.Add(sizedArrayType->mElementType); + typeVector.Add(sizedArrayType->mElementType); typeVector.Add(sizedArrayType->mElementCountSource); return ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, BfPopulateType_Data)->ToTypeInstance(); } @@ -7181,7 +7551,7 @@ BfTypeInstance* BfModule::GetWrappedStructType(BfType* type, bool allowSpecializ } BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode) -{ +{ BfPrimitiveType* primType = mContext->mPrimitiveTypes[typeCode]; if (primType == NULL) { @@ -7262,12 +7632,12 @@ BfPrimitiveType* BfModule::GetPrimitiveType(BfTypeCode typeCode) case BfTypeCode_StringId: BFMODULE_FATAL(this, "Invalid use of StringId"); break; - default: + default: BF_DBG_FATAL("Invalid type"); break; } mContext->mPrimitiveTypes[typeCode] = primType; - } + } return primType; } @@ -7275,28 +7645,28 @@ BfIRType BfModule::GetIRLoweredType(BfTypeCode loweredTypeCode, BfTypeCode lower { BF_ASSERT(!mIsComptimeModule); - BF_ASSERT(loweredTypeCode != BfTypeCode_None); - if (loweredTypeCode2 == BfTypeCode_None) - return mBfIRBuilder->GetPrimitiveType(loweredTypeCode); - + BF_ASSERT(loweredTypeCode != BfTypeCode_None); + if (loweredTypeCode2 == BfTypeCode_None) + return mBfIRBuilder->GetPrimitiveType(loweredTypeCode); + SizedArray types; types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode)); types.push_back(mBfIRBuilder->GetPrimitiveType(loweredTypeCode2)); - return mBfIRBuilder->CreateStructType(types); + return mBfIRBuilder->CreateStructType(types); } BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist) { - // Make sure we don't have a partially-formed local method or lambda coming in, because those may be replaced + // Make sure we don't have a partially-formed local method or lambda coming in, because those may be replaced // after the capture phase BF_ASSERT(!methodInstance->mDisallowCalling); auto methodRefType = new BfMethodRefType(); methodRefType->mContext = mContext; //methodRefType->mCaptureType = NULL; - methodRefType->mMethodRef = methodInstance; + methodRefType->mMethodRef = methodInstance; methodRefType->mOwner = methodInstance->GetOwner(); - methodRefType->mOwnerRevision = methodRefType->mOwner->mRevision; + methodRefType->mOwnerRevision = methodRefType->mOwner->mRevision; //methodRefType->mMangledName = BfMangler::Mangle(mCompiler->GetMangleKind(), methodInstance); methodRefType->mIsAutoCompleteMethod = methodInstance->mIsAutocompleteMethod; methodRefType->mIsUnspecialized = methodInstance->mIsUnspecialized; @@ -7308,7 +7678,7 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, BfResolvedTypeSet::EntryRef typeEntry; auto inserted = mContext->mResolvedTypes.Insert(methodRefType, &lookupCtx, &typeEntry); if (typeEntry->mValue == NULL) - { + { BF_ASSERT(!mustAlreadyExist); BF_ASSERT(!methodInstance->mHasMethodRefType); @@ -7321,7 +7691,7 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, BfLogSysM("Create MethodRefType %p MethodInstance: %p\n", methodRefType, methodInstance); methodRefType->mRevision = 0; AddDependency(methodInstance->GetOwner(), methodRefType, BfDependencyMap::DependencyFlag_Calls); - + BfTypeVector tupleTypes; Array tupleNames; @@ -7330,11 +7700,11 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, methodRefType->mAlign = 1; int dataIdx = 0; - - // CRepr, just because we're lazy (for now) + + // CRepr, just because we're lazy (for now) int implicitParamCount = methodInstance->GetImplicitParamCount(); for (int implicitParamIdx = methodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++) - { + { auto paramType = methodInstance->GetParamType(implicitParamIdx); if (!paramType->IsValuelessType()) { @@ -7347,7 +7717,7 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, methodRefType->mAlign = std::max(methodRefType->mAlign, paramType->mAlign); dataIdx++; - } + } else { methodRefType->mParamToDataIdx.Add(-1); @@ -7360,10 +7730,10 @@ BfMethodRefType* BfModule::CreateMethodRefType(BfMethodInstance* methodInstance, // { // methodRefType->mCaptureType = CreateTupleType(tupleTypes, tupleNames); // AddDependency(methodRefType->mCaptureType, methodRefType, BfDependencyMap::DependencyFlag_ReadFields); -// +// // methodRefType->mSize = methodRefType->mCaptureType->mSize; // methodRefType->mAlign = methodRefType->mCaptureType->mAlign; -// } +// } // else // { // methodRefType->mSize = 0; @@ -7465,8 +7835,8 @@ void BfModule::FixIntUnknown(BfTypedValue& typedVal, BfType* matchType) } void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs) -{ - if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()) && (rhs.mType != NULL) && +{ + if ((lhs.mType != NULL) && (lhs.mType->IsIntUnknown()) && (rhs.mType != NULL) && (rhs.mType->IsInteger()) && (!rhs.mType->IsIntUnknown())) { if (CanCast(lhs, rhs.mType)) @@ -7478,7 +7848,7 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs) } } - if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()) && (lhs.mType != NULL) && + if ((rhs.mType != NULL) && (rhs.mType->IsIntUnknown()) && (lhs.mType != NULL) && (lhs.mType->IsInteger()) && (!lhs.mType->IsIntUnknown())) { if (CanCast(rhs, lhs.mType)) @@ -7497,12 +7867,12 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs) void BfModule::FixValueActualization(BfTypedValue& typedVal, bool force) { if (!typedVal.mValue.IsConst()) - return; + return; if ((mBfIRBuilder->mIgnoreWrites) && (!force)) return; auto constant = mBfIRBuilder->GetConstant(typedVal.mValue); if (!HasUnactializedConstant(constant, mBfIRBuilder)) - return; + return; typedVal.mValue = ConstantToCurrent(constant, mBfIRBuilder, typedVal.mType, false); } @@ -7564,7 +7934,7 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef, bool allowCreate { auto primType = (BfPrimitiveType*)resolvedTypeRef; resolvedTypeRef = GetPrimitiveStructType(primType->mTypeDef->mTypeCode); - if (resolvedTypeRef == NULL) + if (resolvedTypeRef == NULL) return NULL; } else if (resolvedTypeRef->IsPointer()) @@ -7606,7 +7976,7 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef, bool allowCreate resolvedTypeRef = ResolveTypeDef(mCompiler->mSizedArrayTypeDef, typeVector, populateType, resolveFlags); if (resolvedTypeRef == NULL) return NULL; - } + } BfTypeInstance* typeInst = resolvedTypeRef->ToTypeInstance(); if ((typeInst == NULL) && (!resolvedTypeRef->IsGenericParam())) @@ -7634,7 +8004,7 @@ BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef); BfTupleType* tupleType = NULL; - + auto actualTupleType = mContext->mTupleTypePool.Get(); actualTupleType->Init(baseType->mTypeDef->mProject, baseType); @@ -7660,13 +8030,13 @@ BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const { BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx]; fieldInstance->mFieldIdx = fieldIdx; - BfType* fieldType = fieldTypes[fieldIdx]; + BfType* fieldType = fieldTypes[fieldIdx]; if ((fieldType->IsVar()) && (!allowVar)) fieldType = mContext->mBfObjectType; fieldInstance->SetResolvedType(fieldType); - fieldInstance->mOwner = tupleType; + fieldInstance->mOwner = tupleType; } - + tupleType->mIsUnspecializedType = false; tupleType->mIsUnspecializedTypeVariation = false; if (isUnspecialzied) @@ -7682,7 +8052,7 @@ BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const tupleType->Dispose(); mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType); } - + return (BfTupleType*)resolvedTupleType; } @@ -7694,7 +8064,7 @@ BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType) BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx]; if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet())) { - needsSanitize = true; + needsSanitize = true; break; } } @@ -7712,7 +8082,7 @@ BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType) if ((fieldInstance->mResolvedType->IsVar()) || (fieldInstance->mResolvedType->IsLet())) fieldTypes.Add(mContext->mBfObjectType); else - fieldTypes.Add(fieldInstance->mResolvedType); + fieldTypes.Add(fieldInstance->mResolvedType); if (!fieldDef->IsUnnamedTupleField()) { for (int i = 0; i < fieldIdx; i++) @@ -7741,7 +8111,7 @@ BfModifiedTypeType* BfModule::CreateModifiedTypeType(BfType* resolvedTypeRef, Bf retTypeType->mContext = mContext; retTypeType->mModifiedKind = modifiedKind; retTypeType->mElementType = resolvedTypeRef; - auto resolvedRetTypeType = ResolveType(retTypeType); + auto resolvedRetTypeType = ResolveType(retTypeType); if (resolvedRetTypeType != retTypeType) mContext->mModifiedTypeTypePool.GiveBack(retTypeType); return (BfModifiedTypeType*)resolvedRetTypeType; @@ -7773,7 +8143,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType if (typeDef->mTypeDeclaration == NULL) { BF_ASSERT(!typeDef->mIsDelegate && !typeDef->mIsFunction); - } + } //BF_ASSERT(typeDef->mTypeCode != BfTypeCode_Extension); BF_ASSERT(!typeDef->mIsPartial || typeDef->mIsCombinedPartial); @@ -7784,7 +8154,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType if (typeDef->mGenericParamDefs.size() != 0) return ResolveTypeDef(typeDef, BfTypeVector(), populateType, resolveFlags); - auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get(); + auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get(); typeDefTypeRef->mTypeDef = typeDef; auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType); if (resolvedtypeDefType == NULL) @@ -7812,7 +8182,7 @@ BfTypeInstance* BfModule::GetBaseType(BfTypeInstance* typeInst) } } - if ((typeInst->mBaseType == NULL) && (typeInst != mContext->mBfObjectType)) + if ((typeInst->mBaseType == NULL) && (typeInst != mContext->mBfObjectType)) PopulateType(typeInst, BfPopulateType_BaseType); return typeInst->mBaseType; } @@ -7827,7 +8197,7 @@ void BfModule::HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) && (autoComplete->mDefProp == NULL)) { - autoComplete->mDefType = typeDef; + autoComplete->mDefType = typeDef; autoComplete->mDefTypeGenericParamIdx = typeGenericParamIdx; autoComplete->SetDefinitionLocation(refNode); } @@ -7858,7 +8228,7 @@ void BfModule::HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDe mCompiler->mResolvePassData->HandleMethodGenericParam(refNode, typeDef, methodDef, methodGenericParamIdx); } -BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs) +BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopulateType populateType, bool ignoreErrors, int numGenericArgs, BfResolveTypeRefFlags resolveFlags) { BfTypeDef* nestedTypeDef = NULL; @@ -7901,7 +8271,7 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu findName = directStrTypeRef->mTypeName; if (!findName.Contains('.')) - { + { if (outerType->IsTypeInstance()) { auto outerTypeInstance = outerType->ToTypeInstance(); @@ -7918,10 +8288,11 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu while (checkOuterType != NULL) { for (auto checkType : checkOuterType->mTypeDef->mNestedTypes) - { + { auto latestCheckType = checkType->GetLatest(); - if ((!isFailurePass) && (!CheckProtection(latestCheckType->mProtection, latestCheckType, allowProtected, allowPrivate))) + if ((!isFailurePass) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreProtection) == 0) && + (!CheckProtection(latestCheckType->mProtection, latestCheckType, allowProtected, allowPrivate))) continue; if (checkType->mProject != checkOuterType->mTypeDef->mProject) @@ -7954,6 +8325,8 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu if ((outerTypeInstance->IsEnum()) && (findName == "UnderlyingType")) { + if (outerTypeInstance->IsDataIncomplete()) + PopulateType(outerTypeInstance); auto underlyingType = outerTypeInstance->GetUnderlyingType(); if (underlyingType != NULL) return underlyingType; @@ -7964,7 +8337,7 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu if (nestedTypeDef == NULL) { - if (!mIgnoreErrors && !ignoreErrors) + if ((!mIgnoreErrors) && (!ignoreErrors) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)) { StringT<64> name; name.Append(findName); @@ -7996,14 +8369,14 @@ BfType* BfModule::ResolveInnerType(BfType* outerType, BfAstNode* typeRef, BfPopu } if (genericArgs.size() != nestedTypeDef->mGenericParamDefs.size()) - { + { if (populateType == BfPopulateType_TypeDef) { // Probably from inside ResolveGenericInstanceDef, just return unresolved typedef genericArgs.clear(); } else - { + { ShowGenericArgCountError(typeRef, (int)nestedTypeDef->mGenericParamDefs.size() - (int)nestedTypeDef->mOuterType->mGenericParamDefs.size()); return NULL; } @@ -8089,7 +8462,7 @@ bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType) if (checkInnerType->mNestDepth <= checkOuterType->mNestDepth) return false; while (true) - { + { BfTypeDef* outerType = checkInnerType->mOuterType; if (outerType == NULL) return false; @@ -8098,7 +8471,7 @@ bool BfModule::IsInnerType(BfTypeDef* checkInnerType, BfTypeDef* checkOuterType) if (outerType->GetDefinition() == checkOuterType->GetDefinition()) return true; checkInnerType = checkInnerType->mOuterType; - } + } } BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& genericArgs, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags) @@ -8150,14 +8523,14 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic } BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); return resolvedType; - } + } BfTypeInstance* genericInstType; if (typeDef->mTypeCode == BfTypeCode_TypeAlias) genericInstType = mContext->mAliasTypePool.Get(); else genericInstType = mContext->mGenericTypeInstancePool.Get(); - delete genericInstType->mGenericTypeInfo; + delete genericInstType->mGenericTypeInfo; genericInstType->mGenericTypeInfo = new BfGenericTypeInfo(); BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0); @@ -8189,9 +8562,9 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic BfType* resolvedType = NULL; bool failed = false; - resolvedType = ResolveType(genericInstType, populateType, resolveFlags); + resolvedType = ResolveType(genericInstType, populateType, resolveFlags); if (resolvedType != genericInstType) - { + { BF_ASSERT(genericInstType->mGenericTypeInfo->mGenericParams.size() == 0); BF_ASSERT((genericInstType->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0); genericInstType->mRebuildFlags = (BfTypeRebuildFlags)(genericInstType->mRebuildFlags | BfTypeRebuildFlag_InTempPool); @@ -8233,16 +8606,16 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic auto namedTypeRef = BfNodeDynCast(typeRef); auto directStrTypeDef = BfNodeDynCastExact(typeRef); if ((namedTypeRef != NULL) || (directStrTypeDef != NULL)) - { + { BfTypeLookupError error; error.mRefNode = typeRef; - BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams, resolveFlags); + BfTypeDef* typeDef = FindTypeDef(typeRef, NULL, &error, numGenericParams, resolveFlags); if (typeDef != NULL) { BfAutoComplete* autoComplete = NULL; if (mCompiler->IsAutocomplete()) autoComplete = mCompiler->mResolvePassData->mAutoComplete; - + if ((autoComplete != NULL) && (autoComplete->mIsGetDefinition) && (autoComplete->IsAutocompleteNode(typeRef))) { if ((autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) && @@ -8294,7 +8667,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic if ((wasGenericParam) && ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0)) Fail("Cannot use generic param as generic instance type", typeRef); } - + if (typeDef == NULL) { if ((resolveFlags & BfResolveTypeRefFlag_IgnoreLookupError) == 0) @@ -8304,7 +8677,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic } if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) - { + { BfAutoParentNodeEntry autoParentNodeEntry(this, genericTypeRef); auto type = ResolveTypeRef(qualifiedTypeRef, BfPopulateType_TypeDef, resolveFlags, numGenericParams); if (type == NULL) @@ -8345,7 +8718,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty return resolvedType; } BF_ASSERT(allowFail); - } + } return unspecializedType; } @@ -8355,14 +8728,14 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty if (!unspecializedType->IsUnspecializedType()) { return unspecializedType; - } + } if (unspecializedType->IsUnknownSizedArrayType()) { auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType; auto elementType = ResolveGenericType(arrayType->mElementType, typeGenericArguments, methodGenericArguments, selfType, allowFail); if (elementType == NULL) - return NULL; + return NULL; if (elementType->IsVar()) return elementType; auto sizeType = ResolveGenericType(arrayType->mElementCountSource, typeGenericArguments, methodGenericArguments, selfType, allowFail); @@ -8419,7 +8792,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty return NULL; auto elementTypeInstance = elementType->ToTypeInstance(); if (elementTypeInstance == NULL) - return unspecializedType; + return unspecializedType; return CreateConcreteInterfaceType(elementTypeInstance); } @@ -8442,7 +8815,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty auto unspecializedTupleType = (BfTypeInstance*)unspecializedType; auto unspecializedGenericTupleType = unspecializedTupleType->ToGenericTypeInstance(); - Array fieldNames; + Array fieldNames; BfTypeVector fieldTypes; bool hadChange = false; @@ -8471,7 +8844,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty if (!hadChange) return unspecializedType; - + if (unspecializedGenericTupleType == NULL) wantGeneric = false; @@ -8541,8 +8914,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++) { - String fieldName = fieldNames[fieldIdx]; - BfFieldDef* fieldDef = actualTupleType->AddField(fieldName); + String fieldName = fieldNames[fieldIdx]; + BfFieldDef* fieldDef = actualTupleType->AddField(fieldName); } tupleType = actualTupleType; @@ -8563,11 +8936,11 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty BfType* resolvedType = NULL; if (!failed) resolvedType = ResolveType(tupleType, BfPopulateType_Identity); - + if (resolvedType != tupleType) { delete tupleType->mGenericTypeInfo; - tupleType->mGenericTypeInfo = NULL; + tupleType->mGenericTypeInfo = NULL; tupleType->Dispose(); mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType); } @@ -8580,7 +8953,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty BfTypeInstance* unspecializedDelegateType = (BfTypeInstance*)unspecializedType; BfTypeInstance* unspecializedGenericDelegateType = unspecializedType->ToGenericTypeInstance(); BfDelegateInfo* unspecializedDelegateInfo = unspecializedType->GetDelegateInfo(); - + bool wantGeneric = false; bool isUnspecialized = false; auto _CheckType = [&](BfType* type) @@ -8595,7 +8968,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty bool hasTypeGenerics = false; auto returnType = ResolveGenericType(unspecializedDelegateInfo->mReturnType, typeGenericArguments, methodGenericArguments, selfType, allowFail); - + if (returnType == NULL) return NULL; if (returnType->IsVar()) @@ -8612,7 +8985,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty return NULL; if (paramType->IsVar()) return paramType; - paramTypes.Add(paramType); + paramTypes.Add(paramType); _CheckType(paramType); } @@ -8622,9 +8995,9 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty //TODO: wantGeneric = false; - BfTypeInstance* delegateType = NULL; - auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); - + BfTypeInstance* delegateType = NULL; + auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); + if (wantGeneric) { Array genericArgs; @@ -8635,10 +9008,10 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty { resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, selfType, allowFail); if (resolvedArg == NULL) - return NULL; + return NULL; if (resolvedArg->IsVar()) return resolvedArg; - } + } genericArgs.push_back(resolvedArg); } @@ -8672,14 +9045,14 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty auto dlgType = mContext->mDelegateTypePool.Get(); dlgType->mIsUnspecializedType = isUnspecialized; dlgType->mIsUnspecializedTypeVariation = isUnspecialized; - delegateType = dlgType; + delegateType = dlgType; } delete delegateType->mTypeDef; delegateType->mTypeDef = NULL; BfDelegateInfo* delegateInfo = delegateType->GetDelegateInfo(); delegateInfo->mParams.Clear(); - + BfTypeDef* typeDef = new BfTypeDef(); typeDef->mProject = baseDelegateType->mTypeDef->mProject; @@ -8688,7 +9061,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty typeDef->mTypeCode = unspecializedDelegateType->mTypeDef->mTypeCode; typeDef->mIsDelegate = unspecializedDelegateType->mTypeDef->mIsDelegate; typeDef->mIsFunction = unspecializedDelegateType->mTypeDef->mIsFunction; - + BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke"); BfMethodDef* methodDef = new BfMethodDef(); @@ -8698,7 +9071,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty methodDef->mIdx = 0; methodDef->mIsStatic = !typeDef->mIsDelegate && !unspecializedDelegateInfo->mHasExplicitThis; methodDef->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis; - + auto directTypeRef = BfAstNode::ZeroedAlloc(); delegateInfo->mDirectAllocNodes.push_back(directTypeRef); if (typeDef->mIsDelegate) @@ -8711,20 +9084,20 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(returnType); methodDef->mReturnTypeRef = directTypeRef; - delegateInfo->mReturnType = returnType; + delegateInfo->mReturnType = returnType; delegateInfo->mHasExplicitThis = unspecializedDelegateInfo->mHasExplicitThis; delegateInfo->mHasVarArgs = unspecializedDelegateInfo->mHasVarArgs; int paramIdx = 0; - for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) - { + for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) + { auto paramType = paramTypes[paramIdx]; - + BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx]; - + if (!paramType->IsReified()) delegateType->mIsReified = false; - + auto directTypeRef = BfAstNode::ZeroedAlloc(); delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(paramType); @@ -8746,9 +9119,8 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty methodDef->mIsMutating = unspecializedInvokeMethodDef->mIsMutating; } + // - // - if (typeDef->mIsDelegate) { BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, ""); @@ -8757,7 +9129,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty delegateType->mContext = mContext; delegateType->mTypeDef = typeDef; - + BfType* resolvedType = NULL; if (!failed) resolvedType = ResolveType(delegateType, BfPopulateType_Identity); @@ -8765,12 +9137,12 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty { AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); for (auto paramType : paramTypes) - AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); } else - { + { delegateType->Dispose(); - mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType); + mContext->mDelegateTypePool.GiveBack((BfDelegateType*)delegateType); } BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); return resolvedType; @@ -8801,7 +9173,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty if (resolvedType != NULL) specializedType = resolvedType->ToGenericTypeInstance(); if (specializedType != NULL) - { + { if (specializedType->mGenericTypeInfo->mHadValidateErrors) return NULL; } @@ -8815,17 +9187,17 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty BfType* BfModule::ResolveSelfType(BfType* type, BfType* selfType) { if (!type->IsUnspecializedTypeVariation()) - return type; + return type; return ResolveGenericType(type, NULL, NULL, selfType); } BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags) { BfResolvedTypeSet::LookupContext lookupCtx; - lookupCtx.mModule = this; + lookupCtx.mModule = this; lookupCtx.mResolveFlags = resolveFlags; BfResolvedTypeSet::EntryRef resolvedEntry; - bool inserted = mContext->mResolvedTypes.Insert(lookupType, &lookupCtx, &resolvedEntry); + bool inserted = mContext->mResolvedTypes.Insert(lookupType, &lookupCtx, &resolvedEntry); if (!resolvedEntry) return NULL; @@ -8836,22 +9208,21 @@ BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType, B PopulateType(resolvedTypeRef, populateType); return resolvedTypeRef; } - + if (lookupType->IsGenericTypeInstance()) CheckUnspecializedGenericType((BfTypeInstance*)lookupType, populateType); if (lookupType->IsTuple()) - { + { auto tupleType = (BfTupleType*)lookupType; - tupleType->Finish(); + tupleType->Finish(); } resolvedEntry->mValue = lookupType; - InitType(lookupType, populateType); + InitType(lookupType, populateType); return lookupType; } - bool BfModule::IsUnboundGeneric(BfType* type) { if (type->IsVar()) @@ -8889,9 +9260,11 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL) { + bool isAutocomplete = (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL); + auto activeTypeDef = GetActiveTypeDef(NULL, true); if ((activeTypeDef->mTypeDeclaration != genericTypeInst->mTypeDef->mTypeDeclaration) && (activeTypeDef->IsExtension()) && - (genericTypeInst->mTypeDef->ContainsPartial(activeTypeDef))) + ((genericTypeInst->mTypeDef->ContainsPartial(activeTypeDef)) || (isAutocomplete))) { BfTypeDef* lookupTypeDef = activeTypeDef; while (lookupTypeDef->mNestDepth > genericTypeInst->mTypeDef->mNestDepth) @@ -8899,12 +9272,12 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId BfGenericExtensionEntry* genericExEntry; if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(lookupTypeDef, &genericExEntry)) - { + { return genericExEntry->mGenericParams[genericParamIdx]; } else { - if ((mCompiler->mResolvePassData == NULL) || (mCompiler->mResolvePassData->mAutoComplete == NULL)) + if (!isAutocomplete) { FatalError("Invalid GetGenericParamInstance with extension"); } @@ -8930,7 +9303,7 @@ void BfModule::GetActiveTypeGenericParamInstances(SizedArray prevTypeInst(mCurTypeInstance, NULL); PopulateType(genericTypeInst, BfPopulateType_Declaration); } - + if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL) { auto activeTypeDef = GetActiveTypeDef(NULL, true); @@ -8969,7 +9342,7 @@ void BfModule::GetActiveTypeGenericParamInstances(SizedArraymGenericParamFlags; outTypeConstraint = genericParam->mTypeConstraint; @@ -8992,16 +9365,23 @@ BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfGenericParamType* return genericParam; } -BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type) +BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind) { if (type->mGenericParamKind == BfGenericParamKind_Method) { - if ((mCurMethodInstance == NULL) || (mCurMethodInstance->mMethodInfoEx == NULL) || (type->mGenericParamIdx >= mCurMethodInstance->mMethodInfoEx->mGenericParams.mSize)) + auto curGenericMethodInstance = mCurMethodInstance; + if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)) + { + if ((checkMixinBind) || (mCurMethodState->mMixinState->mUseMixinGenerics)) + curGenericMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance; + } + + if ((curGenericMethodInstance == NULL) || (curGenericMethodInstance->mMethodInfoEx == NULL) || (type->mGenericParamIdx >= curGenericMethodInstance->mMethodInfoEx->mGenericParams.mSize)) { FatalError("Invalid GetGenericParamInstance method generic param"); return NULL; } - return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; + return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; } return GetGenericTypeParamInstance(type->mGenericParamIdx); @@ -9013,7 +9393,7 @@ bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTy return true; BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance(); - + if ((genericTypeInstance != NULL) && (genericTypeInstance != mCurTypeInstance)) { bool doValidate = (genericTypeInstance->mGenericTypeInfo->mHadValidateErrors) || @@ -9049,13 +9429,13 @@ bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTy { if (genericTypeInstance != NULL) { - auto genericTypeInfo = genericTypeInstance->GetGenericTypeInfo(); + auto genericTypeInfo = genericTypeInstance->GetGenericTypeInfo(); for (int argIdx = 0; argIdx < (int)genericInstanceTypeRef->mGenericArguments.size(); argIdx++) { ResolveTypeResult_Validate(genericInstanceTypeRef->mGenericArguments[argIdx], genericTypeInfo->mTypeGenericArguments[argIdx]); } } - } + } else if (auto elementedTypeRef = BfNodeDynCast(typeRef)) { return ResolveTypeResult_Validate(elementedTypeRef, resolvedTypeRef->GetUnderlyingType()); @@ -9068,7 +9448,7 @@ BfType* BfModule::SafeResolveAliasType(BfTypeAliasType* aliasType) { int aliasDepth = 0; HashSet seenAliases; - + BfType* type = aliasType; while (type->IsTypeAlias()) { @@ -9081,7 +9461,7 @@ BfType* BfModule::SafeResolveAliasType(BfTypeAliasType* aliasType) type = type->GetUnderlyingType(); if (type == NULL) - return NULL; + return NULL; } return type; } @@ -9136,7 +9516,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if (resolvedTypeRef != NULL) resolvedTypeInstance = resolvedTypeRef->ToTypeInstance(); - bool isNamespace = false; + bool isNamespace = false; auto checkTypeRef = typeRef; if (auto genericTypeRef = BfNodeDynCast(checkTypeRef)) checkTypeRef = genericTypeRef->mElementType; @@ -9156,7 +9536,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy //mCompiler->mResolvePassData->mSourceClassifier->VisitChildNoRef(typeRef); } } - + BfSourceElementType elemType = BfSourceElementType_Type; { auto type = resolvedTypeRef; @@ -9204,7 +9584,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy autoComplete->CheckNamespace(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace); } mCompiler->mResolvePassData->HandleNamespaceReference(qualifiedTypeRef->mLeft, resolvedTypeInstance->mTypeDef->mNamespace); - + isNamespace = true; } checkTypeRef = qualifiedTypeRef->mLeft; @@ -9216,7 +9596,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy bool setType = false; if ((sourceClassifier != NULL) && (checkTypeRef == headTypeRef) && (elemType != BfSourceElementType_Type)) - { + { if (auto qualifiedNameNode = BfNodeDynCast(checkNameNode)) { sourceClassifier->SetElementType(qualifiedNameNode->mRight, elemType); @@ -9268,8 +9648,8 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy elementTypeRef = namedTypeRef->mNameNode; if (elementTypeRef != NULL) - { - BfType* elementType = resolvedTypeRef; + { + BfType* elementType = resolvedTypeRef; if (BfTypeInstance* elementTypeInst = elementType->ToTypeInstance()) { mCompiler->mResolvePassData->HandleTypeReference(elementTypeRef, elementTypeInst->mTypeDef); @@ -9308,7 +9688,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if ((baseNode != NULL) && (autoComplete->IsAutocompleteNode(baseNode))) { - // We didn't have this mDefType check before - why? We always want to catch the FIRST definition, + // We didn't have this mDefType check before - why? We always want to catch the FIRST definition, // so 'Type?' will catch on 'Type' and not 'Type?' if ((autoComplete->mDefType == NULL) && (autoComplete->mDefMethod == NULL) && (autoComplete->mDefField == NULL) && @@ -9320,18 +9700,18 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if ((autoComplete->mResolveType == BfResolveType_GetResultString) && (resolvedTypeRef != NULL)) { - autoComplete->SetResultStringType(resolvedTypeRef); + autoComplete->SetResultStringType(resolvedTypeRef); } } } } - } + } } } } if (resolvedTypeRef == NULL) - return NULL; + return NULL; if (mCurTypeInstance == NULL) { @@ -9344,39 +9724,56 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy BfTypeInstance* payloadTupleType = (BfTypeInstance*)resolvedTypeRef; for (auto& payloadFieldInst : payloadTupleType->mFieldInstances) { - auto payloadFieldType = payloadFieldInst.mResolvedType; + auto payloadFieldType = payloadFieldInst.mResolvedType; AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); } } else if (resolvedTypeRef->IsDelegateFromTypeRef() || resolvedTypeRef->IsFunctionFromTypeRef()) - { + { auto delegateInfo = resolvedTypeRef->GetDelegateInfo(); // if (delegateInfo->mFunctionThisType != NULL) // AddDependency(delegateInfo->mFunctionThisType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); AddDependency(delegateInfo->mReturnType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); for (auto& param : delegateInfo->mParams) - AddDependency(param, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); + AddDependency(param, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference); } BfTypeInstance* typeInstance = resolvedTypeRef->ToTypeInstance(); - BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance(); - + BfTypeInstance* genericTypeInstance = resolvedTypeRef->ToGenericTypeInstance(); + auto populateModule = this; if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0) populateModule = mContext->mUnreifiedModule; - + populateModule->PopulateType(resolvedTypeRef, populateType); - - if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL) && (typeInstance->mTypeDef->mProtection == BfProtection_Internal) && - (typeInstance != mCurTypeInstance) && (typeInstance->mTypeDef->mOuterType == NULL) && (!typeRef->IsTemporary())) + + if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL) && (typeInstance->mTypeDef->mProtection == BfProtection_Internal) && + (typeInstance != mCurTypeInstance) && (typeInstance->mTypeDef->mOuterType == NULL) && (!typeRef->IsTemporary())) { if (!CheckProtection(typeInstance->mTypeDef->mProtection, typeInstance->mTypeDef, false, false)) Fail(StrFormat("'%s' is inaccessible due to its protection level", TypeToString(typeInstance).c_str()), typeRef); // CS0122 } - if ((populateType > BfPopulateType_IdentityNoRemapAlias) && (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef))) - return NULL; - + // If the inner type is definted in an extension then we need to make sure the constraints are good + if ((typeInstance != NULL) && (typeInstance->mTypeDef != NULL) && (typeInstance->mTypeDef->mOuterType != NULL) && + (typeInstance->mTypeDef->mOuterType->mTypeCode == BfTypeCode_Extension)) + { + auto outerType = GetOuterType(typeInstance); + if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mGenericExtensionInfo != NULL)) + { + if (!outerType->mGenericTypeInfo->mGenericExtensionInfo->mConstraintsPassedSet.IsSet(typeInstance->mTypeDef->mOuterType->mPartialIdx)) + { + Fail(StrFormat("'%s' is declared inside a type extension whose constraints were not met", TypeToString(typeInstance).c_str()), typeRef); + } + } + } + + if (populateType > BfPopulateType_IdentityNoRemapAlias) + { + if (!ResolveTypeResult_Validate(typeRef, resolvedTypeRef)) + return NULL; + } + if ((populateType != BfPopulateType_TypeDef) && (populateType != BfPopulateType_IdentityNoRemapAlias)) { int aliasDepth = 0; @@ -9400,12 +9797,12 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined) PopulateType(resolvedTypeRef); if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary())) - CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef); - resolvedTypeRef = resolvedTypeRef->GetUnderlyingType(); + CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef); + resolvedTypeRef = resolvedTypeRef->GetUnderlyingType(); if (resolvedTypeRef != NULL) typeInstance = resolvedTypeRef->ToTypeInstance(); else - typeInstance = NULL; + typeInstance = NULL; } } @@ -9496,12 +9893,12 @@ void BfModule::ShowGenericArgCountError(BfAstNode* typeRef, int wantedGenericPar } } else - genericArgDiffCount = -wantedGenericParams; - + genericArgDiffCount = -wantedGenericParams; + if (wantedGenericParams == 1) Fail("Too few generic parameters, expected one more", lastNode); else - Fail(StrFormat("Too few generic parameters, expected %d more", -genericArgDiffCount), lastNode); + Fail(StrFormat("Too few generic parameters, expected %d more", -genericArgDiffCount), lastNode); } BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool useMixinDecl) @@ -9515,7 +9912,15 @@ BfTypeDef* BfModule::GetActiveTypeDef(BfTypeInstance* typeInstanceOverride, bool if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (useMixinDecl)) useTypeDef = mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->GetDefinition(); else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType != NULL)) - useTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType->GetDefinition(); + { + auto declTypeDef = mCurMethodInstance->mMethodDef->mDeclaringType; + useTypeDef = declTypeDef->GetDefinition(); + if ((declTypeDef->IsEmitted()) && (useTypeDef->mIsCombinedPartial)) + { + // Always consider methods to belong to the primary type declaration + useTypeDef = useTypeDef->mPartials[0]; + } + } else if (mContext->mCurTypeState != NULL) { if ((mContext->mCurTypeState->mCurFieldDef != NULL) && (mContext->mCurTypeState->mCurFieldDef->mDeclaringType != NULL)) @@ -9534,7 +9939,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene return mSystem->FindTypeDef(findName, 0, useTypeDef->mProject); } - BfTypeInstance* skipCheckBaseType = NULL; + BfTypeInstance* skipCheckBaseType = NULL; if (mContext->mCurTypeState != NULL) { if (mContext->mCurTypeState->mCurBaseTypeRef != NULL) @@ -9551,7 +9956,7 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene BfTypeDef* protErrorTypeDef = NULL; BfTypeInstance* protErrorOuterType = NULL; - + BfTypeDef* foundInnerType = NULL; if ((lookupResultCtx != NULL) && (lookupResultCtx->mIsVerify)) @@ -9620,12 +10025,12 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene { if (mSystem->mTypeDefs.TryGet(findName, NULL)) mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, BfAtomComposite(), allowPrivate, &lookupCtx); - + for (auto& checkNamespace : useTypeDef->mNamespaceSearch) - { - BfAtom* atom = findName.mParts[0]; + { + BfAtom* atom = findName.mParts[0]; BfAtom* prevAtom = checkNamespace.mParts[checkNamespace.mSize - 1]; - if (atom->mPrevNamesMap.ContainsKey(prevAtom)) + if (atom->mPrevNamesMap.ContainsKey(prevAtom)) mSystem->FindTypeDef(findName, numGenericArgs, useTypeDef->mProject, checkNamespace, allowPrivate, &lookupCtx); } } @@ -9641,27 +10046,27 @@ BfTypeDef* BfModule::FindTypeDefRaw(const BfAtomComposite& findName, int numGene { if (lookupCtx.HasValidMatch()) break; - + if (lookupCtx.mBestTypeDef->mProtection < BfProtection_Public) { protErrorTypeDef = lookupCtx.mBestTypeDef; protErrorOuterType = staticTypeInstance; - } + } } } } } - + if ((!lookupCtx.HasValidMatch()) && (typeInstance == NULL)) { if (useTypeDef->mOuterType != NULL) return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef->mOuterType, error); } - + if ((error != NULL) && (lookupCtx.mAmbiguousTypeDef != NULL)) { - if (error->mErrorKind == BfTypeLookupError::BfErrorKind_None) - error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous; + if (error->mErrorKind == BfTypeLookupError::BfErrorKind_None) + error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous; error->mAmbiguousTypeDef = lookupCtx.mAmbiguousTypeDef; if (error->mRefNode != NULL) @@ -9694,7 +10099,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric useTypeDef = useTypeDef->GetDefinition(); if ((typeInstance == NULL) && (useTypeDef == NULL)) - { + { BfProject* project = NULL; if ((mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mActiveProject != NULL)) project = mContext->mCurTypeState->mActiveProject; @@ -9713,7 +10118,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric if (!checkNamespace.IsEmpty()) checkNamespace += "."; namespaceNode->mNameNode->ToString(checkNamespace); - } + } } if (!checkNamespace.IsEmpty()) @@ -9724,8 +10129,12 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric } } + BfFindTypeDefFlags findDefFlags = BfFindTypeDefFlag_None; + if ((resolveFlags & BfResolveTypeRefFlag_AllowGlobalContainer) != 0) + findDefFlags = (BfFindTypeDefFlags)(findDefFlags | BfFindTypeDefFlag_AllowGlobal); + BfTypeDef* ambiguousTypeDef = NULL; - BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, namespaceSearch, &ambiguousTypeDef); + BfTypeDef *result = mSystem->FindTypeDef(findName, numGenericArgs, project, namespaceSearch, &ambiguousTypeDef, findDefFlags); if ((ambiguousTypeDef != NULL) && (error != NULL)) { error->mErrorKind = BfTypeLookupError::BfErrorKind_Ambiguous; @@ -9735,7 +10144,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric } return result; - } + } if ((mCompiler->mResolvePassData != NULL) && (typeInstance != NULL)) { @@ -9758,7 +10167,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric if (useTypeDef->mIsPartial) isValid = typeInstance->mTypeDef->GetDefinition()->ContainsPartial(useTypeDef); else - isValid = typeInstance->mTypeDef->GetDefinition() == useTypeDef; + isValid = typeInstance->mTypeDef->GetDefinition() == useTypeDef; if ((!isValid) && (mCurMethodInstance != NULL) && (mCurMethodInstance->mIsForeignMethodDef)) { @@ -9767,7 +10176,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric } BF_ASSERT(isValid); - + typeLookupEntryPtr->mAtomUpdateIdx = typeLookupEntry.mName.GetAtomUpdateIdx(); // FindTypeDefRaw may re-enter when finding base types, so we need to expect that resultPtr can change @@ -9789,7 +10198,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric } resultPtr->mTypeDef = typeDef; - resultPtr->mForceLookup = errorPtr->mErrorKind != BfTypeLookupError::BfErrorKind_None; + resultPtr->mForceLookup = errorPtr->mErrorKind != BfTypeLookupError::BfErrorKind_None; return typeDef; } @@ -9799,7 +10208,7 @@ BfTypeDef* BfModule::FindTypeDef(const BfAtomComposite& findName, int numGeneric return FindTypeDefRaw(findName, numGenericArgs, typeInstance, useTypeDef, error, NULL, resolveFlags); else return resultPtr->mTypeDef; - } + } } BfTypeDef* BfModule::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfTypeInstance* typeInstanceOverride, BfTypeLookupError* error, BfResolveTypeRefFlags resolveFlags) @@ -9812,7 +10221,7 @@ BfTypeDef* BfModule::FindTypeDef(const StringImpl& typeName, int numGenericArgs, auto result = FindTypeDef(findName, numGenericArgs, typeInstanceOverride, error, resolveFlags); // Don't allow just finding extensions here. This can happen in some 'using static' cases but generally shouldn't happen if ((result != NULL) && (result->mTypeCode == BfTypeCode_Extension)) - return NULL; + return NULL; return result; } @@ -9833,7 +10242,7 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI BF_ASSERT(typeRef->IsA() || typeRef->IsA() || typeRef->IsA()); auto namedTypeRef = BfNodeDynCast(typeRef); - StringView findNameStr; + StringView findNameStr; if (namedTypeRef != NULL) findNameStr = namedTypeRef->mNameNode->ToStringView(); else @@ -9857,7 +10266,7 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI findNameStr = "System.String"; Fail("'string' alias not supported, use 'String'", typeRef); } - } + } BfSizedAtomComposite findName; if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0) @@ -9865,21 +10274,20 @@ BfTypeDef* BfModule::FindTypeDef(BfTypeReference* typeRef, BfTypeInstance* typeI String attributeName; attributeName += findNameStr; attributeName += "Attribute"; - if (!mSystem->ParseAtomComposite(attributeName, findName)) - return NULL; + if (!mSystem->ParseAtomComposite(attributeName, findName)) + return NULL; } else { - if (!mSystem->ParseAtomComposite(findNameStr, findName)) - return NULL; + if (!mSystem->ParseAtomComposite(findNameStr, findName)) + return NULL; } - - + #ifdef BF_AST_HAS_PARENT_MEMBER if (auto parentGenericTypeRef = BfNodeDynCast(typeRef->mParent)) { if (parentGenericTypeRef->mElementType == typeRef) - BF_ASSERT(numGenericParams == parentGenericTypeRef->GetGenericArgCount()); + BF_ASSERT(numGenericParams == parentGenericTypeRef->GetGenericArgCount()); } #endif @@ -9897,10 +10305,10 @@ void BfModule::CheckTypeRefFixit(BfAstNode* typeRef, const char* appendName) String typeName = typeRef->ToString(); if (appendName != NULL) typeName += appendName; - + std::set fixitNamespaces; - //TODO: Do proper value for numGenericArgs + //TODO: Do proper value for numGenericArgs mSystem->FindFixitNamespaces(typeName, -1, mCompiler->mResolvePassData->mParsers[0]->mProject, fixitNamespaces); int insertLoc = 0; @@ -9946,7 +10354,7 @@ void BfModule::TypeRefNotFound(BfTypeReference* typeRef, const char* appendName) { //BfTypeInstance* typeInstance = (typeInstanceOverride != NULL) ? typeInstanceOverride : mCurTypeInstance; // We don't need a typeInstanceOverride because that is used to lookup references - // from mixins, but it's the type using the mixin (mCurTypeInstance) that needs + // from mixins, but it's the type using the mixin (mCurTypeInstance) that needs // rebuilding if the lookup fails BfTypeInstance* typeInstance = mCurTypeInstance; BfTypeLookupEntry typeLookupEntry; @@ -9967,20 +10375,20 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) if (auto wildcardTypeRef = BfNodeDynCast(typeRef)) return true; - + StringT<128> nameStr; typeRef->ToString(nameStr); if (isAttributeRef) nameStr.Append("Attribute"); auto typeDef = mSystem->FindTypeDef(nameStr, (BfProject*)NULL); if ((typeDef != NULL) && (typeDef->mGenericParamDefs.IsEmpty())) - return true; + return true; if (auto qualifiedTypeRef = BfNodeDynCast(typeRef)) { if (qualifiedTypeRef->mLeft == NULL) return false; - + if (auto wildcardTypeRef = BfNodeDynCast(qualifiedTypeRef->mRight)) { StringT<128> leftNameStr; @@ -9997,7 +10405,7 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) return ValidateTypeWildcard(qualifiedTypeRef->mLeft, false); } - } + } if (!BfNodeIsA(typeRef)) { @@ -10026,10 +10434,10 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) if (auto genericTypeRef = BfNodeDynCast(typeRef)) { _ToString(genericTypeRef->mElementType, false); - genericCount += genericTypeRef->mCommas.mSize + 1; + genericCount += genericTypeRef->mCommas.mSize + 1; for (auto genericArg : genericTypeRef->mGenericArguments) if (!ValidateTypeWildcard(genericArg, false)) - return false; + return false; } else { @@ -10057,7 +10465,7 @@ bool BfModule::ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef) BfAtomCompositeT<16> compositeEx; if (!mSystem->ParseAtomComposite(nameEx, compositeEx)) return false; - + auto itr = mSystem->mTypeDefs.TryGet(composite); while (itr != mSystem->mTypeDefs.end()) { @@ -10087,7 +10495,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod if (contextTypeInstance != NULL) { curTypeDef = contextTypeInstance->mTypeDef; - + StringT<128> findName; identifierNode->ToString(findName); @@ -10101,7 +10509,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod genericCheckTypeInstance = GetUnspecializedTypeInstance(genericCheckTypeInstance); doUndefVal = true; } - + BfGenericParamDef* genericParamDef = NULL; BfGenericParamDef* origGenericParamDef = NULL; BfType* genericParamResult = NULL; @@ -10112,18 +10520,18 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance; auto* genericParams = &curTypeDef->mGenericParamDefs; auto* origGenericParams = &curTypeDef->mGenericParamDefs; - + if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL) { auto activeTypeDef = GetActiveTypeDef(NULL, true); genericParams = &activeTypeDef->mGenericParamDefs; - } - + } + for (int genericParamIdx = (int)genericParams->size() - 1; genericParamIdx >= 0; genericParamIdx--) { auto checkGenericParamDef = (*genericParams)[genericParamIdx]; String genericName = checkGenericParamDef->mName; - + if (genericName == findName) { genericParamDef = checkGenericParamDef; @@ -10175,7 +10583,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod } if (genericParamResult != NULL) - { + { auto typeRefSource = identifierNode->GetSourceData(); if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mIsClassifying) && (typeRefSource != NULL)) { @@ -10193,7 +10601,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod BfExprEvaluator exprEvaluator(this); exprEvaluator.mExpectingType = constType; - exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue); + exprEvaluator.GetLiteral(identifierNode, constExprValueType->mValue); if (exprEvaluator.mResult) { @@ -10201,7 +10609,7 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod if (castedVal) return BfTypedValue(castedVal, constType); } - + return exprEvaluator.mResult; } else if (genericParamResult->IsGenericParam()) @@ -10246,7 +10654,7 @@ void BfModule::GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, } } delete customAttributes; - } + } } BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs) @@ -10283,7 +10691,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } if (auto dotType = BfNodeDynCastExact(typeRef)) - { + { Fail(StrFormat("Invalid use of '%s'", BfTokenToString(dotType->mDotToken->mToken)), typeRef); return NULL; } @@ -10359,13 +10767,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { Fail("'Self' type is not usable here", typeRef); } - return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags); + return ResolveTypeResult(typeRef, selfType, populateType, resolveFlags); } else if (findName == "SelfBase") { BfType* selfType = mCurTypeInstance; if (selfType->IsTypeAlias()) - selfType = GetOuterType(selfType); + selfType = GetOuterType(selfType); if (selfType != NULL) { resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_FromIndirectSource); @@ -10394,7 +10802,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (baseType == NULL) { Fail("'SelfBase' type is not usable here", typeRef); - } + } return ResolveTypeResult(typeRef, baseType, populateType, resolveFlags); } else if (findName == "SelfOuter") @@ -10486,7 +10894,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } } - + if ((genericCheckTypeInstance != NULL) && (genericCheckTypeInstance->IsGenericTypeInstance()) && (genericParamResult == NULL)) { auto genericTypeInst = (BfTypeInstance*)genericCheckTypeInstance; @@ -10517,7 +10925,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { SetAndRestoreValue prevSymbolRefKind; if (mCompiler->mResolvePassData != NULL) // Don't add these typeRefs, they are indirect - prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None); + prevSymbolRefKind.Init(mCompiler->mResolvePassData->mGetSymbolReferenceKind, BfGetSymbolReferenceKind_None); genericParamResult = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[genericParamIdx]; if ((genericParamResult != NULL) && (genericParamResult->IsConstExprValue()) && @@ -10526,7 +10934,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } } - } + } if (genericParamResult != NULL) { @@ -10548,8 +10956,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } BfTypeDef* typeDef = NULL; - - if (typeRef->IsNamedTypeReference()) + + if (typeRef->IsNamedTypeReference()) { BfTypeLookupError error; error.mRefNode = typeRef; @@ -10563,7 +10971,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula auto leftType = ResolveTypeRef(qualifiedNameNode->mLeft, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef)); if ((leftType != NULL) && (qualifiedNameNode->mRight != NULL)) { - // Try searching within inner type + // Try searching within inner type auto resolvedType = ResolveInnerType(leftType, qualifiedNameNode->mRight, populateType, true); if (resolvedType != NULL) { @@ -10574,7 +10982,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } } - + if ((typeDef == NULL) && (mCurTypeInstance != NULL)) { // Try searching within inner type @@ -10596,7 +11004,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula checkOuterType = GetOuterType(checkOuterType); } } - + if (typeDef == NULL) { auto staticSearch = GetStaticSearch(); @@ -10643,7 +11051,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } return NULL; - } + } } else if (auto typeDefTypeRef = BfNodeDynCastExact(typeRef)) { @@ -10676,19 +11084,21 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula StringT<128> findName; auto genericTypeRef = BfNodeDynCast(qualifiedTypeRef->mRight); - auto activeTypeDef = GetActiveTypeDef(); + auto activeTypeDef = GetActiveTypeDef(); BfProject* bfProject = NULL; if (activeTypeDef != NULL) bfProject = activeTypeDef->mProject; if (mSystem->ContainsNamespace(leftComposite, bfProject)) - { + { qualifiedTypeRef->mLeft->ToString(findName); findName.Append('.'); if (genericTypeRef != NULL) genericTypeRef->mElementType->ToString(findName); else qualifiedTypeRef->mRight->ToString(findName); + if ((resolveFlags & BfResolveTypeRefFlag_Attribute) != 0) + findName += "Attribute"; } else if ((activeTypeDef != NULL) && (activeTypeDef->mNamespace.EndsWith(leftComposite))) { @@ -10701,7 +11111,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (!findName.IsEmpty()) { - int wantNumGenericArgs = 0; + int wantNumGenericArgs = numGenericArgs; #ifdef BF_AST_HAS_PARENT_MEMBER if (auto genericTypeParent = BfNodeDynCast(typeRef->mParent)) { @@ -10722,11 +11132,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfTypeDef* ambiguousTypeDef = NULL; - //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef); - - //auto typeDef = mSystem->FindTypeDef(findName, wantNumGenericArgs, bfProject, {}, &ambiguousTypeDef); BfTypeLookupError lookupError; - auto typeDef = FindTypeDef(findName, wantNumGenericArgs, NULL, &lookupError); + auto typeDef = FindTypeDef(findName, wantNumGenericArgs, NULL, &lookupError, resolveFlags); if (typeDef != NULL) { if (ambiguousTypeDef != NULL) @@ -10771,9 +11178,18 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (leftType == NULL) { BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef); - leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError)); // We throw an error below if we can't find the type + + auto leftPopulateType = BfPopulateType_Identity; + if ((resolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) == 0) + { + // We can't just pass 'Identity' here because it won't validate a generic type ref on the left + leftPopulateType = BfPopulateType_Declaration; + } + + leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, leftPopulateType, + (BfResolveTypeRefFlags)((resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError) & ~BfResolveTypeRefFlag_Attribute)); // We throw an error below if we can't find the type } - + if (leftType == NULL) { mIgnoreErrors = prevIgnoreErrors.mPrevVal; @@ -10809,7 +11225,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } - auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs); + auto resolvedType = ResolveInnerType(leftType, qualifiedTypeRef->mRight, populateType, false, numGenericArgs, resolveFlags); if ((resolvedType != NULL) && (mCurTypeInstance != NULL)) AddDependency(leftType, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference); return ResolveTypeResult(typeRef, resolvedType, populateType, resolveFlags); @@ -10824,7 +11240,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } if (auto retTypeTypeRef = BfNodeDynCastExact(typeRef)) - { + { if (retTypeTypeRef->mRetTypeToken->mToken == BfToken_RetType) { bool allowThrough = false; @@ -10850,7 +11266,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation())) { - // We could have case where we have "rettype(@T0)" and @T0 gets a type variation of @M0, but we can't do a + // We could have case where we have "rettype(@T0)" and @T0 gets a type variation of @M0, but we can't do a // GetGenericParamInstance on that allowThrough = true; } @@ -10908,12 +11324,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else if (((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsValueType())) || ((genericParam->mGenericParamFlags & (BfGenericParamFlag_Class)) != 0)) { - // Leave as 'T' + // Leave as 'T' } else resolvedType = CreateModifiedTypeType(resolvedType, BfToken_AllocType); } - else if (resolvedType->IsValueType()) + else if (resolvedType->IsValueType()) resolvedType = CreatePointerType(resolvedType); } } @@ -10937,7 +11353,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula resolvedType = ResolveTypeDef(mCompiler->mNullableTypeDef, typeVec, BfPopulateType_Declaration); } else if (resolvedType != NULL) - { + { if (resolvedType->IsValueType()) { if (InDefinitionSection()) @@ -10981,7 +11397,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else Warn(0, "Use 'mut' for generic arguments which may or may not be reference types. Consider using 'ref' here, instead.", refTypeRef->mRefToken); } - } + } if (!needsRefWrap) { @@ -10991,7 +11407,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } - static int sCallIdx = 0; + static int sCallIdx = 0; int callIdx = sCallIdx++; if (callIdx == 0x00006CA4) { @@ -11009,9 +11425,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula lookupCtx.mModule = this; BfResolvedTypeSet::EntryRef resolvedEntry; if (auto delegateTypeRef = BfNodeDynCastExact(typeRef)) - GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention); + GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention); - auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry); + auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry); if (!resolvedEntry) { @@ -11030,7 +11446,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if ((lookupCtx.mIsUnboundGeneric) && (lookupCtx.mRootTypeDef != NULL)) { mContext->mResolvedTypes.RemoveEntry(resolvedEntry); - return ResolveTypeResult(typeRef, ResolveTypeDef(lookupCtx.mRootTypeDef), populateType, resolveFlags); + return ResolveTypeResult(typeRef, ResolveTypeDef(lookupCtx.mRootTypeDef), populateType, resolveFlags); } if ((resolveFlags & BfResolveTypeRefFlag_NoCreate) != 0) @@ -11063,7 +11479,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if ((outerTypeInstance != NULL) && (typeDef->mGenericParamDefs.size() != 0)) { // Try to inherit generic params from current parent - + BfTypeDef* outerType = mSystem->GetCombinedPartial(typeDef->mOuterType); BF_ASSERT(!outerType->mIsPartial); if (TypeHasParentOrEquals(outerTypeInstance->mTypeDef, outerType)) @@ -11155,7 +11571,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula #endif populateModule->InitType(typeInst, populateType); - + if (BfResolvedTypeSet::Hash(typeInst, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); @@ -11164,9 +11580,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } { BF_ASSERT(BfResolvedTypeSet::Hash(typeInst, &lookupCtx) == resolvedEntry->mHashCode); - } + } return ResolveTypeResult(typeRef, typeInst, populateType, resolveFlags); - } + } else if (auto arrayTypeRef = BfNodeDynCast(typeRef)) { if (arrayTypeRef->mDimensions > 4) @@ -11183,25 +11599,19 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - + if ((arrayTypeRef->mDimensions == 1) && (arrayTypeRef->mParams.size() == 1)) { intptr elementCount = -1; BfExpression* sizeExpr = BfNodeDynCast(arrayTypeRef->mParams[0]); BF_ASSERT(sizeExpr != NULL); if (sizeExpr != NULL) - { - BfConstResolver constResolver(this); + { BfType* intType = GetPrimitiveType(BfTypeCode_IntPtr); - constResolver.mExpectingType = intType; - constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue); BfTypedValue typedVal; - { - SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); - typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize); - } + lookupCtx.mResolvedValueMap.TryGetValue(sizeExpr, &typedVal); if (typedVal.mKind == BfTypedValueKind_GenericConstValue) - { + { BfUnknownSizedArrayType* arrayType = new BfUnknownSizedArrayType(); arrayType->mContext = mContext; arrayType->mElementType = elementType; @@ -11264,7 +11674,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } else if (auto genericTypeInstRef = BfNodeDynCast(typeRef)) { - BfTypeReference* outerTypeRef = NULL; + BfTypeReference* outerTypeRef = NULL; Array genericArguments; @@ -11281,7 +11691,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } if (auto genericTypeRef = BfNodeDynCast(checkTypeRef)) - { + { for (auto genericArg : genericTypeRef->mGenericArguments) genericArguments.push_back(genericArg); checkTypeRef = genericTypeRef->mElementType; @@ -11301,7 +11711,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } break; } - + BfTypeVector genericArgs; BfType* type = NULL; @@ -11312,13 +11722,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - + BfTypeInstance* outerTypeInstance = NULL; BfTypeDef* commonOuterType = NULL; int startDefGenericParamIdx = 0; if (outerTypeRef != NULL) - { + { BfType* outerType = lookupCtx.GetCachedResolvedType(outerTypeRef); if (outerType != NULL) { @@ -11327,9 +11737,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } else - { + { outerTypeInstance = mCurTypeInstance; - auto outerType = typeDef->mOuterType; + auto outerType = typeDef->mOuterType; commonOuterType = BfResolvedTypeSet::FindRootCommonOuterType(outerType, &lookupCtx, outerTypeInstance); } @@ -11341,24 +11751,24 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); for (int i = 0; i < startDefGenericParamIdx; i++) genericArgs.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); - } + } for (auto genericArgRef : genericArguments) { - BfType* genericArg = NULL; + BfType* genericArg = NULL; lookupCtx.mResolvedTypeMap.TryGetValue(genericArgRef, &genericArg); if (genericArg == NULL) genericArg = ResolveTypeRef(genericArgRef, NULL, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_AllowGenericTypeParamConstValue | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue)); if ((genericArg == NULL) || (genericArg->IsVar())) - { + { mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, ((genericArg != NULL) && (genericArg->IsVar())) ? genericArg : NULL, populateType, resolveFlags); } genericArgs.Add(genericArg); - } + } BfTypeInstance* genericTypeInst; - if ((type != NULL) && + if ((type != NULL) && ((type->IsDelegateFromTypeRef()) || (type->IsFunctionFromTypeRef()))) { mContext->mResolvedTypes.RemoveEntry(resolvedEntry); @@ -11395,7 +11805,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - + genericTypeInst->mTypeDef = typeDef; if (commonOuterType != NULL) @@ -11425,7 +11835,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula int innerWantedGenericParams = genericParamCount; if (typeDef->mOuterType != NULL) innerWantedGenericParams -= (int)typeDef->mOuterType->mGenericParamDefs.size(); - ShowGenericArgCountError(genericTypeInstRef, innerWantedGenericParams); + ShowGenericArgCountError(genericTypeInstRef, innerWantedGenericParams); delete genericTypeInst; mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); @@ -11435,8 +11845,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula for (auto genericArgRef : genericArguments) { auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx]; - - genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1); + + genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->GetGenericDepth() + 1); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg); genericParamIdx++; @@ -11450,8 +11860,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - resolvedEntry->mValue = genericTypeInst; - + resolvedEntry->mValue = genericTypeInst; + CheckUnspecializedGenericType(genericTypeInst, populateType); populateModule->InitType(genericTypeInst, populateType); @@ -11471,7 +11881,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHashCode); #endif - BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHashCode); + BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHashCode); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); } else if (auto tupleTypeRef = BfNodeDynCast(typeRef)) @@ -11534,7 +11944,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]); fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public; } - actualTupleType->Finish(); + actualTupleType->Finish(); auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance; for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++) { @@ -11548,7 +11958,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula actualTupleType->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); } - CheckUnspecializedGenericType(actualTupleType, populateType); + CheckUnspecializedGenericType(actualTupleType, populateType); if (isUnspecialized) { actualTupleType->mGenericTypeInfo->mIsUnspecialized = true; @@ -11571,7 +11981,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula tupleType = actualTupleType; actualTupleType->mIsUnspecializedType = isUnspecialized; actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized; - } + } tupleType->mFieldInstances.Resize(types.size()); for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++) @@ -11583,7 +11993,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula fieldInstance->mOwner = tupleType; tupleType->mGenericDepth = BF_MAX(tupleType->mGenericDepth, fieldInstance->mResolvedType->GetGenericDepth() + 1); } - + resolvedEntry->mValue = tupleType; BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHashCode); populateModule->InitType(tupleType, populateType); @@ -11629,7 +12039,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else if (auto pointerTypeRef = BfNodeDynCast(typeRef)) { BfPointerType* pointerType = new BfPointerType(); - auto elementType = ResolveTypeRef(pointerTypeRef->mElementType, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); + auto elementType = ResolveTypeRef(pointerTypeRef->mElementType, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); if ((elementType == NULL) || (elementType->IsVar())) { delete pointerType; @@ -11670,7 +12080,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula refType->mElementType = elementType; resolvedEntry->mValue = refType; - + #ifdef _DEBUG if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHashCode) { @@ -11691,8 +12101,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula { if (type->IsTypeGenericParam()) wantGeneric = true; - if (type->IsUnspecializedType()) - isUnspecialized = true; + if (type->IsUnspecializedType()) + isUnspecialized = true; }; bool failed = false; @@ -11706,7 +12116,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula _CheckType(returnType); BfType* functionThisType = NULL; - bool hasMutSpecifier = false; + bool hasMutSpecifier = false; bool isFirst = true; bool isDelegate = delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate; bool hasVarArgs = false; @@ -11714,7 +12124,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula Array paramTypes; for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++) { - auto param = delegateTypeRef->mParams[paramIdx]; + auto param = delegateTypeRef->mParams[paramIdx]; BfResolveTypeRefFlags resolveTypeFlags = BfResolveTypeRefFlag_AllowRef; if ((param->mNameNode != NULL) && (param->mNameNode->Equals("this"))) resolveTypeFlags = (BfResolveTypeRefFlags)(resolveTypeFlags | BfResolveTypeRefFlag_NoWarnOnMut); @@ -11753,7 +12163,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } hasMutSpecifier = true; - functionThisType = refType->mElementType; + functionThisType = refType->mElementType; } paramTypes.Add(functionThisType); _CheckType(functionThisType); @@ -11787,21 +12197,21 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula genericTypeInst->mGenericTypeInfo = new BfGenericTypeInfo(); genericTypeInst->mGenericTypeInfo->mFinishedGenericParams = true; delegateType = genericTypeInst; - delegateInfo = delegateType->GetDelegateInfo(); + delegateInfo = delegateType->GetDelegateInfo(); auto parentTypeInstance = (BfTypeInstance*)mCurTypeInstance; for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mGenericParams.size(); i++) { - genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef()); + genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef()); } for (int i = 0; i < parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments.size(); i++) - { + { genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i]; genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); } CheckUnspecializedGenericType(genericTypeInst, populateType); - + // We don't ever need to do an actual pass over generic delegate methods, so it's safe to set the 'unspecialized variation' flag if (isUnspecialized) { @@ -11822,7 +12232,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } delegateInfo->mCallingConvention = lookupCtx.mCallingConvention; - + Val128 hashContext; BfTypeDef* typeDef = new BfTypeDef(); @@ -11840,14 +12250,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula typeDef->mIsFunction = true; typeDef->mTypeCode = BfTypeCode_Struct; } - + BfMethodDef* methodDef = new BfMethodDef(); methodDef->mDeclaringType = typeDef; methodDef->mName = "Invoke"; methodDef->mProtection = BfProtection_Public; methodDef->mIdx = 0; - methodDef->mIsStatic = !typeDef->mIsDelegate && (functionThisType == NULL); - methodDef->mHasExplicitThis = functionThisType != NULL; + methodDef->mIsStatic = !typeDef->mIsDelegate && (functionThisType == NULL); + methodDef->mHasExplicitThis = functionThisType != NULL; if ((functionThisType != NULL) && (hasMutSpecifier)) { @@ -11856,7 +12266,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } auto directTypeRef = BfAstNode::ZeroedAlloc(); - delegateInfo->mDirectAllocNodes.push_back(directTypeRef); + delegateInfo->mDirectAllocNodes.push_back(directTypeRef); if (typeDef->mIsDelegate) directTypeRef->Init(delegateType); else if (mCompiler->mFunctionTypeDef == NULL) @@ -11864,7 +12274,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef)); if (!failed) - typeDef->mBaseTypes.push_back(directTypeRef); + typeDef->mBaseTypes.push_back(directTypeRef); directTypeRef = BfAstNode::ZeroedAlloc(); delegateInfo->mDirectAllocNodes.push_back(directTypeRef); @@ -11873,11 +12283,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula delegateInfo->mReturnType = returnType; delegateInfo->mHasExplicitThis = functionThisType != NULL; delegateInfo->mHasVarArgs = hasVarArgs; - + delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, returnType->GetGenericDepth() + 1); auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx); - + //int paramSrcOfs = (functionThisType != NULL) ? 1 : 0; int paramSrcOfs = 0; for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) @@ -11892,7 +12302,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula paramName = param->mNameNode->ToString(); if (!paramType->IsReified()) - delegateType->mIsReified = false; + delegateType->mIsReified = false; auto directTypeRef = BfAstNode::ZeroedAlloc(); delegateInfo->mDirectAllocNodes.push_back(directTypeRef); @@ -11915,7 +12325,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula Fail("Params parameter must be the last parameter", param); } } - + if (auto dotTypeRef = BfNodeDynCast(paramDef->mTypeRef)) { if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot) @@ -11929,8 +12339,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula } } } - - delegateInfo->mParams.Add(paramType); + + delegateInfo->mParams.Add(paramType); delegateType->mGenericDepth = BF_MAX(delegateType->mGenericDepth, paramType->GetGenericDepth() + 1); } @@ -11938,7 +12348,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (delegateInfo->mHasVarArgs) { BfParameterDef* paramDef = new BfParameterDef(); - paramDef->mParamKind = BfParamKind_VarArgs; + paramDef->mParamKind = BfParamKind_VarArgs; methodDef->mParams.push_back(paramDef); } @@ -11951,8 +12361,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } - // - + // + if (typeDef->mIsDelegate) { BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, ""); @@ -11962,7 +12372,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula delegateType->mContext = mContext; delegateType->mTypeDef = typeDef; populateModule->InitType(delegateType, populateType); - resolvedEntry->mValue = delegateType; + resolvedEntry->mValue = delegateType; AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); // if (delegateInfo->mFunctionThisType != NULL) @@ -11974,7 +12384,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); - int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(delegateType, &lookupCtx); BF_ASSERT(refHash == typeHash); } BF_ASSERT(BfResolvedTypeSet::Equals(delegateType, typeRef, &lookupCtx)); @@ -12017,10 +12427,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula return ResolveTypeRef(constTypeRef->mElementType, populateType, (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoResolveGenericParam)); } else if (auto constExprTypeRef = BfNodeDynCastExact(typeRef)) - { + { if ((mCurTypeInstance != NULL) && (mCurTypeInstance->mDependencyMap.mMinDependDepth > 32)) { - Fail("Generic type dependency depth exceeded", typeRef); + Fail("Generic type dependency depth exceeded", typeRef); mContext->mResolvedTypes.RemoveEntry(resolvedEntry); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); } @@ -12028,11 +12438,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula BfVariant result; BfType* resultType = NULL; if (constExprTypeRef->mConstExpr != NULL) - { + { result = mContext->mResolvedTypes.EvaluateToVariant(&lookupCtx, constExprTypeRef->mConstExpr, resultType); - BF_ASSERT(resultType != NULL); + BF_ASSERT(resultType != NULL); } - + auto constExprType = new BfConstExprValueType(); constExprType->mContext = mContext; @@ -12047,13 +12457,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula if (BfResolvedTypeSet::Hash(constExprType, &lookupCtx) != resolvedEntry->mHashCode) { int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx); - int typeHash = BfResolvedTypeSet::Hash(constExprType, &lookupCtx); + int typeHash = BfResolvedTypeSet::Hash(constExprType, &lookupCtx); BF_ASSERT(refHash == typeHash); } BF_ASSERT(BfResolvedTypeSet::Equals(constExprType, typeRef, &lookupCtx)); #endif - - populateModule->InitType(constExprType, populateType); + + populateModule->InitType(constExprType, populateType); return constExprType; } @@ -12076,7 +12486,7 @@ BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, B auto genericTypeDef = ResolveGenericInstanceDef(genericTypeRef); if (genericTypeDef == NULL) return NULL; - + BfTypeVector typeVector; for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++) typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i)); @@ -12241,7 +12651,7 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArraymResolvedTypes.EvaluateToVariant(&lookupCtx, expr, resultType); if (resultType != NULL) @@ -12251,7 +12661,7 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); - return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail | BfCastFlags_IsCastCheck)); + return CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail | BfCastFlags_IsCastCheck)); } bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting) @@ -12272,7 +12682,7 @@ bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNe return false; auto _GetTypes = [&](BfType* type, Array& types) - { + { BfTypeUtils::SplatIterate([&](BfType* memberType) { types.Add(memberType); }, type); }; @@ -12291,14 +12701,14 @@ bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNe if (fromMemberType != toMemberType) { - if ((outNeedsMemberCasting != NULL) && + if ((outNeedsMemberCasting != NULL) && (fromMemberType->IsIntPtrable()) && (toMemberType->IsIntPtrable())) *outNeedsMemberCasting = true; else return false; } } - + return true; } @@ -12332,7 +12742,7 @@ BfType* BfModule::GetClosestNumericCastType(const BfTypedValue& typedVal, BfType if ((toType != NULL) && (!CanCast(GetFakeTypedValue(returnType), toType))) canCastTo = false; - + if (canCastTo) { if (bestReturnType == NULL) @@ -12370,10 +12780,10 @@ BfType* BfModule::GetClosestNumericCastType(const BfTypedValue& typedVal, BfType } BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targetValue, BfMethodInstance* methodInstance, BfType* toType, BfCastFlags castFlags, BfIRValue irFunc) -{ +{ auto invokeMethodInstance = GetDelegateInvokeMethod(toType->ToTypeInstance()); - bool methodsThisMatch = true; + bool methodsThisMatch = true; if (invokeMethodInstance->mMethodDef->mIsStatic != methodInstance->mMethodDef->mIsStatic) methodsThisMatch = false; else @@ -12433,7 +12843,7 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe } else if (invokeMethodInstance->IsExactMatch(methodInstance, false, false)) { - bool handled = false; + bool handled = false; if (methodInstance->HasThis()) { auto thisType = methodInstance->GetThisType(); @@ -12458,7 +12868,7 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe if (TypeIsSubTypeOf(thisType->ToTypeInstance(), invokeThisType->ToTypeInstance())) { if (invokeThisWasPtr != thisWasPtr) - { + { if (invokeThisWasPtr) Fail(StrFormat("Non-static method '%s' cannot match '%s', consider removing 'mut' from 'mut %s this' in the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode); else @@ -12466,16 +12876,16 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe handled = true; } } - } + } } - + if ((!methodInstance->mMethodDef->mIsStatic) && (!invokeMethodInstance->HasExplicitThis())) { handled = true; auto thisType = methodInstance->GetParamType(-1); Fail(StrFormat("Non-static method '%s' cannot match '%s', consider adding '%s this' to the function parameters", MethodToString(methodInstance).c_str(), TypeToString(toType).c_str(), TypeToString(thisType).c_str()), srcNode); } - + if (!handled) { if (invokeMethodInstance->mMethodDef->mIsStatic) @@ -12521,9 +12931,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Ref X to Ref Y, X* to Y* { bool checkUnderlying = false; - + bool isRef = false; + if (((typedVal.mType->IsRef()) && (toType->IsRef()))) { + isRef = true; auto fromRefType = (BfRefType*)typedVal.mType; auto toRefType = (BfRefType*)toType; if (fromRefType->mRefKind == toRefType->mRefKind) @@ -12539,16 +12951,16 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { auto fromInner = typedVal.mType->GetUnderlyingType(); auto toInner = toType->GetUnderlyingType(); - + if (fromInner == toInner) - { + { return typedVal.mValue; } if ((fromInner->IsTuple()) && (toInner->IsTuple())) { auto fromTuple = (BfTupleType*)fromInner; - auto toTuple = (BfTupleType*)toInner; + auto toTuple = (BfTupleType*)toInner; if (fromTuple->mFieldInstances.size() == toTuple->mFieldInstances.size()) { bool matches = true; @@ -12563,12 +12975,24 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (matches) { // This is either a ref or a ptr so we don't need to set the "IsAddr" flag - typedVal = MakeAddressable(typedVal); - return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)); + typedVal = MakeAddressable(typedVal); + return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)); } } } + if ((isRef) && (fromInner->IsStruct()) && (toInner->IsStruct())) + { + if (TypeIsSubTypeOf(fromInner->ToTypeInstance(), toInner->ToTypeInstance())) + { + if (toInner->IsValuelessType()) + return mBfIRBuilder->GetFakeVal(); + // Is this valid? + typedVal = MakeAddressable(typedVal); + return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)); + } + } + // ref int <-> ref int64/int32 (of same size) if (((fromInner->IsInteger()) && (toInner->IsInteger())) && (fromInner->mSize == toInner->mSize) && @@ -12587,14 +13011,16 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Func -> void* if ((typedVal.mType->IsFunction()) && (toType->IsVoidPtr())) { + typedVal = LoadValue(typedVal); return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType)); } if (explicitCast) - { + { // void* -> Func if ((typedVal.mType->IsVoidPtr()) && (toType->IsFunction())) { + typedVal = LoadValue(typedVal); return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, BfTypeCode_IntPtr); } @@ -12604,7 +13030,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // void* -> intptr if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr())) - { + { if ((!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0)) { if (!ignoreErrors) @@ -12612,14 +13038,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp else if (!silentFail) SetFail(); } - + auto toPrimitive = (BfPrimitiveType*)toType; return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode); } // intptr -> void* if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer())) - { + { if ((!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0)) { if (!ignoreErrors) @@ -12632,7 +13058,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } - // * <-> Var + // * <-> Var if ((typedVal.mType->IsVar()) || (toType->IsVar())) { return mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toType)); @@ -12675,7 +13101,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((constraintTypeInst != NULL) && (constraintTypeInst->IsDelegateOrFunction())) { - // Could be a methodref - can't cast to anything else + // Could be a methodref - can't cast to anything else } else { @@ -12732,7 +13158,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp BfIRValue retVal; - // For these casts, it's just important we get *A* value to work with here, + // For these casts, it's just important we get *A* value to work with here, // as this is just use for unspecialized parsing. We don't use the generated code { auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)typedVal.mType); @@ -12759,7 +13185,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } - // * -> Generic param + // * -> Generic param if (toType->IsGenericParam()) { if (explicitCast) @@ -12774,7 +13200,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)toType); if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Var) return GetDefaultValue(toType); - + if (typedVal.mType->IsNull()) { bool allowCast = (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface)) != 0; @@ -12785,7 +13211,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } if (genericParamInst->mTypeConstraint != NULL) - { + { if (genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mEnumTypeDef)) { // int->Enum @@ -12800,7 +13226,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (castedVal) return castedVal; } - + if (explicitCast) { if (((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) != 0) || @@ -12815,7 +13241,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((typedVal.mType->IsIntegral()) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0)) { - bool allowCast = explicitCast; + bool allowCast = explicitCast; if ((!allowCast) && (typedVal.mType->IsIntegral())) { // Allow implicit cast of zero @@ -12850,11 +13276,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp return BfIRValue::sValueless; if (ignoreWrites) return mBfIRBuilder->GetFakeVal(); - + if (resultFlags != NULL) *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr); typedVal = MakeAddressable(typedVal); - return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toTypeInstance)); + return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(toTypeInstance)); } } @@ -12960,7 +13386,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Boxing? bool mayBeBox = false; - if (((typedVal.mType->IsValueType()) || (typedVal.mType->IsPointer()) || (typedVal.mType->IsValuelessType())) && + if (((typedVal.mType->IsValueType()) || (typedVal.mType->IsPointer()) || (typedVal.mType->IsValuelessType())) && ((toType->IsInterface()) || (toType == mContext->mBfObjectType))) { // Make sure there's no conversion operator before we box @@ -12969,14 +13395,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } //TODO: the IsGenericParam is not valid - why did we have that? The generic param could be a struct for example... - if ((explicitCast) && ((typedVal.mType->IsInterface()) || (typedVal.mType == mContext->mBfObjectType) /*|| (typedVal.mType->IsGenericParam())*/) && + if ((explicitCast) && ((typedVal.mType->IsInterface()) || (typedVal.mType == mContext->mBfObjectType) /*|| (typedVal.mType->IsGenericParam())*/) && ((toType->IsValueType()) || (toType->IsPointer()))) { if (toType->IsValuelessType()) - return BfIRValue::sValueless; + return BfIRValue::sValueless; - if (ignoreWrites) - return mBfIRBuilder->GetFakeVal(); + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); // Unbox! if ((castFlags & BfCastFlags_Unchecked) == 0) @@ -13037,7 +13463,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp); return allocaInst; } - + auto boxedType = CreateBoxedType(toType); mBfIRBuilder->PopulateType(boxedType); AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); @@ -13048,14 +13474,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp valPtr = mBfIRBuilder->CreateBitCast(valPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(toType))); } if ((toType->IsComposite()) && (resultFlags != NULL)) - { + { *resultFlags = BfCastResultFlags_IsAddr; return valPtr; } else return mBfIRBuilder->CreateLoad(valPtr, false); } - + // Null -> Nullable if ((typedVal.mType->IsNull()) && (toType->IsNullable())) { @@ -13064,15 +13490,15 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if ((castFlags & BfCastFlags_PreferAddr) != 0) { - auto boolType = GetPrimitiveType(BfTypeCode_Boolean); - auto toTypeInst = toType->ToTypeInstance(); + auto boolType = GetPrimitiveType(BfTypeCode_Boolean); + auto toTypeInst = toType->ToTypeInstance(); int hasValueIdx = toTypeInst->mFieldInstances[1].mDataIdx; - + auto allocaInst = CreateAlloca(toType); auto hasValueAddr = mBfIRBuilder->CreateInBoundsGEP(allocaInst, 0, hasValueIdx); // has_value - mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr); - - auto typedValue = BfTypedValue(allocaInst, toType, true); + mBfIRBuilder->CreateStore(GetConstValue(0, boolType), hasValueAddr); + + auto typedValue = BfTypedValue(allocaInst, toType, true); if (resultFlags != NULL) *resultFlags = (BfCastResultFlags)(BfCastResultFlags_IsAddr | BfCastResultFlags_IsTemp); return allocaInst; @@ -13096,7 +13522,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp return BfIRValue(); return mBfIRBuilder->GetFakeVal(); } - + BfIRValue srcPtr = typedVal.mValue; if (!typedVal.IsAddr()) { @@ -13108,7 +13534,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue auto srcVal = mBfIRBuilder->CreateLoad(srcAddr); - auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]), + auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mGenericTypeInfo->mTypeGenericArguments[0]), toNullableType->mGenericTypeInfo->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None); if (!toVal) return BfIRValue(); @@ -13139,7 +13565,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size()) { - typedVal = LoadValue(typedVal); + typedVal = LoadValue(typedVal); BfIRValue curTupleValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toTupleType)); for (int valueIdx = 0; valueIdx < (int)fromTupleType->mFieldInstances.size(); valueIdx++) @@ -13193,7 +13619,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (constant != NULL) { BfConstExprValueType* toConstExprValueType = (BfConstExprValueType*)toType; - + auto variantVal = TypedValueToVariant(srcNode, typedVal, true); if ((mBfIRBuilder->IsIntable(variantVal.mTypeCode)) && (mBfIRBuilder->IsIntable(toConstExprValueType->mValue.mTypeCode))) { @@ -13208,7 +13634,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (toConstExprValueType->mValue.mTypeCode == BfTypeCode_StringId) { - int stringIdx = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); + int stringIdx = GetStringPoolIdx(typedVal.mValue, mBfIRBuilder); if ((stringIdx != -1) && (stringIdx == toConstExprValueType->mValue.mInt32)) return typedVal.mValue; } @@ -13293,7 +13719,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp BF_ASSERT(mBfIRBuilder->mIgnoreWrites); auto undefConst = (BfConstantUndef*)constant; - + BfType* bfType = NULL; if (undefConst->mType.mKind == BfIRTypeData::TypeKind_TypeCode) { @@ -13424,7 +13850,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp case BfTypeCode_UInt32: case BfTypeCode_Int64: // It may seem that we want this to require an explicit cast, - // but consider the case of + // but consider the case of // int val = Math.Max(intA, intB) // Math.Max has an int32 and int64 override, so we want the correct one to be chosen and // to be able to have the int64 return value implicitly used in a 64-bit build @@ -13537,7 +13963,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp PopulateType(svTypeInst); PopulateType(svTypeInst->mBaseType); mBfIRBuilder->PopulateType(svTypeInst); - + SizedArray spanFieldVals; spanFieldVals.Add(mBfIRBuilder->CreateConstAggZero(mBfIRBuilder->MapType(svTypeInst->mBaseType->mBaseType))); @@ -13556,8 +13982,8 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp SizedArray svFieldVals; svFieldVals.Add(mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst->mBaseType), spanFieldVals)); return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(svTypeInst), svFieldVals); - } - } + } + } } } @@ -13588,10 +14014,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp methodMatcher.mAllowImplicitRef = true; methodMatcher.mAllowImplicitWrap = true; BfBaseClassWalker baseClassWalker(walkFromType, walkToType, this); - - bool isConstraintCheck = ((castFlags & BfCastFlags_IsConstraintCheck) != 0); - BfType* operatorConstraintReturnType = NULL; + bool isConstraintCheck = ((castFlags & BfCastFlags_IsConstraintCheck) != 0); + BfType* bestSelfType = NULL; while (true) { @@ -13615,14 +14040,24 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Try without arg args.mSize = 0; } - + if (isConstraintCheck) { auto returnType = CheckOperator(checkType, operatorDef, typedVal, BfTypedValue()); if (returnType != NULL) { - operatorConstraintReturnType = returnType; - methodMatcher.mBestMethodDef = operatorDef; + auto result = BfTypedValue(mBfIRBuilder->GetFakeVal(), returnType); + if (result) + { + if (result.mType != toType) + { + auto castedResult = CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator), resultFlags); + if (castedResult) + return castedResult; + } + else + return result.mValue; + } } } else @@ -13635,7 +14070,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } } - + if (methodMatcher.mBestMethodDef != NULL) { if (mayBeBox) @@ -13717,14 +14152,6 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } } - else if (isConstraintCheck) - { - auto result = BfTypedValue(mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType); - if (result.mType != toType) - return CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator), resultFlags); - if (result) - return result.mValue; - } else { BfTypedValue result; @@ -13741,6 +14168,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Handle the typedPrim<->underlying part implicitly if (fromType->IsTypedPrimitive()) { + typedVal = LoadValue(typedVal); auto convTypedValue = BfTypedValue(typedVal.mValue, fromType->GetUnderlyingType()); return CastToValue(srcNode, convTypedValue, toType, (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL); } @@ -13763,7 +14191,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Check typedPrimitive->underlying cast if ((explicitCast) && (typedVal.mType->IsTypedPrimitive())) - { + { auto underlyingType = typedVal.mType->GetUnderlyingType(); if ((returnType == underlyingType) && (explicitCast)) { @@ -13864,7 +14292,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // We've already verified that we can cast from the return type to toType in MethodMatcher.CheckMethod return mBfIRBuilder->GetFakeVal(); } - + result = exprEvaluator.CreateCall(&methodMatcher, BfTypedValue()); if (result.mType != toType) return CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator), resultFlags); @@ -13886,7 +14314,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } } - + // Default typed primitive 'underlying casts' happen after checking cast operators if (explicitCast) { @@ -13943,7 +14371,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } if (allowCast) - { + { return CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), castFlags); } } @@ -13953,7 +14381,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp BfBoxedType* boxedType = (BfBoxedType*)typedVal.mType; if (boxedType->mElementType->IsGenericParam()) { - // If we have a boxed generic param, the actual available interfaces constraints won't be + // If we have a boxed generic param, the actual available interfaces constraints won't be // handled, so we need to pass through again as the root generic param BfTypedValue unboxedValue = typedVal; unboxedValue.mType = boxedType->mElementType; @@ -13991,7 +14419,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp "Unable to cast '%s' to '%s'" : "Unable to implicitly cast '%s' to '%s'"; + if ((castFlags & BfCastFlags_FromComptimeReturn) != 0) + errStrF = "Comptime return unable to cast '%s' to '%s'"; + String errStr = StrFormat(errStrF, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()); + auto error = Fail(errStr, srcNode); if ((error != NULL) && (srcNode != NULL)) { @@ -14037,7 +14469,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, BfType* toType, BfCastFlags castFlags) { - bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0; + bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0; if (typedVal.mType == toType) return typedVal; @@ -14064,8 +14496,8 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf { return BfTypedValue(typedVal.mValue, toType, needsMemberCasting ? BfTypedValueKind_SplatHead_NeedsCasting : BfTypedValueKind_SplatHead); } - } - + } + if (typedVal.mType->IsValueType()) { auto addrTypedValue = MakeAddressable(typedVal); @@ -14148,18 +14580,18 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf return BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, BfTypedValueKind_ReadOnlyAddr); } else if (typedVal.IsSplat()) - { + { BfTypedValue retTypedValue = typedVal; retTypedValue.mType = tupleType; return retTypedValue; } - + BfIRValue curTupleValue = CreateAlloca(tupleType); auto loadedVal = LoadValue(typedVal); mBfIRBuilder->CreateStore(loadedVal.mValue, mBfIRBuilder->CreateBitCast(curTupleValue, mBfIRBuilder->MapTypeInstPtr(fromTupleType))); return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr); - } - + } + BfIRValue curTupleValue = CreateAlloca(tupleType); for (int fieldIdx = 0; fieldIdx < (int)fromTupleType->mFieldInstances.size(); fieldIdx++) { @@ -14183,7 +14615,7 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf isCompatible = false; } } - + return BfTypedValue(curTupleValue, tupleType, BfTypedValueKind_TempAddr); } } @@ -14203,18 +14635,18 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf { auto fromTypeInst = typedVal.mType->ToTypeInstance(); auto toTypeInst = toType->ToTypeInstance(); - + auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true); auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true); - + auto toDelegateInfo = toTypeInst->GetDelegateInfo(); if ((fromMethodInst != NULL) && (toMethodInst != NULL) && (fromMethodInst->mCallingConvention == toMethodInst->mCallingConvention) && (fromMethodInst->mMethodDef->mIsMutating == toMethodInst->mMethodDef->mIsMutating) && - (fromMethodInst->mReturnType == toMethodInst->mReturnType) && + (fromMethodInst->mReturnType == toMethodInst->mReturnType) && (fromMethodInst->GetParamCount() == toMethodInst->GetParamCount())) - { + { bool matched = true; StringT<64> fromParamName; @@ -14256,10 +14688,10 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf if (matched) { - BfTypedValue loadedVal = LoadValue(typedVal); + BfTypedValue loadedVal = LoadValue(typedVal); return BfTypedValue(mBfIRBuilder->CreateBitCast(loadedVal.mValue, mBfIRBuilder->MapType(toType)), toType); } - } + } } // Struct truncate @@ -14353,14 +14785,14 @@ BfTypedValue BfModule::GetIntCoercible(const BfTypedValue& typedValue) return BfTypedValue(); if (typedValue.mValue.IsConst()) - { + { auto constant = mBfIRBuilder->GetConstant(typedValue.mValue); if (constant->mConstType == BfConstType_Agg) { uint64 intVal = 0; auto constantArray = (BfConstantAgg*)constant; - int memberIdx = 0; + int memberIdx = 0; for (int memberIdx = 0; memberIdx < (int)constantArray->mValues.size(); memberIdx++) { auto memberConstant = mBfIRBuilder->GetConstant(constantArray->mValues[memberIdx]); @@ -14407,7 +14839,7 @@ bool BfModule::TypeHasParentOrEquals(BfTypeDef* checkChildTypeDef, BfTypeDef* ch if (partial == checkType) return true; } - + return false; } @@ -14464,8 +14896,8 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType } // Type is incomplete. We don't do the IsIncomplete check here because of re-entry - // While handling 'var' resolution, we don't want to force a PopulateType reentry - // but we do have enough information for TypeIsSubTypeOf + // While handling 'var' resolution, we don't want to force a PopulateType reentry + // but we do have enough information for TypeIsSubTypeOf PopulateType(srcType, BfPopulateType_Interfaces_Direct); } @@ -14475,15 +14907,15 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType PopulateType(srcType, BfPopulateType_Interfaces_All); BfTypeDef* checkActiveTypeDef = NULL; - bool checkAccessibility = true; + bool checkAccessibility = true; if (IsInSpecializedSection()) { - // When we have a specialized section, the generic params may not be considered "included" + // When we have a specialized section, the generic params may not be considered "included" // in the module that contains the generic type definition. We rely on any casting errors // to be thrown on the unspecialized type pass. We have a similar issue with injecting mixins. - checkAccessibility = false; - } - + checkAccessibility = false; + } + auto checkType = srcType; while (checkType != NULL) { @@ -14498,7 +14930,7 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType // We need to be lenient when validating generic constraints // Otherwise "T where T : IB" declared in a lib won't be able to match a type B in a using project 'C', - // because this check will see the lib using 'C', which it won't consider visible + // because this check will see the lib using 'C', which it won't consider visible if ((checkActiveTypeDef != NULL) && ((mCurMethodInstance != NULL) && (mContext->mCurTypeState != NULL) && (mContext->mCurTypeState->mResolveKind != BfTypeState::ResolveKind_BuildingGenericParams))) { @@ -14562,7 +14994,7 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeDef* wantType) } // 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 PopulateType(srcType, BfPopulateType_Interfaces_Direct); } @@ -14622,7 +15054,7 @@ int BfModule::GetTypeDistance(BfType* fromType, BfType* toType) auto toPrimType = (BfPrimitiveType*)toType; if ((fromPrimType->IsIntegral()) && (toPrimType->IsIntegral())) - { + { int fromBitSize = fromPrimType->mSize * 8; if (fromPrimType->IsSigned()) fromBitSize--; @@ -14710,23 +15142,23 @@ StringT<128> BfModule::TypeToString(BfType* resolvedType, Array* generic BfTypeNameFlags flags = BfTypeNameFlags_None; if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsUnspecializedTypeVariation())) flags = BfTypeNameFlag_ResolveGenericParamNames; - + StringT<128> str; DoTypeToString(str, resolvedType, flags, genericMethodParamNameOverrides); return str; } StringT<128> BfModule::TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array* genericMethodParamNameOverrides) -{ +{ StringT<128> str; - DoTypeToString(str, resolvedType, typeNameFlags, genericMethodParamNameOverrides); + DoTypeToString(str, resolvedType, typeNameFlags, genericMethodParamNameOverrides); return str; } void BfModule::VariantToString(StringImpl& str, const BfVariant& variant) { switch (variant.mTypeCode) - { + { case BfTypeCode_Boolean: if (variant.mUInt64 == 0) str += "false"; @@ -14745,7 +15177,7 @@ void BfModule::VariantToString(StringImpl& str, const BfVariant& variant) case BfTypeCode_Char8: case BfTypeCode_Char16: case BfTypeCode_Char32: - if ((variant.mUInt32 >= 32) && (variant.mUInt32 <= 0x7E)) + if ((variant.mUInt32 >= 32) && (variant.mUInt32 <= 0x7E)) str += StrFormat("'%c'", (char)variant.mUInt32); else if (variant.mUInt32 <= 0xFF) str += StrFormat("'\\x%2X'", variant.mUInt32); @@ -14845,7 +15277,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF DoTypeToString(str, arrayType->mGenericTypeInfo->mTypeGenericArguments[0], typeNameFlags, genericMethodNameOverrides); str += "["; for (int i = 1; i < arrayType->mDimensions; i++) - str += ","; + str += ","; str += "]"; return; } @@ -14881,7 +15313,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } str += ")"; return; - } + } else if (resolvedType->IsDelegateFromTypeRef() || resolvedType->IsFunctionFromTypeRef()) { SetAndRestoreValue prevTypeInstance(mCurTypeInstance); @@ -14897,7 +15329,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } auto methodDef = delegateType->mTypeDef->mMethods[0]; - + switch (methodDef->mCallingConvention) { case BfCallingConvention_Stdcall: @@ -14936,14 +15368,14 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides); str += "("; - bool isFirstParam = true;// + bool isFirstParam = true;// for (int paramIdx = 0; paramIdx < methodDef->mParams.size(); paramIdx++) { if (!isFirstParam) str += ", "; auto paramDef = methodDef->mParams[paramIdx]; BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType | BfTypeNameFlag_ExtendedInfo)); - + if (paramDef->mParamKind == BfParamKind_VarArgs) { str += "..."; @@ -14992,7 +15424,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF else if (resolvedType->IsTypeInstance()) { BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType; - + if ((typeNameFlags & BfTypeNameFlag_ExtendedInfo) != 0) { if (typeInstance->mTypeDef->mIsDelegate) @@ -15020,7 +15452,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace)) - { + { if (!typeInstance->mTypeDef->mNamespace.IsEmpty()) { typeInstance->mTypeDef->mNamespace.ToString(str); @@ -15028,16 +15460,16 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF str += '.'; } } - - SizedArray typeDefStack; - + + SizedArray typeDefStack; + BfTypeDef* endTypeDef = NULL; if (((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) && (mCurTypeInstance != NULL)) { - auto checkTypeInst = typeInstance; - + auto checkTypeInst = typeInstance; + auto outerTypeInst = GetOuterType(checkTypeInst); - if (outerTypeInst != NULL) + if (outerTypeInst != NULL) { checkTypeInst = outerTypeInst; auto checkTypeDef = checkTypeInst->mTypeDef; @@ -15221,7 +15653,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecializedVariation)) doResolveGenericParams = false; } - + if (!doResolveGenericParams) { if (genericParam->mGenericParamKind == BfGenericParamKind_Method) @@ -15234,7 +15666,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF str += (*genericMethodNameOverrides)[genericParam->mGenericParamIdx]; return; } - } + } str += StrFormat("@M%d", genericParam->mGenericParamIdx); return; } @@ -15263,7 +15695,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } } - //TEMPORARY if (genericParam->mGenericParamKind == BfGenericParamKind_Type) { auto curTypeInstance = mCurTypeInstance; @@ -15277,6 +15708,12 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } auto genericParamInstance = GetGenericParamInstance(genericParam); + if (genericParamInstance == NULL) + { + str += StrFormat("@M%d", genericParam->mGenericParamIdx); + return; + } + auto genericParamDef = genericParamInstance->GetGenericParamDef(); if (genericParamDef != NULL) str += genericParamInstance->GetGenericParamDef()->mName; @@ -15314,7 +15751,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } else if (resolvedType->IsModifiedTypeType()) { - auto retTypeType = (BfModifiedTypeType*)resolvedType; + auto retTypeType = (BfModifiedTypeType*)resolvedType; str += BfTokenToString(retTypeType->mModifiedKind); str += "("; DoTypeToString(str, retTypeType->mElementType, typeNameFlags, genericMethodNameOverrides); @@ -15351,11 +15788,11 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF checkType = arrayType->mElementType; continue; } - + DoTypeToString(str, checkType, typeNameFlags, genericMethodNameOverrides); break; } - + for (int i = 0; i < (int)sizes.mSize; i++) { if (sizes[i] == -1) @@ -15377,11 +15814,10 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } VariantToString(str, constExprValueType->mValue); - + return; } BFMODULE_FATAL(this, "Not implemented"); str += "???"; return; -} - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.cpp b/IDEHelper/Compiler/BfNamespaceVisitor.cpp index 78caf433..d37760e0 100644 --- a/IDEHelper/Compiler/BfNamespaceVisitor.cpp +++ b/IDEHelper/Compiler/BfNamespaceVisitor.cpp @@ -6,14 +6,13 @@ USING_NS_BF; ////////////////////////////////////////////////////////////////////////// - void BfNamespaceVisitor::Visit(BfUsingDirective* usingDirective) { if (usingDirective->mNamespace == NULL) - { + { return; } - + String usingString = usingDirective->mNamespace->ToString(); BfAtomCompositeT<16> usingComposite; mSystem->ParseAtomComposite(usingString, usingComposite); @@ -24,11 +23,11 @@ void BfNamespaceVisitor::Visit(BfUsingDirective* usingDirective) } void BfNamespaceVisitor::Visit(BfUsingModDirective* usingDirective) -{ +{ BfAstNode* useNode = usingDirective->mTypeRef; BfAstNode* checkNode = usingDirective->mTypeRef; while (true) - { + { if (auto qualifiedTypeRef = BfNodeDynCast(checkNode)) checkNode = qualifiedTypeRef->mLeft; else if (auto elementedTypeRef = BfNodeDynCast(checkNode)) @@ -42,9 +41,9 @@ void BfNamespaceVisitor::Visit(BfUsingModDirective* usingDirective) if (useNode == NULL) return; - + String usingString = useNode->ToString(); - + BfAtomCompositeT<16> usingComposite; if (mSystem->ParseAtomComposite(usingString, usingComposite)) mResolvePassData->HandleNamespaceReference(useNode, usingComposite); @@ -53,7 +52,7 @@ void BfNamespaceVisitor::Visit(BfUsingModDirective* usingDirective) void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) { BfAtomCompositeT<16> prevNamespace = mNamespace; - + if (namespaceDeclaration->mNameNode == NULL) return; @@ -64,7 +63,7 @@ void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) if (dotIdx == -1) { BfAtom* namespaceAtom = mSystem->FindAtom(namespaceLeft); - mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1); + mNamespace.Set(mNamespace.mParts, mNamespace.mSize, &namespaceAtom, 1); break; } @@ -76,7 +75,7 @@ void BfNamespaceVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration) if (mResolvePassData->mAutoComplete != NULL) mResolvePassData->mAutoComplete->CheckNamespace(namespaceDeclaration->mNameNode, mNamespace); mResolvePassData->HandleNamespaceReference(namespaceDeclaration->mNameNode, mNamespace); - VisitChild(namespaceDeclaration->mBody); + VisitChild(namespaceDeclaration->mBody); mNamespace = prevNamespace; } @@ -88,4 +87,4 @@ void BfNamespaceVisitor::Visit(BfBlock* block) void BfNamespaceVisitor::Visit(BfRootNode* rootNode) { VisitMembers(rootNode); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfNamespaceVisitor.h b/IDEHelper/Compiler/BfNamespaceVisitor.h index 89edd11a..e072951a 100644 --- a/IDEHelper/Compiler/BfNamespaceVisitor.h +++ b/IDEHelper/Compiler/BfNamespaceVisitor.h @@ -9,7 +9,7 @@ class BfResolvePassData; class BfNamespaceVisitor : public BfStructuralVisitor { -public: +public: BfSystem* mSystem; BfResolvePassData* mResolvePassData; BfAtomComposite mNamespace; @@ -20,7 +20,7 @@ public: mSystem = NULL; mResolvePassData = NULL; } - + virtual void Visit(BfUsingDirective* usingDirective) override; virtual void Visit(BfUsingModDirective* usingDirective) override; virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override; diff --git a/IDEHelper/Compiler/BfParser.cpp b/IDEHelper/Compiler/BfParser.cpp index 00c6bd8d..77d28807 100644 --- a/IDEHelper/Compiler/BfParser.cpp +++ b/IDEHelper/Compiler/BfParser.cpp @@ -1,6 +1,5 @@ #pragma warning(disable:4996) - #include "BfParser.h" #include "BfReducer.h" #include "BfPrinter.h" @@ -158,7 +157,7 @@ void BfParserCache::ReportMemory(MemReporter* memReporter) int allocPages = 0; int usedPages = 0; mAstAllocManager.GetStats(allocPages, usedPages); - + OutputDebugStrF("Parsers: %d Chars: %d UsedAlloc: %dk BytesPerChar: %d SysAllocPages: %d SysUsedPages: %d (%dk) LargeAllocs: %dk\n", (int)mEntries.size(), srcLen, allocBytesUsed / 1024, allocBytesUsed / BF_MAX(1, srcLen), allocPages, usedPages, (usedPages * BfAstAllocManager::PAGE_SIZE) / 1024, largeAllocs / 1024); @@ -182,7 +181,6 @@ static int DecodeInt(uint8* buf, int& idx) curByte = buf[idx++]; value |= ((curByte & 0x7f) << shift); shift += 7; - } while (curByte >= 128); // Sign extend negative numbers. if (((curByte & 0x40) != 0) && (shift < 64)) @@ -192,14 +190,14 @@ static int DecodeInt(uint8* buf, int& idx) static int gCurDataId = 0; BfParserData::BfParserData() -{ +{ mDataId = (int)BfpSystem_InterlockedExchangeAdd32((uint32*)&gCurDataId, 1) + 1; mHash = 0; mRefCount = -1; mJumpTable = NULL; mJumpTableSize = 0; - mFailed = false; + mFailed = false; mCharIdData = NULL; mUniqueParser = NULL; mDidReduce = false; @@ -239,7 +237,7 @@ int BfParserData::GetCharIdAtIndex(int findIndex) } void BfParserData::GetLineCharAtIdx(int idx, int& line, int& lineChar) -{ +{ if (mJumpTableSize <= 0) { line = 0; @@ -348,7 +346,7 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem { BfLogSys(bfSystem, "BfParser::BfParser %08X\n", this); - gParserCount++; + gParserCount++; mTextVersion = -1; mEmbedKind = BfSourceEmbedKind_None; @@ -374,15 +372,15 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem mLineStart = 0; //mCurToken = (BfSyntaxToken)0; mToken = BfToken_None; - mSyntaxToken = BfSyntaxToken_None; + mSyntaxToken = BfSyntaxToken_None; mTokenStart = 0; mTokenEnd = 0; - mLineNum = 0; + mLineNum = 0; mCompatMode = false; mQuickCompatMode = false; mLiteral.mWarnType = 0; - mDataId = -1; + mDataId = -1; mTriviaStart = 0; mParsingFailed = false; @@ -397,14 +395,16 @@ BfParser::BfParser(BfSystem* bfSystem, BfProject* bfProject) : BfSource(bfSystem } } - //static std::set gFoundNodes; BfParser::~BfParser() { int parserCount = gParserCount--; - if (mParserData->mRefCount == -1) + if (mParserData == NULL) + { + } + else if (mParserData->mRefCount == -1) { // Owned data, never intended for cache mParserData->mSrc = NULL; // Count on BfSource dtor to release strc @@ -415,12 +415,12 @@ BfParser::~BfParser() // Just never got added to the cache delete mParserData; } - else + else { - mParserData->Deref(); + mParserData->Deref(); } - mSourceData = NULL; + mSourceData = NULL; BfLogSys(mSystem, "BfParser::~BfParser %p\n", this); } @@ -466,9 +466,9 @@ void BfParser::TokenFail(const StringImpl& error, int offset) void BfParser::Init(uint64 cacheHash) { BF_ASSERT(mParserData == NULL); - + mParserData = new BfParserData(); - mSourceData = mParserData; + mSourceData = mParserData; mParserData->mFileName = mFileName; if (mDataId != -1) mParserData->mDataId = mDataId; @@ -477,7 +477,7 @@ void BfParser::Init(uint64 cacheHash) mParserData->mAstAllocManager = &gBfParserCache->mAstAllocManager; mParserData->mSrc = mSrc; mParserData->mSrcLength = mSrcLength; - + if (cacheHash != 0) { BfLogSysM("Creating cached parserData %p for %p %s\n", mParserData, this, mFileName.c_str()); @@ -499,9 +499,9 @@ void BfParser::Init(uint64 cacheHash) mParserData->mJumpTable = mJumpTable; mParserData->mJumpTableSize = mJumpTableSize; - + mAlloc = &mParserData->mAlloc; - mAlloc->mSourceData = mSourceData; + mAlloc->mSourceData = mSourceData; } void BfParser::NewLine() @@ -525,7 +525,7 @@ void BfParser::SetSource(const char* data, int length) const int EXTRA_BUFFER_SIZE = 80; // Extra chars for a bit of AllocChars room //TODO: Check cache - // Don't cache if we have a Cursorid set, + // Don't cache if we have a Cursorid set, // if mDataId != -1 // if BfParerFlag != 0 @@ -566,7 +566,7 @@ void BfParser::SetSource(const char* data, int length) BfParserCache::DataEntry* dataEntryP; if (gBfParserCache->mEntries.TryGetWith(lookupEntry, &dataEntryP)) - { + { mUsingCache = true; mParserData = dataEntryP->mParserData; @@ -591,7 +591,7 @@ void BfParser::SetSource(const char* data, int length) mSrcLength = length; mOrigSrcLength = length; - mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/; + mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/; char* ownedSrc = new char[mSrcAllocSize + 1]; if (data != NULL) memcpy(ownedSrc, data, length); @@ -749,7 +749,7 @@ BfBlock* BfParser::ParseInlineBlock(int spaceIdx, int endIdx) break; if ((childNode->IsA())) { - mSidechannelRootNode->Add(childNode); + mSidechannelRootNode->Add(childNode); mPendingSideNodes.push_back(childNode); continue; } @@ -794,7 +794,7 @@ void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block) if (paramNode->ToStringView() == "warning") { ++itr; - //auto iterNode = paramNode->mNext; + //auto iterNode = paramNode->mNext; //BfAstNode* iterNode = parentNode->mChildArr.GetAs(++curIdx); BfAstNode* iterNode = itr.Get(); @@ -859,11 +859,11 @@ void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block) } else if (paramNode->ToStringView() == "format") { - ++itr; + ++itr; BfAstNode* iterNode = itr.Get(); if (iterNode) { - if ((iterNode->ToStringView() != "disable") && + if ((iterNode->ToStringView() != "disable") && (iterNode->ToStringView() != "restore")) { mPassInstance->FailAfterAt("Expected \"disable\" or \"restore\" after \"format\"", mSourceData, paramNode->GetSrcEnd() - 1); @@ -877,13 +877,13 @@ void BfParser::HandlePragma(const StringImpl& pragma, BfBlock* block) } void BfParser::HandleDefine(const StringImpl& name, BfAstNode* paramNode) -{ +{ mPreprocessorDefines[name] = BfDefineState_ManualSet; } void BfParser::HandleUndefine(const StringImpl& name) { - mPreprocessorDefines[name] = BfDefineState_ManualUnset; + mPreprocessorDefines[name] = BfDefineState_ManualUnset; } MaybeBool BfParser::HandleIfDef(const StringImpl& name) @@ -921,16 +921,14 @@ MaybeBool BfParser::HandleProcessorCondition(BfBlock* paramNode) void BfParser::HandleInclude(BfAstNode* paramNode) { - } void BfParser::HandleIncludeNext(BfAstNode* paramNode) { - } bool BfParser::HandlePreprocessor() -{ +{ int triviaStart = mTriviaStart; int checkIdx = 0; @@ -954,7 +952,7 @@ bool BfParser::HandlePreprocessor() String pragmaParam; switch (mSrc[mSrcIdx - 1]) - { + { case '<': if (mPreprocessorIgnoreDepth > 0) return false; @@ -963,15 +961,15 @@ bool BfParser::HandlePreprocessor() case '=': if (mPreprocessorIgnoreDepth > 0) return false; - pragma = "==="; - break; + pragma = "==="; + break; case '>': if (mPreprocessorIgnoreDepth > 1) - return false; + return false; pragma = ">>>"; break; } - + bool atEnd = false; int startIdx = mSrcIdx - 1; @@ -999,7 +997,7 @@ bool BfParser::HandlePreprocessor() } if (!hadSlash) - break; + break; } if (c == '\0') @@ -1041,7 +1039,7 @@ bool BfParser::HandlePreprocessor() BfBlock* paramNode = NULL; if (pragma.IsEmpty()) - { + { if (spaceIdx != -1) { pragma = String(mSrc + charIdx, mSrc + spaceIdx); @@ -1230,7 +1228,7 @@ bool BfParser::HandlePreprocessor() mPreprocessorNodeStack.pop_back(); } else if (pragma == "define") - { + { if ((paramNode != NULL) && (!paramNode->mChildArr.IsEmpty())) HandleDefine(paramNode->mChildArr[0]->ToString(), paramNode); wantedParam = true; @@ -1243,7 +1241,7 @@ bool BfParser::HandlePreprocessor() } else if (pragma == "error") { - wantsSingleParam = false; + wantsSingleParam = false; mPassInstance->FailAt(pragmaParam, mSourceData, startIdx, mSrcIdx - startIdx); wantedParam = true; } @@ -1366,7 +1364,6 @@ struct StrHashT<4> { const static int HASH = (StrHashT<3>::HASH) ^ Str[4]; }; - }; // This is little endian only @@ -1394,12 +1391,19 @@ double BfParser::ParseLiteralDouble() char buf[256]; int len = std::min(mTokenEnd - mTokenStart, 255); - memcpy(buf, &mSrc[mTokenStart], len); - char c = buf[len - 1]; + int outLen = 0; + for (int i = 0; i < len; i++) + { + char c = mSrc[mTokenStart + i]; + if (c != '\'') + buf[outLen++] = c; + } + + char c = buf[outLen - 1]; if ((c == 'd') || (c == 'D') || (c == 'f') || (c == 'F')) - buf[len - 1] = '\0'; + buf[outLen - 1] = '\0'; else - buf[len] = '\0'; + buf[outLen] = '\0'; return strtod(buf, NULL); } @@ -1501,7 +1505,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro if (mSrc[mSrcIdx + 1] == '=') { if (mSrc[mSrcIdx + 2] == '=') - { + { if (HandlePreprocessor()) { // Conflict split @@ -1771,7 +1775,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro } break; case '$': - + c = mSrc[mSrcIdx]; if ((c == '\"') || (c == '@') || (c == '$')) { @@ -1784,7 +1788,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro case '\'': { SizedArray interpolateExpressions; - + String lineHeader; String strLiteral; char startChar = c; @@ -2128,9 +2132,9 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mPassInstance->FailAfterAt("Expected '}'", mSourceData, newBlock->GetSrcEnd() - 1); } mInAsmBlock = false; - interpolateExpressions.Add(newBlock); + interpolateExpressions.Add(newBlock); } - + if (interpolateSetting == 1) { for (int i = 0; i < braceCount - 1; i++) @@ -2158,7 +2162,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro braceCount++; mSrcIdx++; } - + bool isClosingBrace = false; if (!interpolateExpressions.IsEmpty()) @@ -2175,14 +2179,14 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro isClosingBrace = true; } else if (block->mCloseBrace->mSrcStart == mSrcIdx - braceCount) - { + { block->mCloseBrace->mSrcEnd = mSrcIdx - braceCount + interpolateSetting; isClosingBrace = true; } } if (interpolateSetting == 1) - { + { for (int i = 0; i < braceCount - 1; i++) strLiteral += '}'; } @@ -2211,7 +2215,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro { mTokenStart = stringStart; stringStart = -1; - } + } mTriviaStart = triviaStart; mTokenEnd = mSrcIdx; @@ -2235,7 +2239,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro { bool isGraphemeCluster = false; - // There's no explicit unicode limit to how many diacriticals a grapheme cluster can contain, + // There's no explicit unicode limit to how many diacriticals a grapheme cluster can contain, // but we apply a limit for sanity for the purpose of this error if (strLiteral.length() < 64) { @@ -2255,7 +2259,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro { mLiteral.mInt64 = (uint8)strLiteral[0]; } - + if (mLiteral.mInt64 >= 0x8000) // Use 0x8000 to remain UTF16-compatible mLiteral.mTypeCode = BfTypeCode_Char32; else if (mLiteral.mInt64 >= 0x80) // Use 0x80 to remain UTF8-compatible @@ -2278,7 +2282,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro interpolateExpr->mTriviaStart = mTriviaStart; interpolateExpr->mSrcStart = mTokenStart; interpolateExpr->mSrcEnd = mSrcIdx; - BfSizedArrayInitIndirect(interpolateExpr->mExpressions, interpolateExpressions, mAlloc); + BfSizedArrayInitIndirect(interpolateExpr->mExpressions, interpolateExpressions, mAlloc); mGeneratedNode = interpolateExpr; mSyntaxToken = BfSyntaxToken_GeneratedNode; mToken = BfToken_None; @@ -2310,10 +2314,10 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro if (!mPendingSideNodes.IsEmpty()) { if (auto prevComment = BfNodeDynCast(mPendingSideNodes.back())) - { + { // This is required for folding '///' style multi-line documentation into a single node if (prevComment->GetTriviaStart() == mTriviaStart) - { + { auto prevCommentKind = GetCommentKind(prevComment->mSrcStart); if ((!BfIsCommentBlock(commentKind)) && (commentKind == prevCommentKind)) @@ -2328,7 +2332,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro if ((!handled) && (!disablePreprocessor)) { auto bfCommentNode = mAlloc->Alloc(); - bfCommentNode->Init(this); + bfCommentNode->Init(this); bfCommentNode->mCommentKind = commentKind; mSidechannelRootNode->Add(bfCommentNode); mPendingSideNodes.push_back(bfCommentNode); @@ -2536,7 +2540,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro return; default: if (((c >= '0') && (c <= '9')) || (c == '-')) - { + { bool prevIsDot = prevToken == BfToken_Dot; if (c == '-') @@ -2552,9 +2556,12 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mToken = BfToken_MinusEquals; mSrcIdx++; } - else if ((mCompatMode) && (mSrc[mSrcIdx] == '>')) + else if (mSrc[mSrcIdx] == '>') { - mToken = BfToken_Dot; + if (mCompatMode) + mToken = BfToken_Dot; + else + mToken = BfToken_Arrow; mSrcIdx++; } else @@ -2563,7 +2570,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mTokenEnd = mSrcIdx; return; } - + bool hadOverflow = false; uint64 val = 0; int numberBase = 10; @@ -2660,14 +2667,14 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro { // Skip float parsing if we have a double-dot `1..` case hasDot = false; - } + } // The 'prevIsDot' helps tuple lookups like "tuple.0.0", interpreting those as two integers rather than a float if (((hasDot) && (!prevIsDot)) || (hasExp)) { // Switch to floating point mode //double dVal = val; - //double dValScale = 0.1; + //double dValScale = 0.1; //if (hasExp) //dVal *= pow(10, expVal); while (true) @@ -2782,7 +2789,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro if (endNumber) { mTokenEnd = mSrcIdx - 1; - mSrcIdx--; + mSrcIdx--; if ((numberBase == 0x10) && ((hexDigits >= 16) || ((hadSeps) && (hexDigits > 8)) || ((hadLeadingHexSep) && (hexDigits == 8)))) @@ -2801,7 +2808,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mLiteral.mTypeCode = BfTypeCode_IntUnknown; if ((numberBase == 0x10) && (hexDigits == 7)) - mLiteral.mWarnType = BfWarning_BF4201_Only7Hex; + mLiteral.mWarnType = BfWarning_BF4201_Only7Hex; if ((numberBase == 0x10) && (hexDigits == 9)) mLiteral.mWarnType = BfWarning_BF4202_TooManyHexForInt; @@ -2816,9 +2823,9 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mLiteral.mTypeCode = BfTypeCode_UInt64; } else if (val > 0xFFFFFFFFLL) - { + { mLiteral.mTypeCode = BfTypeCode_Int64; - } + } } mSyntaxToken = BfSyntaxToken_Literal; @@ -2845,9 +2852,9 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro val *= numberBase; val += c - 'a' + 0xa; } - + else if ((c == 'u') || (c == 'U')) - { + { if ((mSrc[mSrcIdx] == 'l') || (mSrc[mSrcIdx] == 'L')) { if (mSrc[mSrcIdx] == 'l') @@ -2874,7 +2881,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro else if ((c == 'l') || (c == 'L')) { if (c == 'l') - TokenFail("Uppercase 'L' required for int64"); + TokenFail("Uppercase 'L' required for int64"); if ((mSrc[mSrcIdx] == 'u') || (mSrc[mSrcIdx] == 'U')) { mSrcIdx++; @@ -2887,12 +2894,12 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart); mSyntaxToken = BfSyntaxToken_Literal; return; - } + } mTokenEnd = mSrcIdx; mLiteral.mTypeCode = BfTypeCode_Int64; mLiteral.mInt64 = (int64)val; if (val == 0x8000000000000000) - mLiteral.mTypeCode = BfTypeCode_UInt64; + mLiteral.mTypeCode = BfTypeCode_UInt64; else if (val >= 0x8000000000000000) hadOverflow = true; if (numberBase == 0x10) @@ -2924,14 +2931,14 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro else { mTokenEnd = mSrcIdx - 1; - mSrcIdx--; + mSrcIdx--; mLiteral.mUInt64 = val; mLiteral.mTypeCode = BfTypeCode_IntUnknown; mSyntaxToken = BfSyntaxToken_Literal; TokenFail("Unexpected character while parsing number", 0); return; } - + if ((uint64)prevVal > (uint64)val) hadOverflow = true; } @@ -3167,12 +3174,14 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro case TOKEN_HASH('n', 'a', 'm', 'e'): if (SrcPtrHasToken("namespace")) mToken = BfToken_Namespace; + else if (SrcPtrHasToken("nameof")) + mToken = BfToken_NameOf; break; case TOKEN_HASH('n', 'e', 'w', 0): if (SrcPtrHasToken("new")) mToken = BfToken_New; break; - case TOKEN_HASH('n', 'u', 'l', 'l'): + case TOKEN_HASH('n', 'u', 'l', 'l'): if (SrcPtrHasToken("null")) mToken = BfToken_Null; else if (SrcPtrHasToken("nullable")) @@ -3197,7 +3206,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro case TOKEN_HASH('p', 'a', 'r', 'a'): if ((!mCompatMode) && (SrcPtrHasToken("params"))) mToken = BfToken_Params; - break; + break; case TOKEN_HASH('p', 'r', 'i', 'v'): if (SrcPtrHasToken("private")) mToken = BfToken_Private; @@ -3444,7 +3453,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro { if (interpolateSetting == 0) stringStart = mTokenStart; - interpolateSetting++; + interpolateSetting++; } } } @@ -3460,7 +3469,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) bool isAsmBlock = false; bool isTernary = false; - SizedArray childArr; + SizedArray childArr; int parenDepth = 0; @@ -3475,7 +3484,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) } NextToken(-1, isInterpolate && (parenDepth == 0)); - + if (mPreprocessorIgnoredSectionNode != NULL) { if (mSyntaxToken != BfSyntaxToken_EOF) @@ -3492,7 +3501,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) gParseMemberIdx++; int memberIdx = gParseMemberIdx; - + auto childNode = CreateNode(); if (childNode == NULL) break; @@ -3540,12 +3549,12 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) } mInAsmBlock = false; astNode->Add(newBlock); - childArr.push_back(newBlock); - } + childArr.push_back(newBlock); + } else if (mToken == BfToken_RBrace) { if (depth == 0) - Fail("Unexpected ending brace"); + Fail("Unexpected ending brace"); break; } else @@ -3562,7 +3571,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) bool endNow = false; if (mToken == BfToken_Colon) - { + { endNow = true; if (!childArr.IsEmpty()) { @@ -3583,7 +3592,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) if (mToken == BfToken_Comma) endNow = true; - + if (endNow) { mSrcIdx = mTokenStart; @@ -3591,7 +3600,7 @@ void BfParser::ParseBlock(BfBlock* astNode, int depth, bool isInterpolate) } } - astNode->Add(childNode); + astNode->Add(childNode); childArr.Add(childNode); if ((mSyntaxToken == BfSyntaxToken_Token) && (mToken == BfToken_RBrace)) @@ -3651,7 +3660,7 @@ void BfParser::Parse(BfPassInstance* passInstance) mSyntaxToken = BfSyntaxToken_None; mPassInstance = passInstance; - int startIdx = mSrcIdx; + int startIdx = mSrcIdx; if (mUsingCache) { @@ -3692,7 +3701,7 @@ void BfParser::Parse(BfPassInstance* passInstance) if ((mPassInstance->HasMessages()) || (mParsingFailed)) { - mParserData->mFailed = true; // Don't reuse cache if there were errors or warnings + mParserData->mFailed = true; // Don't reuse cache if there were errors or warnings } mPassInstance = NULL; @@ -3723,18 +3732,18 @@ void BfParser::Close() } else { - // It's possible two of the same entries were being parsed at the same time on different threads. + // It's possible two of the same entries were being parsed at the same time on different threads. // Just let the loser be deleted in the dtor BfLogSys(mSystem, "Duplicate parser %p not added to cache\n", this); } - } + } } void BfParser::HadSrcRealloc() { int jumpTableSize = ((mSrcAllocSize + 1) + PARSER_JUMPTABLE_DIVIDE - 1) / PARSER_JUMPTABLE_DIVIDE; if (jumpTableSize > mJumpTableSize) - { + { auto jumpTable = new BfLineStartEntry[jumpTableSize]; memset(jumpTable, 0, jumpTableSize * sizeof(BfLineStartEntry)); memcpy(jumpTable, mJumpTable, mJumpTableSize * sizeof(BfLineStartEntry)); @@ -3747,7 +3756,6 @@ void BfParser::HadSrcRealloc() mParserData->mJumpTable = mJumpTable; mParserData->mJumpTableSize = mJumpTableSize; } - } void BfParser::GenerateAutoCompleteFrom(int srcPosition) @@ -3766,7 +3774,7 @@ void BfParser::ReportMemory(MemReporter* memReporter) // if (!mUsingCache) // memReporter->AddBumpAlloc("AstAlloc", *mAlloc); -// +// // memReporter->Add("JumpTable", mJumpTableSize * sizeof(BfLineStartEntry)); memReporter->Add(sizeof(BfParser)); @@ -3901,7 +3909,7 @@ BF_EXPORT void BF_CALLTYPE BfParser_SetNextRevision(BfParser* bfParser, BfParser BF_EXPORT void BF_CALLTYPE BfParser_SetCursorIdx(BfParser* bfParser, int cursorIdx) { - bfParser->SetCursorIdx(cursorIdx); + bfParser->SetCursorIdx(cursorIdx); } BF_EXPORT void BF_CALLTYPE BfParser_SetIsClassifying(BfParser* bfParser) @@ -3945,7 +3953,7 @@ BF_EXPORT bool BF_CALLTYPE BfParser_Reduce(BfParser* bfParser, BfPassInstance* b BP_ZONE("BfParser_Reduce"); if (bfParser->mUsingCache) return true; // Already reduced - + bfParser->FinishSideNodes(); int startFailIdx = bfPassInstance->mFailedIdx; int startWarningCount = bfPassInstance->mWarningCount; @@ -3997,7 +4005,7 @@ BF_EXPORT const char* BF_CALLTYPE BfParser_DocPrep(BfParser* bfParser) bfPrinter.mCharMapping = &gCharMapping; bfPrinter.mDocPrep = true; bfPrinter.Visit(bfParser->mRootNode); - outString = bfPrinter.mOutString; + outString = bfPrinter.mOutString; return outString.c_str(); } @@ -4078,7 +4086,7 @@ BF_EXPORT BfResolvePassData* BF_CALLTYPE BfParser_CreateResolvePassData(BfParser } BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, bool fullRefresh) -{ +{ if (bfParser->mCursorIdx != -1) resolvePassData->mHasCursorIdx = true; @@ -4092,7 +4100,6 @@ BF_EXPORT bool BF_CALLTYPE BfParser_BuildDefs(BfParser* bfParser, BfPassInstance BF_EXPORT void BF_CALLTYPE BfParser_RemoveDefs(BfParser* bfParser) { - } BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceClassifier::CharData* charData, bool preserveFlags) @@ -4101,18 +4108,18 @@ BF_EXPORT void BF_CALLTYPE BfParser_ClassifySource(BfParser* bfParser, BfSourceC bfParser->Close(); BfSourceClassifier bfSourceClassifier(bfParser, charData); - bfSourceClassifier.mPreserveFlags = preserveFlags; + bfSourceClassifier.mPreserveFlags = preserveFlags; bfSourceClassifier.Visit(bfParser->mRootNode); bfSourceClassifier.mIsSideChannel = false; //? false or true? bfSourceClassifier.Visit(bfParser->mErrorRootNode); bfSourceClassifier.mIsSideChannel = true; - bfSourceClassifier.Visit(bfParser->mSidechannelRootNode); + bfSourceClassifier.Visit(bfParser->mSidechannelRootNode); } BF_EXPORT void BF_CALLTYPE BfParser_CreateClassifier(BfParser* bfParser, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData, BfSourceClassifier::CharData* charData) { resolvePassData->mIsClassifying = true; - bfParser->mSourceClassifier = new BfSourceClassifier(bfParser, charData); + bfParser->mSourceClassifier = new BfSourceClassifier(bfParser, charData); bfParser->mSourceClassifier->mClassifierPassId = bfPassInstance->mClassifierPassId; if ((resolvePassData->mParsers.IsEmpty()) || (bfParser != resolvePassData->mParsers[0])) @@ -4124,7 +4131,7 @@ BF_EXPORT void BF_CALLTYPE BfParser_CreateClassifier(BfParser* bfParser, BfPassI bfParser->mSourceClassifier->mSkipMethodInternals = true; bfParser->mSourceClassifier->mSkipTypeDeclarations = true; if (charData != NULL) - { + { if ((doClassifyPass) && (bfParser->mRootNode != NULL)) bfParser->mSourceClassifier->Visit(bfParser->mRootNode); } @@ -4163,4 +4170,4 @@ BF_EXPORT void BF_CALLTYPE BfParser_GenerateAutoCompletionFrom(BfParser* bfParse BF_EXPORT void BF_CALLTYPE BfParser_SetCompleteParse(BfParser* bfParser) { bfParser->mCompleteParse = true; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfParser.h b/IDEHelper/Compiler/BfParser.h index b146dfc7..d68f825e 100644 --- a/IDEHelper/Compiler/BfParser.h +++ b/IDEHelper/Compiler/BfParser.h @@ -20,15 +20,15 @@ enum BfSyntaxToken { BfSyntaxToken_None, BfSyntaxToken_Token, - BfSyntaxToken_Identifier, + BfSyntaxToken_Identifier, BfSyntaxToken_CharQuote, - BfSyntaxToken_StringQuote, + BfSyntaxToken_StringQuote, BfSyntaxToken_ForwardSlash, - BfSyntaxToken_Literal, + BfSyntaxToken_Literal, BfSyntaxToken_CommentLine, BfSyntaxToken_CommentBlock, - BfSyntaxToken_GeneratedNode, - BfSyntaxToken_FAILED, + BfSyntaxToken_GeneratedNode, + BfSyntaxToken_FAILED, BfSyntaxToken_HIT_END_IDX, BfSyntaxToken_EOF }; @@ -59,12 +59,12 @@ enum MaybeBool { MaybeBool_None = -1, MaybeBool_False = 0, - MaybeBool_True = 1, + MaybeBool_True = 1, }; class BfParserData : public BfSourceData { -public: +public: uint64 mHash; int mDataId; int mRefCount; // -1 = not cached @@ -82,7 +82,7 @@ public: Dictionary mWarningEnabledChanges; std::set mUnwarns; bool mFailed; // Don't cache if there's a warning or an error - bool mDidReduce; + bool mDidReduce; public: BfParserData(); @@ -95,11 +95,11 @@ public: } virtual BfParser* ToParser() override; - int GetCharIdAtIndex(int findIndex); + int GetCharIdAtIndex(int findIndex); void GetLineCharAtIdx(int idx, int& line, int& lineChar); bool IsUnwarnedAt(BfAstNode* node); bool IsWarningEnabledAtSrcIndex(int warningNumber, int srcIdx); - void ReportMemory(MemReporter* memReporter); + void ReportMemory(MemReporter* memReporter); }; class BfParserCache @@ -115,7 +115,7 @@ public: }; struct DataEntry - { + { BfParserData* mParserData; bool operator==(const LookupEntry& lookup) const; @@ -123,7 +123,7 @@ public: { return lookup.mParserData == mParserData; } - }; + }; public: CritSect mCritSect; @@ -131,7 +131,7 @@ public: BfAstAllocManager mAstAllocManager; HashSet mEntries; -public: +public: BfParserCache(); ~BfParserCache(); void ReportMemory(MemReporter* memReporter); @@ -153,30 +153,30 @@ enum BfSourceEmbedKind : int8 class BfParser : public BfSource { -public: +public: BfParserData* mParserData; bool mUsingCache; BfPassInstance* mPassInstance; BfSourceClassifier* mSourceClassifier; - String mFileName; + String mFileName; int mTextVersion; BfSourceEmbedKind mEmbedKind; - bool mAwaitingDelete; - + bool mAwaitingDelete; + bool mCompatMode; // Does C++ compatible parsing - bool mQuickCompatMode; + bool mQuickCompatMode; bool mScanOnly; bool mCompleteParse; bool mIsEmitted; BfLineStartEntry* mJumpTable; int mJumpTableSize; - int mOrigSrcLength; + int mOrigSrcLength; int mDataId; int mSrcIdx; int mLineStart; - int mLineNum; + int mLineNum; bool mInAsmBlock; BfParserFlag mParserFlags; @@ -186,43 +186,43 @@ public: BfSyntaxToken mSyntaxToken; int mTriviaStart; // mTriviaStart < mTokenStart when there's leading whitespace int mTokenStart; - int mTokenEnd; + int mTokenEnd; BfAstNode* mGeneratedNode; - BfVariant mLiteral; + BfVariant mLiteral; BfToken mToken; BfPreprocesorIgnoredSectionNode* mPreprocessorIgnoredSectionNode; int mPreprocessorIgnoreDepth; Array< std::pair > mPreprocessorNodeStack; Dictionary mPreprocessorDefines; - - std::set mPreprocessorIgnoredSectionStarts; + + std::set mPreprocessorIgnoredSectionStarts; public: virtual void HandleInclude(BfAstNode* paramNode); virtual void HandleIncludeNext(BfAstNode* paramNode); virtual void HandlePragma(const StringImpl& pragma, BfBlock* block); virtual void HandleDefine(const StringImpl& name, BfAstNode* paramNode); - virtual void HandleUndefine(const StringImpl& name); + virtual void HandleUndefine(const StringImpl& name); virtual MaybeBool HandleIfDef(const StringImpl& name); virtual MaybeBool HandleProcessorCondition(BfBlock* paramNode); -public: +public: void Init(uint64 cacheHash = 0); - void NewLine(); + void NewLine(); BfExpression* CreateInlineExpressionFromNode(BfBlock* block); bool EvaluatePreprocessor(BfExpression* expr); BfBlock* ParseInlineBlock(int spaceIdx, int endIdx); - bool HandlePreprocessor(); + bool HandlePreprocessor(); bool IsUnwarnedAt(BfAstNode* node); bool SrcPtrHasToken(const char* name); uint32 GetTokenHash(); void ParseBlock(BfBlock* astNode, int depth, bool isInterpolate = false); - double ParseLiteralDouble(); + double ParseLiteralDouble(); void AddErrorNode(int startIdx, int endIdx); - BfCommentKind GetCommentKind(int startIdx); + BfCommentKind GetCommentKind(int startIdx); -public: +public: BfParser(BfSystem* bfSystem, BfProject* bfProject = NULL); ~BfParser(); @@ -232,23 +232,23 @@ public: void GetLineCharAtIdx(int idx, int& line, int& lineChar); void Fail(const StringImpl& error, int offset = -1); - void TokenFail(const StringImpl& error, int offset = -1); - - void SetSource(const char* data, int length); + void TokenFail(const StringImpl& error, int offset = -1); + + void SetSource(const char* data, int length); void MoveSource(const char* data, int length); // Takes ownership of data ptr void RefSource(const char* data, int length); void MakeNegative(uint64& val, bool& hadOverflow); void NextToken(int endIdx = -1, bool outerIsInterpolate = false, bool disablePreprocessor = false); - BfAstNode* CreateNode(); - - void Parse(BfPassInstance* passInstance); + BfAstNode* CreateNode(); + + void Parse(BfPassInstance* passInstance); int GetCharIdAtIndex(int findIndex); virtual void Close() override; virtual void HadSrcRealloc() override; - void GenerateAutoCompleteFrom(int srcPosition); - - void ReportMemory(MemReporter* memReporter); + void GenerateAutoCompleteFrom(int srcPosition); + + void ReportMemory(MemReporter* memReporter); void GetSrcPosition(int idx, int& lineNum, int& column); }; diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index 03368a79..0e8a36c9 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -17,8 +17,8 @@ BfPrinter::BfPrinter(BfRootNode *rootNode, BfRootNode *sidechannelRootNode, BfRo mSidechannelNextNode = mSidechannelItr.Get(); if (errorRootNode != NULL) - mErrorItr = errorRootNode->begin(); - mErrorNextNode = mErrorItr.Get(); + mErrorItr = errorRootNode->begin(); + mErrorNextNode = mErrorItr.Get(); mTriviaIdx = 0; mCurSrcIdx = 0; @@ -26,11 +26,11 @@ BfPrinter::BfPrinter(BfRootNode *rootNode, BfRootNode *sidechannelRootNode, BfRo mCurBlockState = NULL; mQueuedSpaceCount = 0; mLastSpaceOffset = 0; - mReformatting = false; + mReformatting = false; mDocPrep = false; mIgnoreTrivia = false; - mForceUseTrivia = false; - mIsFirstStatementInBlock = false; + mForceUseTrivia = false; + mIsFirstStatementInBlock = false; mFormatStart = -1; mFormatEnd = -1; mInSideChannel = false; @@ -52,7 +52,7 @@ BfPrinter::BfPrinter(BfRootNode *rootNode, BfRootNode *sidechannelRootNode, BfRo } void BfPrinter::Write(const StringView& str) -{ +{ if (str == '\n') mCurCol = 0; else if (mMaxCol > 0) @@ -66,8 +66,8 @@ void BfPrinter::Write(const StringView& str) mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize; else mCurCol++; - } - } + } + } mOutString.Append(str); if (mCharMapping != NULL) @@ -75,8 +75,8 @@ void BfPrinter::Write(const StringView& str) for (int i = 0; i < (int)str.length(); i++) { int prevSrcIdx = -1; - if (mCharMapping->size() > 0) - prevSrcIdx = mCharMapping->back(); + if (mCharMapping->size() > 0) + prevSrcIdx = mCharMapping->back(); if (prevSrcIdx != -1) { bool matched = false; @@ -99,7 +99,7 @@ void BfPrinter::Write(const StringView& str) if (matched) { - // It matches the source character, extend... + // It matches the source character, extend... mCharMapping->push_back(curSrcIdx); } else @@ -113,11 +113,11 @@ void BfPrinter::Write(const StringView& str) mCharMapping->push_back(-1); } } - } + } } void BfPrinter::FlushIndent() -{ +{ while ((mQueuedSpaceCount >= mTabSize) && (!mWantsTabsAsSpaces)) { Write("\t"); @@ -126,19 +126,19 @@ void BfPrinter::FlushIndent() while (mQueuedSpaceCount > 0) { - Write(" "); + Write(" "); mQueuedSpaceCount--; } } void BfPrinter::Write(BfAstNode* node, int start, int len) { - FlushIndent(); + FlushIndent(); if (mMaxCol > 0) { int startCol = mCurCol; - + auto parserData = node->GetParserData(); for (int i = 0; i < len; i++) @@ -148,7 +148,7 @@ void BfPrinter::Write(BfAstNode* node, int start, int len) mCurCol = ((mCurCol / mTabSize) + 1) * mTabSize; else mCurCol++; - } + } } mOutString.Append(node->GetSourceData()->mSrc + start, len); @@ -157,7 +157,7 @@ void BfPrinter::Write(BfAstNode* node, int start, int len) if (start < mParser->mSrcLength) { for (int i = 0; i < len; i++) - { + { mCharMapping->push_back(start + i); } } @@ -171,11 +171,11 @@ void BfPrinter::Write(BfAstNode* node, int start, int len) void BfPrinter::WriteSourceString(BfAstNode* node) { - Write(node, node->GetSrcStart(), node->GetSrcLength()); + Write(node, node->GetSrcStart(), node->GetSrcLength()); } void BfPrinter::QueueVisitChild(BfAstNode* astNode) -{ +{ if (astNode != NULL) { mNextStateModify.mQueuedNode = astNode; @@ -188,7 +188,7 @@ void BfPrinter::QueueVisitErrorNodes(BfRootNode* astNode) { for (auto& childNodeRef : *astNode) { - BfAstNode* childNode = childNodeRef; + BfAstNode* childNode = childNodeRef; if (childNode->IsA()) QueueVisitChild(childNode); } @@ -203,16 +203,16 @@ void BfPrinter::FlushVisitChild() { if (mChildNodeQueue.size() == 0) return; - + auto nodeQueue = mChildNodeQueue; - mChildNodeQueue.Clear(); - - std::stable_sort(nodeQueue.begin(), nodeQueue.end(), CompareNodeStart); + mChildNodeQueue.Clear(); + + std::stable_sort(nodeQueue.begin(), nodeQueue.end(), CompareNodeStart); for (auto& node : nodeQueue) { mNextStateModify = node; - + VisitChild(node.mQueuedNode); if (mVirtualNewLineIdx == mNextStateModify.mWantNewLineIdx) mVirtualNewLineIdx = node.mWantNewLineIdx; @@ -230,29 +230,29 @@ void BfPrinter::VisitChildWithPrecedingSpace(BfAstNode* bfAstNode) void BfPrinter::VisitChildWithProceedingSpace(BfAstNode* bfAstNode) { if (bfAstNode == NULL) - return; + return; VisitChild(bfAstNode); ExpectSpace(); } void BfPrinter::ExpectSpace() { - mNextStateModify.mExpectingSpace = true; + mNextStateModify.mExpectingSpace = true; } void BfPrinter::ExpectNewLine() { - mNextStateModify.mWantNewLineIdx++; + mNextStateModify.mWantNewLineIdx++; } void BfPrinter::ExpectIndent() -{ +{ mNextStateModify.mWantVirtualIndent++; ExpectNewLine(); } void BfPrinter::ExpectUnindent() -{ +{ mNextStateModify.mWantVirtualIndent--; ExpectNewLine(); } @@ -261,13 +261,13 @@ void BfPrinter::VisitChildNextLine(BfAstNode* node) { if (node == NULL) return; - + if (node->IsA()) { VisitChild(node); } else - { + { ExpectNewLine(); ExpectIndent(); VisitChild(node); @@ -290,7 +290,7 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx) else if (c == ' ') origLineSpacing += 1; else - return -1; + return -1; } if (lineStartIdx != NULL) *lineStartIdx = checkIdx + 1; @@ -305,16 +305,16 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) { int startIdx = BF_MAX(node->mTriviaStart, mTriviaIdx); Write(node, startIdx, node->mSrcEnd - startIdx); - mTriviaIdx = node->mSrcEnd; + mTriviaIdx = node->mSrcEnd; return; } bool startsWithSpace = false; - + bool wasExpectingNewLine = mExpectingNewLine; mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart()); - int endIdx = mTriviaIdx; + int endIdx = mTriviaIdx; int crCount = 0; auto astNodeSrc = node->GetSourceData(); int srcEnd = node->GetSrcEnd(); @@ -331,9 +331,9 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) } bool wantsPrefixSpace = (!mOutString.IsEmpty()) && (!isspace((uint8)mOutString[mOutString.mLength - 1])); - + bool expectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx; - + int startIdx = mTriviaIdx; if ((expectingNewLine) && (mReformatting)) { @@ -351,9 +351,9 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) startIdx = node->GetSrcStart(); // Leave left-aligned preprocessor nodes if ((node->GetSourceData()->mSrc[node->GetSrcStart()] != '#') || (origLineSpacing > 0)) - mQueuedSpaceCount = origLineSpacing + mLastSpaceOffset; + mQueuedSpaceCount = origLineSpacing + mLastSpaceOffset; } - } + } auto commentNode = BfNodeDynCast(node); bool isBlockComment = false; @@ -395,7 +395,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) startIdx = node->mSrcStart; if (doWrap) - { + { bool wantWrap = false; int spacedWordCount = 0; @@ -442,8 +442,8 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) int lineEmittedChars = 0; // This handles tab adjustment within multiline comments - FlushIndent(); - bool isNewLine = false; + FlushIndent(); + bool isNewLine = false; for (int srcIdx = startIdx; srcIdx < endIdx; srcIdx++) { #ifdef A @@ -451,7 +451,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) #endif bool emitChar = true; - + char c = astNodeSrc->mSrc[srcIdx]; if ((wantsPrefixSpace) && (isspace((uint8)c))) @@ -471,7 +471,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) int startIdx = srcIdx; for (int checkIdx = srcIdx + 1; checkIdx < endIdx + 1; checkIdx++) { - char checkC = astNodeSrc->mSrc[checkIdx]; + char checkC = astNodeSrc->mSrc[checkIdx]; if (isBlockComment) { @@ -518,7 +518,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) if ((checkC != ' ') && (checkC != '\t')) break; - } + } } if (merging) @@ -539,7 +539,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) mCurCol = 0; prevHadWrap = false; } - else if (isNewLine) + else if (isNewLine) { if (c == ' ') { @@ -552,31 +552,31 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) emitChar = false; } else - { + { // Leave left-aligned preprocessor nodes that are commented out if ((c != '#') || (mQueuedSpaceCount > 0)) mQueuedSpaceCount = std::max(0, mQueuedSpaceCount + mLastSpaceOffset); else mQueuedSpaceCount = mCurIndentLevel * mTabSize; // Do default indent - isNewLine = false; + isNewLine = false; } } if (emitChar) - { + { int startIdx = srcIdx; if (c != '\n') { while (srcIdx < endIdx) - { + { char c = astNodeSrc->mSrc[srcIdx + 1]; if (isspace((uint8)c)) break; srcIdx++; } } - + if (doWrap) { int len = 0; @@ -586,7 +586,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) if (isutf(c)) len++; } - + if ((mCurCol + len > mMaxCol) && (lineEmittedChars >= 8)) { Write("\n"); @@ -595,10 +595,10 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) if (isStarredBlockComment) Write(" * "); - else if (!isBlockComment) + else if (!isBlockComment) Write("// "); - prevHadWrap = true; - + prevHadWrap = true; + while (startIdx < endIdx) { char c = astNodeSrc->mSrc[startIdx]; @@ -611,7 +611,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) } if (wantsPrefixSpace) - { + { mQueuedSpaceCount++; wantsPrefixSpace = false; } @@ -645,7 +645,7 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node) FlushIndent(); - mTriviaIdx = endIdx; + mTriviaIdx = endIdx; mIsFirstStatementInBlock = false; mExpectingNewLine = wasExpectingNewLine; } @@ -658,7 +658,7 @@ void BfPrinter::CheckRawNode(BfAstNode* node) (!BfNodeIsExact(node)) && (!BfNodeIsExact(node))) return; - + //mForceUseTrivia = true; // Usually 'raw' nodes get merged into larger nodes like expressions/statements, but if they don't then this tries to help formatting @@ -669,7 +669,7 @@ void BfPrinter::CheckRawNode(BfAstNode* node) bool inLineStart = false; int spaceCount = 0; - auto parserData = node->GetParserData(); + auto parserData = node->GetParserData(); for (int i = node->mTriviaStart; i < node->mSrcStart; i++) { char c = parserData->mSrc[i]; @@ -753,7 +753,7 @@ void BfPrinter::Update(BfAstNode* bfAstNode) } void BfPrinter::Visit(BfAstNode* bfAstNode) -{ +{ SetAndRestoreValue prevForceTrivia(mForceUseTrivia); bool newExpectingNewLine = mNextStateModify.mWantNewLineIdx != mVirtualNewLineIdx; @@ -763,7 +763,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) int indentOffset = 0; if (bfAstNode->GetTriviaStart() != -1) - { + { if (newExpectingNewLine) { indentOffset = mNextStateModify.mWantVirtualIndent - mVirtualIndentLevel; @@ -774,7 +774,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) while (true) { - int sidechannelDist = -1; + int sidechannelDist = -1; if (mSidechannelNextNode != NULL) sidechannelDist = bfAstNode->GetSrcStart() - mSidechannelNextNode->GetSrcStart(); @@ -795,30 +795,30 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) { auto curErrorNode = mErrorNextNode; ++mErrorItr; - mErrorNextNode = mErrorItr.Get(); + mErrorNextNode = mErrorItr.Get(); mForceUseTrivia = true; - VisitChild(curErrorNode); + VisitChild(curErrorNode); } else break; } - - Update(bfAstNode); - + + Update(bfAstNode); + // When triviaStart == -1, that indicates it's a combined node where the text we want to process is on the inside - if (bfAstNode->GetTriviaStart() != -1) - { + if (bfAstNode->GetTriviaStart() != -1) + { mTriviaIdx = std::max(mTriviaIdx, bfAstNode->GetTriviaStart()); bool usedTrivia = false; - + if ((!mIgnoreTrivia) && (mTriviaIdx < bfAstNode->GetSrcStart())) { if ((!mReformatting) || (mForceUseTrivia)) { Write(bfAstNode, mTriviaIdx, bfAstNode->GetSrcStart() - mTriviaIdx); usedTrivia = true; - } - } + } + } if ((mReformatting) && (!mInSideChannel)) { @@ -838,10 +838,10 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) for (int i = mTriviaIdx; i < triviaEnd; i++) { if (mIgnoreTrivia) - break; + break; char c = astNodeSrc->mSrc[i]; - + if (c == ' ') { if (spaceTriviaStart == -1) @@ -856,9 +856,9 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) } if (((c == '\n') || (i == bfAstNode->GetSrcStart() - 1)) && (hadPrevLineSpacing) && (prevSpaceCount > 0)) - { + { mQueuedSpaceCount += std::max(0, spaceCount - prevSpaceCount) - std::max(0, indentOffset * mTabSize); - + prevSpaceCount = -1; hadPrevLineSpacing = false; } @@ -868,7 +868,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) canUseTrivia = false; hadNewline = true; int backIdx = i - 1; - prevSpaceCount = 0; + prevSpaceCount = 0; while (backIdx >= 0) { char c = astNodeSrc->mSrc[backIdx]; @@ -876,7 +876,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) prevSpaceCount++; else if (c == '\t') prevSpaceCount += mTabSize; - + if ((c == '\n') || (backIdx == 0)) { // Found previous line @@ -904,8 +904,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) { spaceCount = 0; spaceTriviaStart = -1; - } - + } } if ((canUseTrivia) && (spaceCount > 1) && (spaceTriviaStart != -1)) @@ -946,14 +945,14 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) } } else if ((mNextStateModify.mExpectingSpace) || (newExpectingNewLine)) - { + { FlushIndent(); char startChar = bfAstNode->GetSourceData()->mSrc[bfAstNode->GetSrcStart()]; bool isEnding = (startChar == ';') || (startChar == ')'); if ((!isEnding) && (mOutString.length() > 0) && (!isspace((uint8)mOutString[mOutString.length() - 1]))) Write(" "); - } - } + } + } if (!mInSideChannel) { @@ -968,7 +967,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx; } - mForceUseTrivia = false; + mForceUseTrivia = false; if (bfAstNode->GetSrcStart() >= mTriviaIdx) mTriviaIdx = bfAstNode->GetSrcStart(); @@ -978,7 +977,7 @@ void BfPrinter::Visit(BfAstNode* bfAstNode) } bool BfPrinter::CheckReplace(BfAstNode* astNode) -{ +{ return false; } @@ -1018,10 +1017,9 @@ void BfPrinter::Visit(BfNewNode* newNode) } } - void BfPrinter::Visit(BfExpression* expr) { - Visit(expr->ToBase()); + Visit(expr->ToBase()); } void BfPrinter::Visit(BfExpressionStatement* exprStmt) @@ -1033,8 +1031,18 @@ void BfPrinter::Visit(BfExpressionStatement* exprStmt) VisitChild(exprStmt->mTrailingSemicolon); } +void BfPrinter::Visit(BfNamedExpression* namedExpr) +{ + Visit(namedExpr->ToBase()); + + VisitChild(namedExpr->mNameNode); + VisitChild(namedExpr->mColonToken); + ExpectSpace(); + VisitChild(namedExpr->mExpression); +} + void BfPrinter::Visit(BfAttributedExpression* attribExpr) -{ +{ Visit(attribExpr->ToBase()); if (auto indexerExpr = BfNodeDynCast(attribExpr->mExpression)) @@ -1052,20 +1060,20 @@ void BfPrinter::Visit(BfAttributedExpression* attribExpr) VisitChild(indexerExpr->mArguments[i]); } - VisitChild(indexerExpr->mCloseBracket); + VisitChild(indexerExpr->mCloseBracket); } else { VisitChild(attribExpr->mAttributes); VisitChild(attribExpr->mExpression); - } + } } void BfPrinter::Visit(BfStatement* stmt) -{ +{ // Trailing semicolon must come after, so every derived type is responsible for printing it -#ifdef BF_AST_HAS_PARENT_MEMBER +#ifdef BF_AST_HAS_PARENT_MEMBER // if (stmt->mParent != NULL) // { // if (auto block = BfNodeDynCast(stmt->mParent)) @@ -1078,7 +1086,7 @@ void BfPrinter::Visit(BfStatement* stmt) // } // } #endif - + if (stmt == mCurBlockMember) ExpectNewLine(); @@ -1098,7 +1106,7 @@ void BfPrinter::Visit(BfLabelableStatement* labelableStmt) } void BfPrinter::Visit(BfCommentNode* commentNode) -{ +{ WriteIgnoredNode(commentNode); if (commentNode->mCommentKind == BfCommentKind_Line) ExpectNewLine(); @@ -1114,7 +1122,7 @@ void BfPrinter::Visit(BfPreprocessorNode* preprocessorNode) { WriteIgnoredNode(preprocessorNode); - if ((preprocessorNode->mCommand->ToStringView() == "pragma") && + if ((preprocessorNode->mCommand->ToStringView() == "pragma") && (preprocessorNode->mArgument != NULL) && (preprocessorNode->mArgument->mChildArr.mSize == 2) && (preprocessorNode->mArgument->mChildArr[0] != NULL) && @@ -1127,13 +1135,13 @@ void BfPrinter::Visit(BfPreprocessorNode* preprocessorNode) mFormatDisableCount = BF_MAX(0, mFormatDisableCount - 1); } - ExpectNewLine(); + ExpectNewLine(); } void BfPrinter::Visit(BfAttributeDirective* attributeDirective) { Visit(attributeDirective->ToBase()); - + if (attributeDirective->mAttrOpenToken != NULL) { if (attributeDirective->mAttrOpenToken->mToken == BfToken_Comma) @@ -1147,7 +1155,7 @@ void BfPrinter::Visit(BfAttributeDirective* attributeDirective) VisitChild(attributeDirective->mAttrOpenToken); } } - + if (attributeDirective->mAttributeTargetSpecifier != NULL) { if (auto attributeTargetSpecifier = BfNodeDynCast(attributeDirective->mAttributeTargetSpecifier)) @@ -1161,7 +1169,7 @@ void BfPrinter::Visit(BfAttributeDirective* attributeDirective) VisitChild(attributeDirective->mAttributeTargetSpecifier); } } - + VisitChild(attributeDirective->mAttributeTypeRef); VisitChild(attributeDirective->mCtorOpenParen); for (int i = 0; i < (int)attributeDirective->mArguments.size(); i++) @@ -1171,7 +1179,7 @@ void BfPrinter::Visit(BfAttributeDirective* attributeDirective) VisitChildNoRef(attributeDirective->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(attributeDirective->mArguments[i]); + VisitChild(attributeDirective->mArguments[i]); } VisitChild(attributeDirective->mCtorCloseParen); VisitChild(attributeDirective->mAttrCloseToken); @@ -1234,7 +1242,7 @@ void BfPrinter::Visit(BfGenericConstraintsDeclaration* genericConstraints) VisitChildNoRef(genericConstraint->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(genericConstraint->mConstraintTypes[i]); + VisitChild(genericConstraint->mConstraintTypes[i]); } } } @@ -1251,7 +1259,7 @@ void BfPrinter::Visit(BfGenericArgumentsNode* genericArgumentsNode) VisitChildNoRef(genericArgumentsNode->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(genericArgumentsNode->mGenericArgs[i]); + VisitChild(genericArgumentsNode->mGenericArgs[i]); } for (int i = (int)genericArgumentsNode->mGenericArgs.size() - 1; i < (int)genericArgumentsNode->mCommas.size(); i++) VisitChildNoRef(genericArgumentsNode->mCommas.GetSafe(i)); @@ -1276,7 +1284,7 @@ void BfPrinter::Visit(BfTokenNode* tokenNode) } if (tokenNode->GetSrcEnd() == 0) - { + { String tokenStr = BfTokenToString(tokenNode->GetToken()); Write(tokenStr); } @@ -1284,7 +1292,7 @@ void BfPrinter::Visit(BfTokenNode* tokenNode) { BF_ASSERT(tokenNode->GetSrcEnd() > tokenNode->GetSrcStart()); WriteSourceString(tokenNode); - } + } } void BfPrinter::Visit(BfTokenPairNode* tokenPairNode) @@ -1297,6 +1305,15 @@ void BfPrinter::Visit(BfTokenPairNode* tokenPairNode) VisitChild(tokenPairNode->mRight); } +void BfPrinter::Visit(BfUsingSpecifierNode* usingSpecifier) +{ + Visit(usingSpecifier->ToBase()); + + VisitChild(usingSpecifier->mProtection); + ExpectSpace(); + VisitChild(usingSpecifier->mUsingToken); +} + void BfPrinter::Visit(BfLiteralExpression* literalExpr) { Visit(literalExpr->ToBase()); @@ -1315,7 +1332,6 @@ void BfPrinter::Visit(BfLiteralExpression* literalExpr) break; } } - if (isMultiLine) { @@ -1332,7 +1348,7 @@ void BfPrinter::Visit(BfLiteralExpression* literalExpr) } checkIdx--; } - + int queuedSpaceCount = mQueuedSpaceCount; FlushIndent(); @@ -1360,14 +1376,14 @@ void BfPrinter::Visit(BfLiteralExpression* literalExpr) FlushIndent(); i--; - } + } } - + return; } } - WriteSourceString(literalExpr); + WriteSourceString(literalExpr); } void BfPrinter::Visit(BfStringInterpolationExpression* stringInterpolationExpression) @@ -1380,7 +1396,7 @@ void BfPrinter::Visit(BfStringInterpolationExpression* stringInterpolationExpres void BfPrinter::Visit(BfIdentifierNode* identifierNode) { - Visit(identifierNode->ToBase()); + Visit(identifierNode->ToBase()); if (!CheckReplace(identifierNode)) WriteSourceString(identifierNode); @@ -1430,7 +1446,7 @@ void BfPrinter::Visit(BfInitializerExpression* initExpr) VisitChild(initExpr->mTarget); BlockState blockState; - DoBlockOpen(initExpr->mTarget, initExpr->mOpenBrace, initExpr->mCloseBrace, false, blockState); + DoBlockOpen(initExpr->mTarget, initExpr->mOpenBrace, initExpr->mCloseBrace, false, blockState); for (int i = 0; i < (int)initExpr->mValues.size(); i++) { if (i > 0) @@ -1441,13 +1457,13 @@ void BfPrinter::Visit(BfInitializerExpression* initExpr) else ExpectNewLine(); } - + VisitChild(initExpr->mValues[i]); } DoBlockClose(initExpr->mTarget, initExpr->mOpenBrace, initExpr->mCloseBrace, false, blockState); // Visit(initExpr->ToBase()); -// +// // VisitChild(initExpr->mTarget); // ExpectSpace(); // VisitChild(initExpr->mOpenBrace); @@ -1550,11 +1566,11 @@ void BfPrinter::Visit(BfRefTypeRef* typeRef) void BfPrinter::Visit(BfArrayTypeRef* arrayTypeRef) { Visit((BfAstNode*)arrayTypeRef); - + std::function _VisitElements = [&](BfTypeReference* elementRef) { auto arrType = BfNodeDynCast(elementRef); - + if (arrType != NULL) { _VisitElements(arrType->mElementType); @@ -1575,7 +1591,6 @@ void BfPrinter::Visit(BfArrayTypeRef* arrayTypeRef) { if (auto tokenNode = BfNodeDynCast(param)) { - } else { @@ -1593,7 +1608,6 @@ void BfPrinter::Visit(BfArrayTypeRef* arrayTypeRef) _VisitElements(arrayTypeRef); _VisitBrackets(arrayTypeRef); - } void BfPrinter::Visit(BfGenericInstanceTypeRef* genericInstTypeRef) @@ -1626,9 +1640,9 @@ void BfPrinter::Visit(BfTupleTypeRef* typeRef) { Visit((BfAstNode*) typeRef); - VisitChild(typeRef->mOpenParen); + VisitChild(typeRef->mOpenParen); for (int i = 0; i < (int)typeRef->mFieldTypes.size(); i++) - { + { if (i > 0) { VisitChildNoRef(typeRef->mCommas.GetSafe(i - 1)); @@ -1640,7 +1654,7 @@ void BfPrinter::Visit(BfTupleTypeRef* typeRef) { ExpectSpace(); auto fieldNameNode = typeRef->mFieldNames[i]; - if (fieldNameNode != NULL) + if (fieldNameNode != NULL) VisitChild(fieldNameNode); } } @@ -1655,7 +1669,7 @@ void BfPrinter::Visit(BfDelegateTypeRef* typeRef) ExpectSpace(); VisitChild(typeRef->mAttributes); ExpectSpace(); - VisitChild(typeRef->mReturnType); + VisitChild(typeRef->mReturnType); VisitChild(typeRef->mOpenParen); for (int i = 0; i < (int)typeRef->mParams.size(); i++) @@ -1665,8 +1679,8 @@ void BfPrinter::Visit(BfDelegateTypeRef* typeRef) VisitChildNoRef(typeRef->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(typeRef->mParams[i]); - } + VisitChild(typeRef->mParams[i]); + } VisitChild(typeRef->mCloseParen); } @@ -1700,16 +1714,16 @@ void BfPrinter::Visit(BfVariableDeclaration* varDecl) } else VisitChild(varDecl->mTypeRef); - + VisitChildWithPrecedingSpace(varDecl->mNameNode); VisitChildWithPrecedingSpace(varDecl->mEqualsNode); - + if (varDecl->mInitializer != NULL) { if (varDecl->mNameNode != NULL) ExpectSpace(); VisitChild(varDecl->mInitializer); - } + } } void BfPrinter::Visit(BfParameterDeclaration* paramDecl) @@ -1730,7 +1744,7 @@ void BfPrinter::Visit(BfTypeOfExpression* typeOfExpr) VisitChild(typeOfExpr->mToken); VisitChild(typeOfExpr->mOpenParen); VisitChild(typeOfExpr->mTypeRef); - VisitChild(typeOfExpr->mCloseParen); + VisitChild(typeOfExpr->mCloseParen); } void BfPrinter::Visit(BfSizeOfExpression* sizeOfExpr) @@ -1747,7 +1761,7 @@ void BfPrinter::Visit(BfOffsetOfExpression* offsetOfExpr) { VisitChild(offsetOfExpr->mToken); VisitChild(offsetOfExpr->mOpenParen); - VisitChild(offsetOfExpr->mTypeRef); + VisitChild(offsetOfExpr->mTypeRef); VisitChild(offsetOfExpr->mCommaToken); ExpectSpace(); VisitChild(offsetOfExpr->mMemberName); @@ -1797,7 +1811,7 @@ void BfPrinter::Visit(BfDynamicCastExpression* dynCastExpr) } void BfPrinter::Visit(BfCastExpression* castExpr) -{ +{ Visit((BfAstNode*)castExpr); VisitChild(castExpr->mOpenParen); @@ -1805,7 +1819,7 @@ void BfPrinter::Visit(BfCastExpression* castExpr) VisitChild(castExpr->mCloseParen); bool surroundWithParen = false; - + if (surroundWithParen) Write("("); VisitChild(castExpr->mExpression); @@ -1842,19 +1856,19 @@ void BfPrinter::Visit(BfLambdaBindExpression* lambdaBindExpr) VisitChildNoRef(lambdaBindExpr->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(lambdaBindExpr->mParams[i]); + VisitChild(lambdaBindExpr->mParams[i]); } VisitChild(lambdaBindExpr->mCloseParen); ExpectSpace(); - VisitChild(lambdaBindExpr->mFatArrowToken); + VisitChild(lambdaBindExpr->mFatArrowToken); if (lambdaBindExpr->mBody != NULL) { if (lambdaBindExpr->mBody->IsA()) { ExpectNewLine(); ExpectIndent(); - VisitChild(lambdaBindExpr->mBody); - ExpectUnindent(); + VisitChild(lambdaBindExpr->mBody); + ExpectUnindent(); } else { @@ -1875,8 +1889,8 @@ void BfPrinter::Visit(BfObjectCreateExpression* newExpr) VisitChild(newExpr->mNewNode); ExpectSpace(); - - VisitChild(newExpr->mTypeRef); + + VisitChild(newExpr->mTypeRef); if (newExpr->mStarToken != NULL) { @@ -1901,9 +1915,9 @@ void BfPrinter::Visit(BfObjectCreateExpression* newExpr) VisitChildNoRef(newExpr->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(newExpr->mArguments[i]); + VisitChild(newExpr->mArguments[i]); } - _WriteToken(newExpr->mCloseToken, BfToken_RParen); + _WriteToken(newExpr->mCloseToken, BfToken_RParen); } void BfPrinter::Visit(BfBoxExpression* boxExpr) @@ -1914,7 +1928,7 @@ void BfPrinter::Visit(BfBoxExpression* boxExpr) ExpectSpace(); VisitChild(boxExpr->mBoxToken); ExpectSpace(); - VisitChild(boxExpr->mExpression); + VisitChild(boxExpr->mExpression); } void BfPrinter::Visit(BfThrowStatement* throwStmt) @@ -1937,7 +1951,6 @@ void BfPrinter::Visit(BfDeleteStatement* deleteStmt) VisitChild(deleteStmt->mAllocExpr); ExpectSpace(); VisitChild(deleteStmt->mExpression); - VisitChild(deleteStmt->mTrailingSemicolon); } @@ -1972,8 +1985,8 @@ void BfPrinter::Visit(BfDeferStatement* deferStmt) if (deferStmt->mBind != NULL) { auto bind = deferStmt->mBind; - - VisitChild(bind->mOpenBracket); + + VisitChild(bind->mOpenBracket); for (int i = 0; i < bind->mParams.size(); i++) { if (i > 0) @@ -1988,10 +2001,10 @@ void BfPrinter::Visit(BfDeferStatement* deferStmt) VisitChild(deferStmt->mOpenParen); VisitChild(deferStmt->mScopeToken); - VisitChild(deferStmt->mCloseParen); + VisitChild(deferStmt->mCloseParen); ExpectSpace(); VisitChild(deferStmt->mTargetNode); - + VisitChild(deferStmt->mTrailingSemicolon); } @@ -2021,13 +2034,13 @@ void BfPrinter::Visit(BfCaseExpression* caseExpr) } else { - VisitChild(caseExpr->mValueExpression); + VisitChild(caseExpr->mValueExpression); ExpectSpace(); - VisitChild(caseExpr->mCaseToken); + VisitChild(caseExpr->mCaseToken); BF_ASSERT(caseExpr->mEqualsNode == NULL); ExpectSpace(); VisitChild(caseExpr->mCaseExpression); - } + } } void BfPrinter::Visit(BfSwitchCase* switchCase) @@ -2035,7 +2048,7 @@ void BfPrinter::Visit(BfSwitchCase* switchCase) if (mIndentCaseLabels) ExpectIndent(); - VisitChild(switchCase->mCaseToken); + VisitChild(switchCase->mCaseToken); for (int caseIdx = 0; caseIdx < (int) switchCase->mCaseExpressions.size(); caseIdx++) { if ((caseIdx == 0) || (caseIdx > (int)switchCase->mCaseCommas.size())) @@ -2080,30 +2093,29 @@ void BfPrinter::Visit(BfSwitchStatement* switchStmt) ExpectNewLine(); VisitChild(switchStmt->mOpenBrace); - ExpectNewLine(); - + ExpectNewLine(); + for (auto switchCase : switchStmt->mSwitchCases) Visit(switchCase); if (switchStmt->mDefaultCase != NULL) Visit(switchStmt->mDefaultCase); - + ExpectNewLine(); VisitChild(switchStmt->mCloseBrace); VisitChild(switchStmt->mTrailingSemicolon); } - void BfPrinter::Visit(BfTryStatement* tryStmt) { Visit(tryStmt->ToBase()); - + VisitChild(tryStmt->mTryToken); VisitChild(tryStmt->mStatement); } void BfPrinter::Visit(BfCatchStatement* catchStmt) -{ +{ Visit(catchStmt->ToBase()); WriteSourceString(catchStmt); @@ -2141,12 +2153,12 @@ void BfPrinter::Visit(BfIfStatement* ifStmt) VisitChild(ifStmt->mIfToken); ExpectSpace(); - VisitChild(ifStmt->mOpenParen); + VisitChild(ifStmt->mOpenParen); VisitChild(ifStmt->mCondition); VisitChild(ifStmt->mCloseParen); - ExpectSpace(); - VisitChildNextLine(ifStmt->mTrueStatement); - VisitChild(ifStmt->mElseToken); + ExpectSpace(); + VisitChildNextLine(ifStmt->mTrueStatement); + VisitChild(ifStmt->mElseToken); if (ifStmt->mFalseStatement != NULL) { ExpectSpace(); @@ -2160,9 +2172,9 @@ void BfPrinter::Visit(BfIfStatement* ifStmt) } void BfPrinter::Visit(BfReturnStatement* returnStmt) -{ +{ Visit(returnStmt->ToBase()); - + VisitChild(returnStmt->mReturnToken); if (returnStmt->mExpression != NULL) { @@ -2173,7 +2185,7 @@ void BfPrinter::Visit(BfReturnStatement* returnStmt) } void BfPrinter::Visit(BfUsingStatement* doStmt) -{ +{ Visit(doStmt->ToBase()); VisitChild(doStmt->mUsingToken); @@ -2191,20 +2203,20 @@ void BfPrinter::Visit(BfDoStatement* doStmt) Visit(doStmt->ToBase()); VisitChild(doStmt->mDoToken); - VisitChildNextLine(doStmt->mEmbeddedStatement); + VisitChildNextLine(doStmt->mEmbeddedStatement); } void BfPrinter::Visit(BfRepeatStatement* repeatStmt) { Visit(repeatStmt->ToBase()); - VisitChild(repeatStmt->mRepeatToken); + VisitChild(repeatStmt->mRepeatToken); VisitChildNextLine(repeatStmt->mEmbeddedStatement); VisitChild(repeatStmt->mWhileToken); ExpectSpace(); VisitChild(repeatStmt->mOpenParen); VisitChild(repeatStmt->mCondition); - VisitChild(repeatStmt->mCloseParen); + VisitChild(repeatStmt->mCloseParen); VisitChild(repeatStmt->mTrailingSemicolon); } @@ -2213,7 +2225,7 @@ void BfPrinter::Visit(BfWhileStatement* whileStmt) { Visit(whileStmt->ToBase()); - VisitChild(whileStmt->mWhileToken); + VisitChild(whileStmt->mWhileToken); ExpectSpace(); VisitChild(whileStmt->mOpenParen); VisitChild(whileStmt->mCondition); @@ -2233,7 +2245,7 @@ void BfPrinter::Visit(BfBreakStatement* breakStmt) ExpectSpace(); VisitChild(breakStmt->mLabel); } - VisitChild(breakStmt->mTrailingSemicolon); + VisitChild(breakStmt->mTrailingSemicolon); } void BfPrinter::Visit(BfContinueStatement* continueStmt) @@ -2288,11 +2300,11 @@ void BfPrinter::Visit(BfForStatement* forStmt) void BfPrinter::Visit(BfForEachStatement* forEachStmt) { - Visit(forEachStmt->ToBase()); + Visit(forEachStmt->ToBase()); VisitChild(forEachStmt->mForToken); ExpectSpace(); - VisitChild(forEachStmt->mOpenParen); + VisitChild(forEachStmt->mOpenParen); if (forEachStmt->mReadOnlyToken != NULL) { VisitChild(forEachStmt->mReadOnlyToken); @@ -2304,7 +2316,7 @@ void BfPrinter::Visit(BfForEachStatement* forEachStmt) ExpectSpace(); VisitChild(forEachStmt->mInToken); ExpectSpace(); - VisitChild(forEachStmt->mCollectionExpression); + VisitChild(forEachStmt->mCollectionExpression); VisitChild(forEachStmt->mCloseParen); ExpectNewLine(); VisitChildNextLine(forEachStmt->mEmbeddedStatement); @@ -2342,8 +2354,8 @@ void BfPrinter::Visit(BfParenthesizedExpression* parenExpr) { Visit(parenExpr->ToBase()); - VisitChild(parenExpr->mOpenParen); - VisitChild(parenExpr->mExpression); + VisitChild(parenExpr->mOpenParen); + VisitChild(parenExpr->mExpression); VisitChild(parenExpr->mCloseParen); } @@ -2370,7 +2382,7 @@ void BfPrinter::Visit(BfTupleExpression* tupleExpr) ExpectSpace(); } } - + VisitChild(tupleExpr->mValues[i]); } @@ -2399,7 +2411,7 @@ void BfPrinter::Visit(BfIndexerExpression* indexerExpr) VisitChildNoRef(indexerExpr->mCommas.GetSafe(i - 1)); ExpectSpace(); } - VisitChild(indexerExpr->mArguments[i]); + VisitChild(indexerExpr->mArguments[i]); } VisitChild(indexerExpr->mCloseBracket); @@ -2441,11 +2453,11 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration) ExpectNewLine(); } - QueueVisitChild(ctorDeclaration->mProtectionSpecifier); + QueueVisitChild(ctorDeclaration->mProtectionSpecifier); ExpectSpace(); QueueVisitChild(ctorDeclaration->mNewSpecifier); ExpectSpace(); - QueueVisitChild(ctorDeclaration->mStaticSpecifier); + QueueVisitChild(ctorDeclaration->mStaticSpecifier); ExpectSpace(); if (mDocPrep) @@ -2457,7 +2469,7 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration) else { QueueVisitChild(ctorDeclaration->mThisToken); - } + } QueueVisitChild(ctorDeclaration->mOpenParen); for (int i = 0; i < (int) ctorDeclaration->mParams.size(); i++) @@ -2477,10 +2489,20 @@ void BfPrinter::Visit(BfConstructorDeclaration* ctorDeclaration) QueueVisitChild(ctorDeclaration->mFatArrowToken); QueueVisitChild(ctorDeclaration->mBody); - + FlushVisitChild(); } +void BfPrinter::Visit(BfAutoConstructorDeclaration* ctorDeclaration) +{ + if (ctorDeclaration->mPrefix != NULL) + { + VisitChild(ctorDeclaration->mPrefix); + ExpectSpace(); + } + Visit(ctorDeclaration->ToBase()); +} + void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration) { //Visit((BfAstNode*)dtorDeclaration); @@ -2488,7 +2510,7 @@ void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration) QueueVisitChild(dtorDeclaration->mAttributes); ExpectNewLine(); ExpectSpace(); - QueueVisitChild(dtorDeclaration->mProtectionSpecifier); + QueueVisitChild(dtorDeclaration->mProtectionSpecifier); ExpectSpace(); QueueVisitChild(dtorDeclaration->mNewSpecifier); ExpectSpace(); @@ -2498,14 +2520,14 @@ void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration) if (mDocPrep) { - FlushVisitChild(); + FlushVisitChild(); VisitChild(mCurTypeDecl->mNameNode); } else { QueueVisitChild(dtorDeclaration->mThisToken); } - + QueueVisitChild(dtorDeclaration->mOpenParen); for (int i = 0; i < (int) dtorDeclaration->mParams.size(); i++) { @@ -2516,7 +2538,7 @@ void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration) } QueueVisitChild(dtorDeclaration->mParams[i]); } - QueueVisitChild(dtorDeclaration->mCloseParen); + QueueVisitChild(dtorDeclaration->mCloseParen); QueueVisitChild(dtorDeclaration->mFatArrowToken); QueueVisitChild(dtorDeclaration->mBody); @@ -2524,41 +2546,40 @@ void BfPrinter::Visit(BfDestructorDeclaration* dtorDeclaration) FlushVisitChild(); } - void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) -{ +{ if (methodDeclaration->mAttributes != NULL) { QueueVisitChild(methodDeclaration->mAttributes); ExpectNewLine(); } - + if (methodDeclaration->mExternSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mExternSpecifier); + QueueVisitChild(methodDeclaration->mExternSpecifier); } if (methodDeclaration->mProtectionSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mProtectionSpecifier); + QueueVisitChild(methodDeclaration->mProtectionSpecifier); } - + if (methodDeclaration->mNewSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mNewSpecifier); + QueueVisitChild(methodDeclaration->mNewSpecifier); } - + if (methodDeclaration->mVirtualSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mVirtualSpecifier); + QueueVisitChild(methodDeclaration->mVirtualSpecifier); } - + if (methodDeclaration->mStaticSpecifier != NULL) - { + { ExpectSpace(); QueueVisitChild(methodDeclaration->mStaticSpecifier); } @@ -2570,23 +2591,23 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) } if (methodDeclaration->mMixinSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mMixinSpecifier); + QueueVisitChild(methodDeclaration->mMixinSpecifier); } if (methodDeclaration->mPartialSpecifier != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mPartialSpecifier); + QueueVisitChild(methodDeclaration->mPartialSpecifier); } - + if ((methodDeclaration->mNameNode != NULL) || (methodDeclaration->mExplicitInterface != NULL)) ExpectSpace(); - QueueVisitChild(methodDeclaration->mExplicitInterface); + QueueVisitChild(methodDeclaration->mExplicitInterface); QueueVisitChild(methodDeclaration->mExplicitInterfaceDotToken); QueueVisitChild(methodDeclaration->mNameNode); - + if (auto operatorDecl = BfNodeDynCast(methodDeclaration)) { if ((operatorDecl->mOpTypeToken != NULL) && (operatorDecl->mOpTypeToken->mToken == BfToken_LChevron)) @@ -2595,7 +2616,7 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) QueueVisitChild(methodDeclaration->mGenericParams); if (auto operatorDecl = BfNodeDynCast(methodDeclaration)) - { + { ExpectSpace(); QueueVisitChild(operatorDecl->mExplicitToken); ExpectSpace(); @@ -2603,14 +2624,14 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) ExpectSpace(); QueueVisitChild(operatorDecl->mOpTypeToken); ExpectSpace(); - QueueVisitChild(methodDeclaration->mReturnType); + QueueVisitChild(methodDeclaration->mReturnType); } else if (methodDeclaration->mReturnType != NULL) - { + { ExpectSpace(); - QueueVisitChild(methodDeclaration->mReturnType); + QueueVisitChild(methodDeclaration->mReturnType); } - + QueueVisitChild(methodDeclaration->mOpenParen); if (methodDeclaration->mThisToken != NULL) { @@ -2623,7 +2644,7 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) { QueueVisitChild(methodDeclaration->mCommas.GetSafe(i - 1)); ExpectSpace(); - } + } QueueVisitChild(methodDeclaration->mParams[i]); } QueueVisitChild(methodDeclaration->mCloseParen); @@ -2636,15 +2657,15 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration) ExpectSpace(); QueueVisitChild(methodDeclaration->mFatArrowToken); ExpectSpace(); - } + } QueueVisitChild(methodDeclaration->mBody); - QueueVisitChild(methodDeclaration->mEndSemicolon); + QueueVisitChild(methodDeclaration->mEndSemicolon); } void BfPrinter::Visit(BfMethodDeclaration* methodDeclaration) { //Visit(methodDeclaration->ToBase()); - + ExpectNewLine(); QueueMethodDeclaration(methodDeclaration); //?? QueueVisitErrorNodes(methodDeclaration); @@ -2659,12 +2680,12 @@ void BfPrinter::Visit(BfOperatorDeclaration* opreratorDeclaration) } void BfPrinter::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration) -{ +{ ExpectNewLine(); QueueVisitChild(propertyMethodDeclaration->mAttributes); ExpectNewLine(); QueueVisitChild(propertyMethodDeclaration->mProtectionSpecifier); - ExpectSpace(); + ExpectSpace(); QueueVisitChild(propertyMethodDeclaration->mNameNode); ExpectSpace(); QueueVisitChild(propertyMethodDeclaration->mSetRefSpecifier); @@ -2673,8 +2694,8 @@ void BfPrinter::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration) ExpectSpace(); QueueVisitChild(propertyMethodDeclaration->mFatArrowToken); ExpectSpace(); - if (auto block = BfNodeDynCast(propertyMethodDeclaration->mBody)) - ExpectNewLine(); + if (auto block = BfNodeDynCast(propertyMethodDeclaration->mBody)) + ExpectNewLine(); QueueVisitChild(propertyMethodDeclaration->mBody); QueueVisitChild(propertyMethodDeclaration->mEndSemicolon); } @@ -2692,7 +2713,7 @@ void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration) ExpectNewLine(); QueueVisitChild(propertyDeclaration->mAttributes); - ExpectNewLine(); + ExpectNewLine(); ExpectSpace(); QueueVisitChild(propertyDeclaration->mProtectionSpecifier); ExpectSpace(); @@ -2716,7 +2737,7 @@ void BfPrinter::Visit(BfPropertyDeclaration* propertyDeclaration) QueueVisitChild(propertyDeclaration->mExplicitInterfaceDotToken); QueueVisitChild(propertyDeclaration->mNameNode); ExpectSpace(); - + if (indexerDeclaration != NULL) { QueueVisitChild(indexerDeclaration->mThisToken); @@ -2780,10 +2801,10 @@ void BfPrinter::Visit(BfFieldDeclaration* fieldDeclaration) bool isEnumDecl = false; if (auto enumEntry = BfNodeDynCast(fieldDeclaration)) - { + { isEnumDecl = true; } - + if (fieldDeclaration->mPrecedingComma != NULL) { mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx; @@ -2846,7 +2867,7 @@ void BfPrinter::Visit(BfEnumCaseDeclaration* enumCaseDeclaration) { ExpectNewLine(); - Visit(enumCaseDeclaration->ToBase()); + Visit(enumCaseDeclaration->ToBase()); if (mDocPrep) { @@ -2864,7 +2885,7 @@ void BfPrinter::Visit(BfEnumCaseDeclaration* enumCaseDeclaration) } VisitChild(enumCaseDeclaration->mCaseToken); - ExpectSpace(); + ExpectSpace(); for (int i = 0; i < (int)enumCaseDeclaration->mEntries.size(); i++) { @@ -2889,8 +2910,8 @@ void BfPrinter::Visit(BfTypeAliasDeclaration* typeDeclaration) } void BfPrinter::Visit(BfFieldDtorDeclaration* fieldDtorDeclaration) -{ - ExpectSpace(); +{ + ExpectSpace(); if (fieldDtorDeclaration->mBody != NULL) { if (fieldDtorDeclaration->mBody->IsA()) @@ -2930,16 +2951,16 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) break; } } - - ExpectNewLine(); + + ExpectNewLine(); QueueVisitChild(typeDeclaration->mAttributes); if (!isOneLine) - ExpectNewLine(); + ExpectNewLine(); ExpectSpace(); QueueVisitChild(typeDeclaration->mAbstractSpecifier); ExpectSpace(); QueueVisitChild(typeDeclaration->mSealedSpecifier); - ExpectSpace(); + ExpectSpace(); QueueVisitChild(typeDeclaration->mProtectionSpecifier); ExpectSpace(); QueueVisitChild(typeDeclaration->mStaticSpecifier); @@ -2951,16 +2972,15 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) if ((mDocPrep) && (typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mTypeNode->mToken == BfToken_Enum)) { if (auto defineBlock = BfNodeDynCast(typeDeclaration->mDefineNode)) - { + { if (auto enumEntryDecl = BfNodeDynCast(defineBlock->GetFirst())) { - } else { isEnumDoc = true; } - } + } } if (isEnumDoc) @@ -2991,14 +3011,14 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) QueueVisitChild(typeDeclaration->mBaseClassCommas.GetSafe(i - 1)); } } - ExpectSpace(); + ExpectSpace(); } QueueVisitChild(typeDeclaration->mGenericConstraintsDeclaration); if (queueChildren) { if (auto defineBlock = BfNodeDynCast(typeDeclaration->mDefineNode)) - { + { for (auto member : defineBlock->mChildArr) { SetAndRestoreValue prevBlockMember(mCurBlockMember, member); @@ -3018,7 +3038,7 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) } } else - { + { FlushVisitChild(); if (auto defineBlock = BfNodeDynCast(typeDeclaration->mDefineNode)) { @@ -3044,14 +3064,14 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) VisitChild(member); } ExpectUnindent(); - VisitChild(defineBlock->mCloseBrace); - } + VisitChild(defineBlock->mCloseBrace); + } else { FlushVisitChild(); VisitChild(typeDeclaration->mDefineNode); } - } + } ExpectNewLine(); } @@ -3059,13 +3079,13 @@ void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration) void BfPrinter::Visit(BfUsingDirective* usingDirective) { //Visit(usingDirective->ToBase()); - - ExpectNewLine(); - VisitChild(usingDirective->mUsingToken); - ExpectSpace(); - VisitChild(usingDirective->mNamespace); - VisitChild(usingDirective->mTrailingSemicolon); + ExpectNewLine(); + VisitChild(usingDirective->mUsingToken); + ExpectSpace(); + VisitChild(usingDirective->mNamespace); + + VisitChild(usingDirective->mTrailingSemicolon); ExpectNewLine(); } @@ -3091,12 +3111,12 @@ void BfPrinter::Visit(BfNamespaceDeclaration* namespaceDeclaration) ExpectNewLine(); VisitChild(namespaceDeclaration->mNamespaceNode); ExpectSpace(); - VisitChild(namespaceDeclaration->mNameNode); + VisitChild(namespaceDeclaration->mNameNode); VisitChild(namespaceDeclaration->mBody); } void BfPrinter::DoBlockOpen(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState) -{ +{ blockState.mLastSpaceOffset = mLastSpaceOffset; blockState.mIndentStart = mNextStateModify.mWantVirtualIndent; @@ -3141,7 +3161,7 @@ void BfPrinter::DoBlockClose(BfAstNode* prevNode, BfTokenNode* blockOpen, BfToke { if (!blockState.mDoInlineBlock) { - ExpectUnindent(); + ExpectUnindent(); mNextStateModify.mDoingBlockClose = true; } else @@ -3150,7 +3170,7 @@ void BfPrinter::DoBlockClose(BfAstNode* prevNode, BfTokenNode* blockOpen, BfToke QueueVisitChild(blockClose); else VisitChild(blockClose); - + if (!blockState.mDoInlineBlock) { mNextStateModify.mWantVirtualIndent = blockState.mIndentStart; @@ -3159,7 +3179,7 @@ void BfPrinter::DoBlockClose(BfAstNode* prevNode, BfTokenNode* blockOpen, BfToke } void BfPrinter::Visit(BfBlock* block) -{ +{ BlockState blockState; SetAndRestoreValue prevBlockState(mCurBlockState, &blockState); @@ -3167,7 +3187,7 @@ void BfPrinter::Visit(BfBlock* block) for (auto& childNodeRef : *block) { BfAstNode* child = childNodeRef; - SetAndRestoreValue prevForceTrivia(mForceUseTrivia); + SetAndRestoreValue prevForceTrivia(mForceUseTrivia); SetAndRestoreValue prevVirtualIndent(mNextStateModify.mWantVirtualIndent); SetAndRestoreValue prevBlockMember(mCurBlockMember, child); CheckRawNode(child); @@ -3179,7 +3199,7 @@ void BfPrinter::Visit(BfBlock* block) } void BfPrinter::Visit(BfRootNode* rootNode) -{ +{ for (auto child : rootNode->mChildArr) { SetAndRestoreValue prevBlockMember(mCurBlockMember, child); @@ -3189,7 +3209,7 @@ void BfPrinter::Visit(BfRootNode* rootNode) // Flush whitespace at the end of the document BfParserData* bfParser = rootNode->GetSourceData()->ToParserData(); if (bfParser != NULL) - { + { BfAstNode* endNode = mSource->mAlloc.Alloc(); endNode->Init(rootNode->GetSrcEnd(), bfParser->mSrcLength, bfParser->mSrcLength); Visit(endNode); @@ -3203,5 +3223,4 @@ void BfPrinter::Visit(BfRootNode* rootNode) void BfPrinter::Visit(BfInlineAsmStatement* asmStmt) { - -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfPrinter.h b/IDEHelper/Compiler/BfPrinter.h index 7601e6f1..e0a6dcd8 100644 --- a/IDEHelper/Compiler/BfPrinter.h +++ b/IDEHelper/Compiler/BfPrinter.h @@ -5,7 +5,6 @@ NS_BF_BEGIN - class BfPrinter : public BfElementVisitor { public: @@ -26,10 +25,10 @@ public: struct StateModify { public: - bool mExpectingSpace; + bool mExpectingSpace; int mWantNewLineIdx; bool mDoingBlockOpen; - bool mDoingBlockClose; + bool mDoingBlockClose; int mWantVirtualIndent; BfAstNode* mQueuedNode; @@ -43,18 +42,18 @@ public: void Clear() { - mExpectingSpace = false; + mExpectingSpace = false; mDoingBlockOpen = false; mDoingBlockClose = false; mQueuedNode = NULL; } }; - + BfSourceData* mSource; BfParserData* mParser; BfBlock::Iterator mSidechannelItr; - BfAstNode* mSidechannelNextNode; + BfAstNode* mSidechannelNextNode; BfBlock::Iterator mErrorItr; BfAstNode* mErrorNextNode; @@ -65,18 +64,18 @@ public: int mCurSrcIdx; Array mChildNodeQueue; int mFormatStart; - int mFormatEnd; + int mFormatEnd; int mFormatDisableCount; StateModify mNextStateModify; - + String mOutString; - bool mReformatting; + bool mReformatting; bool mIgnoreTrivia; bool mDocPrep; BlockState* mCurBlockState; int mCurIndentLevel; int mQueuedSpaceCount; - int mLastSpaceOffset; // Indent difference from original to new + int mLastSpaceOffset; // Indent difference from original to new bool mExpectingNewLine; int mCurCol; int mMaxCol; @@ -86,19 +85,19 @@ public: bool mIsFirstStatementInBlock; bool mForceUseTrivia; - bool mInSideChannel; + bool mInSideChannel; int mStateModifyVirtualIndentLevel; int mVirtualIndentLevel; int mVirtualNewLineIdx; - + Array* mCharMapping; int mHighestCharId; -public: +public: BfPrinter(BfRootNode* rootNode, BfRootNode* sidechannelRootNode, BfRootNode* errorRootNode); - -public: + +public: void Update(BfAstNode* bfAstNode); bool CheckReplace(BfAstNode* astNode); void FlushIndent(); @@ -106,7 +105,7 @@ public: void Write(BfAstNode* node, int start, int len); void WriteSourceString(BfAstNode* node); void QueueVisitChild(BfAstNode* astNode); - void QueueVisitErrorNodes(BfRootNode* astNode); + void QueueVisitErrorNodes(BfRootNode* astNode); void FlushVisitChild(); void VisitChildWithPrecedingSpace(BfAstNode* bfAstNode); void VisitChildWithProceedingSpace(BfAstNode* bfAstNode); @@ -117,9 +116,9 @@ public: void VisitChildNextLine(BfAstNode* node); void DoBlockOpen(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState); void DoBlockClose(BfAstNode* prevNode, BfTokenNode* blockOpen, BfTokenNode* blockClose, bool queue, BlockState& blockState); - void QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration); + void QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration); int CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx); - void WriteIgnoredNode(BfAstNode* node); + void WriteIgnoredNode(BfAstNode* node); void CheckRawNode(BfAstNode* node); virtual void Visit(BfAstNode* bfAstNode) override; @@ -128,23 +127,25 @@ public: virtual void Visit(BfNewNode * newNode) override; virtual void Visit(BfExpression* expr) override; virtual void Visit(BfExpressionStatement* exprStmt) override; + virtual void Visit(BfNamedExpression* namedExpr) override; virtual void Visit(BfAttributedExpression* attribExpr) override; - virtual void Visit(BfStatement* stmt) override; + virtual void Visit(BfStatement* stmt) override; virtual void Visit(BfLabelableStatement* labelableStmt) override; virtual void Visit(BfCommentNode* commentNode) override; virtual void Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection) override; virtual void Visit(BfPreprocessorNode* preprocessorNode) override; - virtual void Visit(BfAttributeDirective* attributeDirective) override; + virtual void Visit(BfAttributeDirective* attributeDirective) override; virtual void Visit(BfGenericParamsDeclaration* genericParams) override; virtual void Visit(BfGenericOperatorConstraint* genericConstraints) override; virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints) override; virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode) override; - virtual void Visit(BfEmptyStatement* emptyStmt) override; + virtual void Visit(BfEmptyStatement* emptyStmt) override; virtual void Visit(BfTokenNode* tokenNode) override; virtual void Visit(BfTokenPairNode* tokenPairNode) override; + virtual void Visit(BfUsingSpecifierNode* usingSpecifier) override; virtual void Visit(BfLiteralExpression* literalExpr) override; virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression) override; virtual void Visit(BfIdentifierNode* identifierNode) override; @@ -154,7 +155,7 @@ public: virtual void Visit(BfMixinExpression* mixinExpr) override; virtual void Visit(BfSizedArrayCreateExpression* createExpr) override; virtual void Visit(BfInitializerExpression* initExpr) override; - virtual void Visit(BfCollectionInitializerExpression* initExpr) override; + virtual void Visit(BfCollectionInitializerExpression* initExpr) override; virtual void Visit(BfTypeReference* typeRef) override; virtual void Visit(BfNamedTypeReference* typeRef) override; virtual void Visit(BfQualifiedTypeReference* qualifiedType) override; @@ -170,7 +171,7 @@ public: virtual void Visit(BfPointerTypeRef* typeRef) override; virtual void Visit(BfNullableTypeRef* typeRef) override; virtual void Visit(BfVariableDeclaration* varDecl) override; - virtual void Visit(BfParameterDeclaration* paramDecl) override; + virtual void Visit(BfParameterDeclaration* paramDecl) override; virtual void Visit(BfTypeOfExpression* typeOfExpr) override; virtual void Visit(BfSizeOfExpression* sizeOfExpr) override; virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override; @@ -179,11 +180,11 @@ public: virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override; virtual void Visit(BfDynamicCastExpression* dynCastExpr) override; virtual void Visit(BfCastExpression* castExpr) override; - virtual void Visit(BfDelegateBindExpression* invocationExpr) override; + virtual void Visit(BfDelegateBindExpression* invocationExpr) override; virtual void Visit(BfLambdaBindExpression* lambdaBindExpr) override; virtual void Visit(BfObjectCreateExpression* invocationExpr) override; virtual void Visit(BfBoxExpression* boxExpr) override; - virtual void Visit(BfInvocationExpression* invocationExpr) override; + virtual void Visit(BfInvocationExpression* invocationExpr) override; virtual void Visit(BfSwitchCase* switchCase) override; virtual void Visit(BfWhenExpression* whenExpr) override; virtual void Visit(BfSwitchStatement* switchStmt) override; @@ -217,6 +218,7 @@ public: virtual void Visit(BfUnaryOperatorExpression* binOpExpr) override; virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override; virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override; + virtual void Visit(BfAutoConstructorDeclaration* ctorDeclaration) override; virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override; virtual void Visit(BfMethodDeclaration* methodDeclaration) override; virtual void Visit(BfOperatorDeclaration* opreratorDeclaration) override; diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index a9f62ae0..f73343f2 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -149,7 +149,7 @@ void BfReducer::ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode) if (!newNode->IsInitialized()) { -#ifdef BF_AST_COMPACT +#ifdef BF_AST_COMPACT if (prevNode->mIsCompact) { newNode->mIsCompact = prevNode->mIsCompact; @@ -224,9 +224,8 @@ void BfReducer::AddErrorNode(BfAstNode* astNode, bool removeNode) astNode->RemoveSelf(); } - bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple) -{ +{ AssertCurrentNode(checkNode); if (couldBeExpr != NULL) @@ -418,7 +417,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int bool hadTupleComma = false; bool hadIdentifier = false; bool foundSuccessToken = false; - bool hadUnexpectedIdentifier = false; + bool hadUnexpectedIdentifier = false; BfTokenNode* lastToken = NULL; SizedArray tokenStack; @@ -459,7 +458,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int if ((doEnding) && (tokenStack.size() == 1)) doEnding = checkToken == tokenStack.back(); if (doEnding) - { + { bool success = false; if ((lastToken != NULL) && ((lastToken->GetToken() == BfToken_RChevron) || (lastToken->GetToken() == BfToken_RDblChevron))) @@ -469,7 +468,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int } if (successToken == BfToken_RParen) - { + { success = (chevronDepth == 0) && (bracketDepth == 0) && (parenDepth == 1); if (success) @@ -477,7 +476,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int // Check identifierExpected - this catches (.) casts if ((identifierExpected) && (couldBeExpr != NULL)) *couldBeExpr = false; - } + } } else if ((successToken == BfToken_Comma) || (successToken == BfToken_LBracket)) @@ -575,7 +574,6 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int return false; } } - } else if ((checkToken == BfToken_Const) && (chevronDepth > 0)) { @@ -631,9 +629,9 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int if (tokenStack.IsEmpty()) break; - + for (int i = 0; i < ((checkToken == BfToken_RDblChevron) ? 2 : 1); i++) - { + { if (tokenStack.back() != BfToken_RChevron) { if (outEndNode != NULL) @@ -900,7 +898,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int else if ((checkToken == BfToken_DotDotDot) && (chevronDepth > 0)) { isDone = true; - + auto nextNode = mVisitorPos.Get(checkIdx + 1); if (auto nextToken = BfNodeDynCast(nextNode)) { @@ -910,7 +908,6 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int } else if (checkToken != BfToken_LBracket) isDone = true; - if (isDone) { @@ -961,7 +958,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int { // Allow identifierExpected = false; - } + } else { bool mayBeExprPart = false; @@ -1000,7 +997,7 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int int retryNode = -1; if (IsTypeReference(checkNode, successToken, endNode, &retryNode, outEndNode, couldBeExpr, isGenericType, isTuple)) return true; - + if ((retryNode != -1) && (successToken == BfToken_None)) { int newEndNode = -1; @@ -1063,7 +1060,6 @@ bool BfReducer::IsLocalMethod(BfAstNode* nameNode) } else { - } checkIdx++; @@ -1585,7 +1581,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat //if (!couldBeExpr) { auto endingTokenNode = BfNodeDynCast(mVisitorPos.Get(outEndNode - 1)); - // If the type ends with a * or a ? then it could be an expression + // If the type ends with a * or a ? then it could be an expression if (endingTokenNode == NULL) { isLocalVariable = true; @@ -1598,14 +1594,6 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat if (isTuple) isLocalVariable = true; } - else if (endingToken == BfToken_Star) - { - // Check spacing for "a* b" to determine if it's a pointer definition or a multiply - auto beforeStarNode = mVisitorPos.Get(outEndNode - 2); - if ((endingTokenNode->GetSrcStart() == beforeStarNode->GetSrcEnd()) && - (identifierNode->GetSrcStart() > endingTokenNode->GetSrcEnd())) - isLocalVariable = true; - } else if ((endingToken != BfToken_Star) && (endingToken != BfToken_Question)) isLocalVariable = true; } @@ -1831,7 +1819,6 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat bool isLambdaBind = false; bool isBoxing = false; - auto nextNode = mVisitorPos.GetNext(); if (auto nextTokenNode = BfNodeDynCast(nextNode)) { @@ -1853,7 +1840,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat mVisitorPos.mReadPos--; } } - + if (auto interpExpr = BfNodeDynCastExact(nextNode)) { mVisitorPos.MoveNext(); @@ -1862,8 +1849,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat interpExpr->mAllocNode = allocNode; interpExpr->mTriviaStart = allocNode->mTriviaStart; - interpExpr->mSrcStart = allocNode->mSrcStart; - + interpExpr->mSrcStart = allocNode->mSrcStart; + exprLeft = interpExpr; } else if (isBoxing) @@ -2008,7 +1995,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat auto expr = CreateExpressionAfter(isConstExpr); MEMBER_SET_CHECKED(isConstExpr, mExpression, expr); tokenNode = ExpectTokenAfter(isConstExpr, BfToken_RParen); - MEMBER_SET_CHECKED(isConstExpr, mCloseParen, tokenNode); + MEMBER_SET_CHECKED(isConstExpr, mCloseParen, tokenNode); exprLeft = isConstExpr; } else if (token == BfToken_Question) @@ -2179,9 +2166,9 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat couldBeExpr = false; isTuple = false; if ((createExprFlags & CreateExprFlags_NoCast) == 0) - isCastExpr = IsTypeReference(node, BfToken_RParen, -1, &endNodeIdx, &couldBeExpr, NULL, &isTuple); + isCastExpr = IsTypeReference(node, BfToken_RParen, -1, &endNodeIdx, &couldBeExpr, NULL, &isTuple); if (endNodeIdx != -1) - endNode = mVisitorPos.Get(endNodeIdx); + endNode = mVisitorPos.Get(endNodeIdx); if (isCastExpr) { bool isValidTupleCast = false; @@ -2250,9 +2237,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } } - if (isCastExpr) - { + { BfCastExpression* bfCastExpr = NULL; if (isTuple) { @@ -2292,7 +2278,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat unaryOpExpr = bfCastExpr; } } - + if (!isCastExpr) { if (auto nextToken = BfNodeDynCast(mVisitorPos.GetNext())) @@ -2360,13 +2346,48 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat exprLeft = CreateMemberReferenceExpression(typeRef); } } + else if (tokenNode->GetToken() == BfToken_NameOf) + { + BfNameOfExpression* nameOfExpr = mAlloc->Alloc(); + ReplaceNode(tokenNode, nameOfExpr); + nameOfExpr->mToken = tokenNode; + tokenNode = ExpectTokenAfter(nameOfExpr, BfToken_LParen); + MEMBER_SET_CHECKED(nameOfExpr, mOpenParen, tokenNode); + + mVisitorPos.MoveNext(); + int outEndNode = -1; + bool isTypeRef = IsTypeReference(mVisitorPos.GetCurrent(), BfToken_RParen, -1, &outEndNode); + mVisitorPos.mReadPos--; + + if ((isTypeRef) && (outEndNode > 0)) + { + if (auto tokenNode = BfNodeDynCast(mVisitorPos.Get(outEndNode - 1))) + { + if ((tokenNode->mToken == BfToken_RChevron) || (tokenNode->mToken == BfToken_RDblChevron)) + { + // Can ONLY be a type reference + auto typeRef = CreateTypeRefAfter(nameOfExpr); + MEMBER_SET_CHECKED(nameOfExpr, mTarget, typeRef); + } + } + } + + if (nameOfExpr->mTarget == NULL) + { + auto expr = CreateExpressionAfter(nameOfExpr); + MEMBER_SET_CHECKED(nameOfExpr, mTarget, expr); + } + tokenNode = ExpectTokenAfter(nameOfExpr, BfToken_RParen); + MEMBER_SET_CHECKED(nameOfExpr, mCloseParen, tokenNode); + exprLeft = nameOfExpr; + } if (exprLeft == NULL) { BfUnaryOp unaryOp = BfTokenToUnaryOp(tokenNode->GetToken()); if (unaryOp != BfUnaryOp_None) - { + { unaryOpExpr = mAlloc->Alloc(); unaryOpExpr->mOp = unaryOp; unaryOpExpr->mOpToken = tokenNode; @@ -2377,7 +2398,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat innerFlags = (CreateExprFlags)(innerFlags | (createExprFlags & CreateExprFlags_AllowVariableDecl)); if (unaryOp == BfUnaryOp_PartialRangeThrough) // This allows for just a naked '...' - innerFlags = (CreateExprFlags)(innerFlags | CreateExprFlags_AllowEmpty); + innerFlags = (CreateExprFlags)(innerFlags | CreateExprFlags_AllowEmpty); // Don't attempt binary or unary operations- they will always be lower precedence unaryOpExpr->mExpression = CreateExpressionAfter(unaryOpExpr, innerFlags); @@ -2405,7 +2426,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat if (auto assignmentExpr = BfNodeDynCast(unaryOpExpr->mExpression)) { - // Apply unary operator (likely a dereference) to LHS + // Apply unary operator (likely a dereference) to LHS assignmentExpr->RemoveSelf(); ReplaceNode(unaryOpExpr, assignmentExpr); if (assignmentExpr->mLeft != NULL) @@ -2468,23 +2489,23 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat { BfToken token = tokenNode->GetToken(); - if (((createExprFlags & CreateExprFlags_BreakOnRChevron) != 0) && + if (((createExprFlags & CreateExprFlags_BreakOnRChevron) != 0) && ((token == BfToken_RChevron) || (token == BfToken_RDblChevron))) return exprLeft; - + BfUnaryOp postUnaryOp = BfUnaryOp_None; if (token == BfToken_DblPlus) postUnaryOp = BfUnaryOp_PostIncrement; if (token == BfToken_DblMinus) - postUnaryOp = BfUnaryOp_PostDecrement; + postUnaryOp = BfUnaryOp_PostDecrement; if (token == BfToken_DotDotDot) - { + { //TODO: Detect if this is a BfUnaryOp_PartialRangeFrom } if (postUnaryOp != BfUnaryOp_None) - { + { auto unaryOpExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, unaryOpExpr); unaryOpExpr->mOp = postUnaryOp; @@ -2496,7 +2517,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } if (token == BfToken_As) - { + { auto dynCastExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, dynCastExpr); dynCastExpr->mTarget = exprLeft; @@ -2510,7 +2531,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } if (token == BfToken_Is) - { + { auto checkTypeExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, checkTypeExpr); checkTypeExpr->mTarget = exprLeft; @@ -2761,7 +2782,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat continue; } - // Could be a struct generic initializer, or a generic method invocation + // Could be a struct generic initializer, or a generic method invocation if (auto outToken = BfNodeDynCast(outNode)) { int endNodeIdx = -1; @@ -2830,7 +2851,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat binOpExpression->mLeft = exprLeft; binOpExpression->mOp = binOp; MEMBER_SET(binOpExpression, mOpToken, tokenNode); - + if (exprRight == NULL) return binOpExpression; MEMBER_SET(binOpExpression, mRight, exprRight); @@ -2913,7 +2934,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat { exprLeft = CreateIndexerExpression(exprLeft); } - else if ((token == BfToken_Dot) || (token == BfToken_DotDot) || (token == BfToken_QuestionDot)) + else if ((token == BfToken_Dot) || (token == BfToken_DotDot) || (token == BfToken_QuestionDot) || (token == BfToken_Arrow)) { if ((token == BfToken_DotDot) && ((createExprFlags & CreateExprFlags_BreakOnCascade) != 0)) return exprLeft; @@ -3212,7 +3233,7 @@ BfStatement* BfReducer::CreateForStatement(BfAstNode* node) { // Try to convert 'int i = 0, j = 0` into two variable declarations instead of a var decl and an assignment if (auto prevExprStmt = BfNodeDynCast(initializers.back())) - { + { if (auto prevVarDecl = BfNodeDynCast(prevExprStmt->mExpression)) { if (auto exprStmt = BfNodeDynCast(stmt)) @@ -3547,7 +3568,7 @@ BfSwitchStatement* BfReducer::CreateSwitchStatement(BfTokenNode* tokenNode) token = tokenNode->GetToken(); if ((tokenNode == NULL) || ((token != BfToken_Case) && (token != BfToken_When) && (token != BfToken_Default))) - { + { Fail("Expected 'case'", child); AddErrorNode(child); isDone = !mVisitorPos.MoveNext(); @@ -3596,7 +3617,7 @@ BfSwitchStatement* BfReducer::CreateSwitchStatement(BfTokenNode* tokenNode) whenExpr->mWhenToken = whenToken; ReplaceNode(whenToken, whenExpr); //mVisitorPos.MoveNext(); - //auto exprAfter = wasWhenSet ? (BfAstNode*)switchCase : (BfAstNode*)whenExpr; + //auto exprAfter = wasWhenSet ? (BfAstNode*)switchCase : (BfAstNode*)whenExpr; if (expr == NULL) { auto innerExpr = CreateExpressionAfter(whenToken); @@ -3700,7 +3721,7 @@ BfSwitchStatement* BfReducer::CreateSwitchStatement(BfTokenNode* tokenNode) { int token = tokenNode->GetToken(); if ((token == BfToken_Case) || (token == BfToken_Default) || (token == BfToken_When)) - break; // Done! No fallthrough + break; // Done! No fallthrough } nextNode = mVisitorPos.GetNext(); @@ -3709,7 +3730,7 @@ BfSwitchStatement* BfReducer::CreateSwitchStatement(BfTokenNode* tokenNode) hadEmptyCaseStatement = false; mVisitorPos.MoveNext(); - // We need to use CreateStmtFlags_NoCaseExpr because otherwise during typing a new statement at the end of one case, it + // We need to use CreateStmtFlags_NoCaseExpr because otherwise during typing a new statement at the end of one case, it // could interpret the 'case' token for the next case as being part of a case expression in the first case auto stmt = CreateStatement(nextNode, (CreateStmtFlags)(CreateStmtFlags_FindTrailingSemicolon | CreateStmtFlags_NoCaseExpr | CreateStmtFlags_AllowLocalFunction)); if (stmt == NULL) @@ -4086,7 +4107,7 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS { auto flags = (CreateStmtFlags)(CreateStmtFlags_FindTrailingSemicolon | CreateStmtFlags_ForceVariableDecl); if (token == BfToken_Static) - flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowLocalFunction); + flags = (CreateStmtFlags)(flags | CreateStmtFlags_AllowLocalFunction); auto stmt = CreateStatementAfter(tokenNode, flags); if (auto exprStmt = BfNodeDynCast(stmt)) { @@ -4427,15 +4448,10 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS (unaryOperatorExpr->mOp == BfUnaryOp_Decrement) || (unaryOperatorExpr->mOp == BfUnaryOp_PostDecrement); - if ((unaryOperatorExpr->mOp == BfUnaryOp_Ref) || (unaryOperatorExpr->mOp == BfUnaryOp_Mut) || (unaryOperatorExpr->mOp == BfUnaryOp_Out)) + if (unaryOperatorExpr->mOp == BfUnaryOp_Out) { - if (unaryOperatorExpr->mOp == BfUnaryOp_Ref) - Fail("Cannot use 'ref' in this context", unaryOperatorExpr); - else if (unaryOperatorExpr->mOp == BfUnaryOp_Mut) - Fail("Cannot use 'mut' in this context", unaryOperatorExpr); - else - Fail("Cannot use 'out' in this context", unaryOperatorExpr); - return NULL; + unaryOperatorExpr->mOp = BfUnaryOp_Ref; + Fail("Cannot use 'out' in this context", unaryOperatorExpr); } } @@ -4490,7 +4506,7 @@ bool BfReducer::IsTerminatingExpression(BfAstNode* node) chevronDepth++; break; case BfToken_RChevron: - // If we find a < and > that are not separated by parens, that's a generic, which must be a + // If we find a < and > that are not separated by parens, that's a generic, which must be a // variable decl if it's not in parens if ((parenDepth == 0) && (chevronDepth > 0)) return false; @@ -4981,7 +4997,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF } MEMBER_SET_CHECKED(delegateTypeRef, mCloseParen, closeNode); mVisitorPos.MoveNext(); - + isHandled = true; firstNode = delegateTypeRef; @@ -5004,7 +5020,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF firstNode = declTypeRef; if ((createTypeRefFlags & CreateTypeRefFlags_EarlyExit) != 0) - return declTypeRef; + return declTypeRef; } else if (token == BfToken_LParen) { @@ -5073,7 +5089,7 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF { Fail("Expected type", firstNode); return NULL; - } + } } } @@ -5496,7 +5512,7 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode) auto rightIdentifier = BfNodeDynCast(nextNextToken); if (rightIdentifier == NULL) { - if (auto rightToken = BfNodeDynCast(nextNextToken)) + if (auto rightToken = BfNodeDynCast(nextNextToken)) { if (BfTokenIsKeyword(rightToken->mToken)) { @@ -5504,14 +5520,17 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode) ReplaceNode(rightToken, rightIdentifier); } } - + if (rightIdentifier == NULL) return leftIdentifier; } // If the previous dotted span failed (IE: had chevrons) then don't insert qualified names in the middle of it auto prevNodeToken = BfNodeDynCast(prevNode); - if ((prevNodeToken != NULL) && ((prevNodeToken->GetToken() == BfToken_Dot) || (prevNodeToken->GetToken() == BfToken_QuestionDot))) + if ((prevNodeToken != NULL) && + ((prevNodeToken->GetToken() == BfToken_Dot) || + (prevNodeToken->GetToken() == BfToken_QuestionDot) || + (prevNodeToken->GetToken() == BfToken_Arrow))) return leftIdentifier; mVisitorPos.MoveNext(); // past . @@ -5541,7 +5560,7 @@ void BfReducer::TryIdentifierConvert(int readPos) ReplaceNode(tokenNode, identifierNode); mVisitorPos.Set(readPos, identifierNode); } - } + } } void BfReducer::CreateQualifiedNames(BfAstNode* node) @@ -5666,7 +5685,7 @@ Do_RBracket: mVisitorPos.MoveNext(); } - // Has another one- chain it + // Has another one- chain it auto nextAttribute = CreateAttributeDirective(tokenNode); if (nextAttribute != NULL) { @@ -5681,14 +5700,14 @@ BfStatement* BfReducer::CreateAttributedStatement(BfTokenNode* tokenNode, Create auto attrib = CreateAttributeDirective(tokenNode); if (attrib == NULL) return NULL; - + BfAstNode* stmt = CreateStatementAfter(attrib, createStmtFlags); if (stmt != NULL) - { + { if (auto localMethodDecl = BfNodeDynCastExact(stmt)) { BF_ASSERT(localMethodDecl->mMethodDeclaration->mAttributes == NULL); - localMethodDecl->mSrcStart = attrib->mSrcStart; + localMethodDecl->mSrcStart = attrib->mSrcStart; MEMBER_SET(localMethodDecl->mMethodDeclaration, mAttributes, attrib); return localMethodDecl; } @@ -5730,7 +5749,7 @@ BfExpression* BfReducer::CreateAttributedExpression(BfTokenNode* tokenNode, bool return NULL; if (!onlyAllowIdentifier) - { + { BfExpression* expr = CreateExpressionAfter(attrib, CreateExprFlags_EarlyExit); if (expr != NULL) { @@ -5755,7 +5774,7 @@ BfExpression* BfReducer::CreateAttributedExpression(BfTokenNode* tokenNode, bool MEMBER_SET(attribExpr, mExpression, expr); return attribExpr; } - } + } Fail("Prefixed attributes can only be used on allocations, invocations, blocks, or variable declarations", attrib); @@ -5816,6 +5835,8 @@ BfTokenNode* BfReducer::ReadArguments(BfAstNode* parentNode, BfAstNode* afterNod } } + BfExpression* argumentExpr = NULL; + if (allowSkippedArgs) { auto nextNode = mVisitorPos.GetNext(); @@ -5834,9 +5855,33 @@ BfTokenNode* BfReducer::ReadArguments(BfAstNode* parentNode, BfAstNode* afterNod continue; } } + + if (auto identifierNode = BfNodeDynCastExact(nextNode)) + { + if (auto nextNextToken = BfNodeDynCast(mVisitorPos.Get(mVisitorPos.mReadPos + 2))) + { + if (nextNextToken->mToken == BfToken_Colon) + { + auto namedExpr = mAlloc->Alloc(); + ReplaceNode(identifierNode, namedExpr); + MEMBER_SET(namedExpr, mNameNode, identifierNode); + MEMBER_SET(namedExpr, mColonToken, nextNextToken) + mVisitorPos.MoveNext(); + mVisitorPos.MoveNext(); + + auto innerExpr = CreateExpressionAfter(namedExpr, CreateExprFlags_AllowVariableDecl); + if (innerExpr != NULL) + { + MEMBER_SET(namedExpr, mExpression, innerExpr); + } + argumentExpr = namedExpr; + } + } + } } - auto argumentExpr = CreateExpressionAfter(afterNode, CreateExprFlags_AllowVariableDecl); + if (argumentExpr == NULL) + argumentExpr = CreateExpressionAfter(afterNode, CreateExprFlags_AllowVariableDecl); if ((argumentExpr != NULL) || (endToken != BfToken_None)) arguments->push_back(argumentExpr); if (argumentExpr == NULL) @@ -6105,7 +6150,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i ReplaceNode(tokenNode, ctorDecl); MEMBER_SET(ctorDecl, mThisToken, tokenNode); if (auto block = BfNodeDynCast(mVisitorPos.GetNext())) - { + { mVisitorPos.MoveNext(); MEMBER_SET(ctorDecl, mBody, block); @@ -6303,6 +6348,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i case BfToken_Override: case BfToken_Abstract: case BfToken_Concrete: + case BfToken_Append: case BfToken_Extern: case BfToken_New: case BfToken_Implicit: @@ -6386,11 +6432,12 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i if (auto usingSpecifier = BfNodeDynCastExact(fieldDecl->mConstSpecifier)) { SetProtection(memberDecl, usingSpecifier->mProtection, tokenNode); + usingSpecifier->mTriviaStart = tokenNode->mTriviaStart; return memberDecl; } } - SetProtection(memberDecl, memberDecl->mProtectionSpecifier, tokenNode); + SetProtection(memberDecl, memberDecl->mProtectionSpecifier, tokenNode); return memberDecl; } @@ -6496,7 +6543,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i { if (token == BfToken_Override) { - // Must be typing an 'override' over a field declaration + // Must be typing an 'override' over a field declaration auto propDecl = mAlloc->Alloc(); propDecl->mVirtualSpecifier = tokenNode; typeMember = memberDecl = propDecl; @@ -6518,23 +6565,23 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i handled = true; } -// if (token == BfToken_Using) -// { -// if ((fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const)) -// { -// Fail("Const cannot be used with 'using' specified", tokenNode); -// } -// else if (fieldDecl->mConstSpecifier != NULL) -// { -// Fail("Using already specified", tokenNode); -// } -// -// auto usingSpecifier = mAlloc->Alloc(); -// ReplaceNode(tokenNode, usingSpecifier); -// MEMBER_SET(usingSpecifier, mUsingToken, tokenNode); -// MEMBER_SET(fieldDecl, mConstSpecifier, usingSpecifier); -// handled = true; -// } + if (token == BfToken_Using) + { + if ((fieldDecl->mConstSpecifier != NULL) && (fieldDecl->mConstSpecifier->mToken == BfToken_Const)) + { + Fail("Const cannot be used with 'using' specified", tokenNode); + } + else if (fieldDecl->mConstSpecifier != NULL) + { + Fail("Using already specified", tokenNode); + } + + auto usingSpecifier = mAlloc->Alloc(); + ReplaceNode(tokenNode, usingSpecifier); + MEMBER_SET(usingSpecifier, mUsingToken, tokenNode); + MEMBER_SET(fieldDecl, mConstSpecifier, usingSpecifier); + handled = true; + } if (token == BfToken_ReadOnly) { @@ -6559,6 +6606,30 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i if (token == BfToken_Extern) { + if ((fieldDecl->mExternSpecifier != NULL) && (fieldDecl->mExternSpecifier->mToken == BfToken_Append)) + { + Fail("Extern cannot be used with 'append' specified", tokenNode); + } + else if (fieldDecl->mExternSpecifier != NULL) + { + Fail("Extern already specified", tokenNode); + } + + MEMBER_SET(fieldDecl, mExternSpecifier, tokenNode); + handled = true; + } + + if (token == BfToken_Append) + { + if ((fieldDecl->mExternSpecifier != NULL) && (fieldDecl->mExternSpecifier->mToken == BfToken_Extern)) + { + Fail("Append cannot be used with 'extern' specified", tokenNode); + } + else if (fieldDecl->mExternSpecifier != NULL) + { + Fail("Append already specified", tokenNode); + } + MEMBER_SET(fieldDecl, mExternSpecifier, tokenNode); handled = true; } @@ -6682,10 +6753,10 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf BfAstNode* bodyAfterNode = accessorIdentifier; BfAstNode* body = NULL; - + auto tokenNode = BfNodeDynCast(child); if ((tokenNode != NULL) && (tokenNode->GetToken() == BfToken_Ref) && (accessorName == "set")) - { + { refSpecifier = tokenNode; bodyAfterNode = tokenNode; @@ -6705,8 +6776,8 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf mVisitorPos.MoveNext(); child = mVisitorPos.GetNext(); - } - + } + bool handled = false; BfTokenNode* fatArrowToken = NULL; BfAstNode* endSemicolon = NULL; @@ -6719,7 +6790,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf mVisitorPos.MoveNext(); } else if (tokenNode->mToken == BfToken_FatArrow) - { + { handled = true; fatArrowToken = tokenNode; mVisitorPos.MoveNext(); @@ -6729,9 +6800,9 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf { body = expr; endSemicolon = ExpectTokenAfter(expr, BfToken_Semicolon); - } + } } - } + } if (!handled) { @@ -6745,7 +6816,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf { body = accessorBlock; mVisitorPos.MoveNext(); - } + } if (body == NULL) { if (child != NULL) @@ -6754,7 +6825,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf AddErrorNode(child); mVisitorPos.MoveNext(); } - } + } } } @@ -6782,7 +6853,7 @@ void BfReducer::ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, Bf auto method = mAlloc->Alloc(); method->mPropertyDeclaration = propertyDeclaration; - + if (fatArrowToken != NULL) MEMBER_SET(method, mFatArrowToken, fatArrowToken); if (endSemicolon != NULL) @@ -6820,12 +6891,12 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept BfTokenNode* refToken = NULL; if (auto tokenNode = BfNodeDynCast(node)) - { + { BfToken token = tokenNode->GetToken(); bool isTypeRef = false; if ((token == BfToken_Delegate) || (token == BfToken_Function)) { - // We need to differentiate between a delegate type reference and a delegate type declaration + // We need to differentiate between a delegate type reference and a delegate type declaration int endNodeIdx = -1; if (IsTypeReference(node, BfToken_LParen, -1, &endNodeIdx)) { @@ -6862,7 +6933,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept } else { - SetAndRestoreValue prevTypeMemberNodeStart(mTypeMemberNodeStart, tokenNode, !declStarted); + SetAndRestoreValue prevTypeMemberNodeStart(mTypeMemberNodeStart, tokenNode, !declStarted); return ReadTypeMember(tokenNode, declStarted, depth, deferredHeadNode); } } @@ -6915,7 +6986,6 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept node = typeRef; - auto nextNode = mVisitorPos.GetNext(); if (auto tokenNode = BfNodeDynCast(nextNode)) { @@ -7069,7 +7139,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept } ParseMethod(operatorDecl, ¶ms, &commas); - + if (params.size() == 1) { if (operatorDecl->mBinOp == BfBinaryOp_Add) @@ -7081,7 +7151,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept { operatorDecl->mBinOp = BfBinaryOp_None; operatorDecl->mUnaryOp = BfUnaryOp_Negate; - } + } } return operatorDecl; @@ -7158,7 +7228,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept // If we don't have a token afterwards then still treat it as a property for autocomplete purposes if ((typeRef != NULL) && ((block != NULL) || (tokenNode == NULL) || (isExprBodyProp))) - { + { if (propertyDeclaration == NULL) { if ((block == NULL) && (!isExprBodyProp)) @@ -7178,7 +7248,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept //mVisitorPos.mReadPos--; // WHY did we want to not set this? - // If we don't, then typing a new method name will end up treating the name node as a typeRef + // If we don't, then typing a new method name will end up treating the name node as a typeRef // which can autocomplete incorrectly MEMBER_SET(propDecl, mNameNode, nameIdentifier); @@ -7243,7 +7313,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept if (tokenNode->mToken == BfToken_Mut) { MEMBER_SET(propertyBodyExpr, mMutSpecifier, tokenNode); - tokenNode = ExpectTokenAfter(tokenNode, BfToken_FatArrow); + tokenNode = ExpectTokenAfter(tokenNode, BfToken_FatArrow); } if (tokenNode != NULL) @@ -7306,7 +7376,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept { if (token == BfToken_LChevron) { - bool isTypeRef = IsTypeReference(nameIdentifier, BfToken_LParen); + bool isTypeRef = IsTypeReference(nameIdentifier, BfToken_LParen); if (!isTypeRef) { bool onNewLine = false; @@ -7318,7 +7388,7 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept if (onNewLine) { - // Actually it looks like a partially formed type declaration followed by a method + // Actually it looks like a partially formed type declaration followed by a method // which returns a generic type FailAfter("Name expected", typeRef); @@ -7419,32 +7489,6 @@ BfInvocationExpression* BfReducer::CreateInvocationExpression(BfAstNode* target, { if (nextToken->GetToken() == BfToken_Colon) { - /*auto scopedInvocationTarget = mAlloc->Alloc(); - ReplaceNode(invocationExpr->mTarget, scopedInvocationTarget); - scopedInvocationTarget->mTarget = invocationExpr->mTarget; - invocationExpr->mTarget = scopedInvocationTarget; - MEMBER_SET(scopedInvocationTarget, mColonToken, nextToken); - - mVisitorPos.MoveNext(); - if (auto nextToken = BfNodeDynCast(mVisitorPos.GetNext())) - { - if ((nextToken->GetToken() == BfToken_Colon) || (nextToken->GetToken() == BfToken_Mixin)) - { - MEMBER_SET(scopedInvocationTarget, mScopeName, nextToken); - mVisitorPos.MoveNext(); - } - } - else if (auto identifier = BfNodeDynCast(mVisitorPos.GetNext())) - { - MEMBER_SET(scopedInvocationTarget, mScopeName, identifier); - mVisitorPos.MoveNext(); - } - - if (scopedInvocationTarget->mScopeName == NULL) - { - FailAfter("Expected scope name", scopedInvocationTarget); - }*/ - auto scopedInvocationTarget = CreateScopedInvocationTarget(invocationExpr->mTarget, nextToken); invocationExpr->SetSrcEnd(scopedInvocationTarget->GetSrcEnd()); } @@ -7492,7 +7536,7 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta SetAndRestoreValue prevVisitorPos(mVisitorPos, BfVisitorPos(block)); bool isDone = !mVisitorPos.MoveNext(); - + BfDeferredAstNodeSizedArray values(initializerExpr, initializerExpr->mValues, mAlloc); BfDeferredAstNodeSizedArray commas(initializerExpr, initializerExpr->mCommas, mAlloc); @@ -7524,12 +7568,12 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta } } } - } + } mVisitorPos.Trim(); - + if (block->mCloseBrace != NULL) - MEMBER_SET(initializerExpr, mCloseBrace, block->mCloseBrace); + MEMBER_SET(initializerExpr, mCloseBrace, block->mCloseBrace); return initializerExpr; } @@ -7792,7 +7836,7 @@ bool BfReducer::SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeR ((prevToken->mToken == BfToken_Internal) && (tokenNode->mToken == BfToken_Protected))) { auto tokenPair = mAlloc->Alloc(); - + if (prevToken->mSrcStart < tokenNode->mSrcStart) { ReplaceNode(prevToken, tokenPair); @@ -7812,7 +7856,7 @@ bool BfReducer::SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeR return true; } } - + Fail("Protection already specified", protectionNodeRef); } protectionNodeRef = tokenNode; @@ -7966,7 +8010,6 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken) MEMBER_SET(newNode, mAllocNode, identifier); mVisitorPos.MoveNext(); } - } } @@ -8047,11 +8090,21 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all { SetAndRestoreValue prevVisitorPos(mVisitorPos, BfVisitorPos(block)); ReadArguments(objectCreateExpr, objectCreateExpr, &arguments, &commas, BfToken_None, true); + + while (true) + { + auto nextNode = mVisitorPos.GetNext(); + if (nextNode == NULL) + break; + AddErrorNode(nextNode); + mVisitorPos.MoveNext(); + } } if (block->mCloseBrace != NULL) MEMBER_SET(objectCreateExpr, mCloseToken, block->mCloseBrace); + objectCreateExpr->mSrcEnd = block->mSrcEnd; return objectCreateExpr; - } + } if (isArray) { @@ -8066,13 +8119,13 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all } else { - // Note- if there WERE an LBracket here then we'd have an 'isArray' case. We pass this in here for + // Note- if there WERE an LBracket here then we'd have an 'isArray' case. We pass this in here for // error display purposes tokenNode = ExpectTokenAfter(objectCreateExpr, BfToken_LParen, BfToken_LBracket); if (tokenNode == NULL) return objectCreateExpr; } - + MEMBER_SET(objectCreateExpr, mOpenToken, tokenNode); BfToken endToken = (BfToken)(tokenNode->GetToken() + 1); @@ -8080,7 +8133,7 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all if (tokenNode == NULL) return objectCreateExpr; MEMBER_SET(objectCreateExpr, mCloseToken, tokenNode); - + return objectCreateExpr; } @@ -8114,7 +8167,7 @@ BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target) if (attributeDirective != NULL) { BfAttributedExpression* attribExpr = mAlloc->Alloc(); - ReplaceNode(indexerExpr, attribExpr); + ReplaceNode(indexerExpr, attribExpr); attribExpr->mExpression = indexerExpr; MEMBER_SET(attribExpr, mAttributes, attributeDirective); return attribExpr; @@ -8125,7 +8178,7 @@ BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target) BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNode* target) { - auto tokenNode = ExpectTokenAfter(target, BfToken_Dot, BfToken_DotDot, BfToken_QuestionDot); + auto tokenNode = ExpectTokenAfter(target, BfToken_Dot, BfToken_DotDot, BfToken_QuestionDot, BfToken_Arrow); auto memberReferenceExpr = mAlloc->Alloc(); if (target != NULL) @@ -8279,16 +8332,16 @@ BfAstNode* BfReducer::HandleTopLevel(BfBlock* node) bool hadPrevFail = false; bool isDone = !mVisitorPos.MoveNext(); - + auto parser = mSource->ToParser(); if ((parser != NULL) && (parser->mEmbedKind == BfSourceEmbedKind_Type)) - { + { while (!isDone) { auto node = mVisitorPos.GetCurrent(); if (node == prevNode) - { + { // If we're stuck on an error and can't process any more nodes break; } @@ -8357,7 +8410,7 @@ BfAstNode* BfReducer::HandleTopLevel(BfBlock* node) isDone = !mVisitorPos.MoveNext(); if (newNode != NULL) - mVisitorPos.Write(newNode); + mVisitorPos.Write(newNode); } mVisitorPos.Trim(); return node; @@ -8442,7 +8495,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi break; } } - } + } else if ((bracketDepth > 0) || (parenDepth > 0)) { // Allow @@ -8566,7 +8619,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi bodyNode = ExpectTokenAfter(namespaceDeclaration, BfToken_Semicolon); else bodyNode = blockNode = ExpectBlockAfter(namespaceDeclaration); - + if (bodyNode == NULL) return namespaceDeclaration; MoveNode(bodyNode, namespaceDeclaration); @@ -8592,7 +8645,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi FailAfter("Expected type declaration", tokenNode); return NULL; } - + mVisitorPos.MoveNext(); auto topLevelObject = CreateTopLevelObject(nextToken, attributes); if (topLevelObject == NULL) @@ -8613,7 +8666,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi break; case BfToken_Sealed: - case BfToken_Abstract: + case BfToken_Abstract: case BfToken_Public: case BfToken_Private: case BfToken_Protected: @@ -8646,7 +8699,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi return NULL; } mVisitorPos.MoveNext(); - + auto topLevelObject = CreateTopLevelObject(nextToken, attributes); if (topLevelObject == NULL) { @@ -8670,7 +8723,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi (token == BfToken_Private) || (token == BfToken_Internal)) { - SetProtection(typeDeclaration, typeDeclaration->mProtectionSpecifier, tokenNode); + SetProtection(typeDeclaration, typeDeclaration->mProtectionSpecifier, tokenNode); } if (token == BfToken_Static) @@ -8761,8 +8814,6 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi //MEMBER_SET(methodDecl, mReturnType, retType); - - return typeDeclaration; } break; @@ -8900,15 +8951,22 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi { if (tokenNode->mToken == BfToken_This) { - mVisitorPos.MoveNext(); + mVisitorPos.MoveNext(); auto ctorDecl = mAlloc->Alloc(); BfDeferredAstSizedArray params(ctorDecl->mParams, mAlloc); BfDeferredAstSizedArray commas(ctorDecl->mCommas, mAlloc); ctorDecl->mReturnType = NULL; ReplaceNode(tokenNode, ctorDecl); - MEMBER_SET(ctorDecl, mThisToken, tokenNode); + MEMBER_SET(ctorDecl, mThisToken, tokenNode); ParseMethod(ctorDecl, ¶ms, &commas); - + + if (!baseClassCommas.IsEmpty()) + { + ctorDecl->mPrefix = baseClassCommas.back(); + baseClassCommas.pop_back(); + ctorDecl->mSrcStart = ctorDecl->mPrefix->mSrcStart; + } + if (typeDeclaration->mAutoCtor == NULL) { MEMBER_SET(typeDeclaration, mAutoCtor, ctorDecl); @@ -9037,7 +9095,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi if (child == NULL) break; auto fieldDecl = mAlloc->Alloc(); - + if (auto tokenNode = BfNodeDynCast(child)) { if (tokenNode->mToken == BfToken_LBracket) @@ -9053,7 +9111,7 @@ BfAstNode* BfReducer::CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDi break; } } - } + } mVisitorPos.MoveNext(); mVisitorPos.Write(fieldDecl); @@ -9290,7 +9348,7 @@ BfCommentNode * BfReducer::FindDocumentation(BfAstNode* defNodeHead, BfAstNode* return NULL; } - if ((checkComment->mCommentKind != BfCommentKind_Documentation_Line_Pre) && + if ((checkComment->mCommentKind != BfCommentKind_Documentation_Line_Pre) && (checkComment->mCommentKind != BfCommentKind_Documentation_Block_Pre)) { // Skip this, not used @@ -9348,6 +9406,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImplmSrcEnd = paramDecl->mSrcEnd; auto nextNode = mVisitorPos.GetNext(); tokenNode = BfNodeDynCast(nextNode); if (tokenNode == NULL) @@ -9362,6 +9421,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImplmTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function)) isFunction = true; else if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate)) @@ -9665,13 +9726,13 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImplmNameNode = nameIdentifierNode; MoveNode(nameIdentifierNode, paramDecl); - nameAfterNode = nameIdentifierNode; - } + nameAfterNode = nameIdentifierNode; + } } node->mSrcEnd = paramDecl->mSrcEnd; @@ -9740,7 +9801,7 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm methodDeclaration->mCloseParen = ParseMethodParams(methodDeclaration, params, commas, BfToken_RParen, true); - // RParen + // RParen if (methodDeclaration->mCloseParen == NULL) { auto nextNode = mVisitorPos.GetNext(); @@ -9845,7 +9906,7 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm if (ctorDecl->mInitializer != NULL) { MEMBER_SET(attribExpr, mExpression, ctorDecl->mInitializer); - } + } MEMBER_SET(ctorDecl, mInitializer, attribExpr); } } @@ -10058,44 +10119,44 @@ BfGenericConstraintsDeclaration* BfReducer::CreateGenericConstraintsDeclaration( // ReplaceNode(tokenNode, genericConstraint); // genericConstraint->mWhereToken = tokenNode; // constraintsDeclaration->mHasExpressions = true; -// +// // genericConstraintsArr.push_back(genericConstraint); -// +// // auto expr = CreateExpressionAfter(genericConstraint, CreateExprFlags_EarlyExit); // if (expr == NULL) // break; -// -// MEMBER_SET(genericConstraint, mExpression, expr); -// +// +// MEMBER_SET(genericConstraint, mExpression, expr); +// // BfTokenNode* nextWhereToken = NULL; // if (auto checkToken = BfNodeDynCast(mVisitorPos.GetNext())) // { // if (checkToken->mToken != BfToken_Where) // nextWhereToken = checkToken; // } -// +// // auto nextNode = mVisitorPos.GetNext(); -// if (BfNodeDynCast(nextNode)) -// break; -// +// if (BfNodeDynCast(nextNode)) +// break; +// // bool handled = false; // if (auto tokenNode = BfNodeDynCast(nextNode)) // { -// if (tokenNode->mToken == BfToken_FatArrow) -// break; +// if (tokenNode->mToken == BfToken_FatArrow) +// break; // } -// +// // tokenNode = ExpectTokenAfter(genericConstraint, BfToken_LBrace, BfToken_Where, BfToken_Semicolon); -// if (tokenNode == NULL) +// if (tokenNode == NULL) // break; -// +// // BfToken token = tokenNode->GetToken(); -// if (token != BfToken_Where) -// { +// if (token != BfToken_Where) +// { // mVisitorPos.mReadPos--; // break; // } -// +// // continue; // } // } @@ -10107,7 +10168,7 @@ BfGenericConstraintsDeclaration* BfReducer::CreateGenericConstraintsDeclaration( ReplaceNode(tokenNode, genericConstraint); genericConstraint->mWhereToken = tokenNode; - genericConstraintsArr.push_back(genericConstraint); + genericConstraintsArr.push_back(genericConstraint); auto genericParamName = CreateTypeRefAfter(genericConstraint); if (genericParamName != NULL) @@ -10143,7 +10204,7 @@ BfGenericConstraintsDeclaration* BfReducer::CreateGenericConstraintsDeclaration( { isDone = true; break; - } + } } tokenNode = ExpectTokenAfter(genericConstraint, BfToken_Comma, BfToken_LBrace, BfToken_Where, BfToken_Semicolon); @@ -10897,4 +10958,4 @@ BfInlineAsmStatement* BfReducer::CreateInlineAsmStatement(BfAstNode* asmNode) } return asmStatement; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfReducer.h b/IDEHelper/Compiler/BfReducer.h index 01b2ed9d..5b2ec940 100644 --- a/IDEHelper/Compiler/BfReducer.h +++ b/IDEHelper/Compiler/BfReducer.h @@ -36,8 +36,8 @@ public: CreateStmtFlags_NoCaseExpr = 1, CreateStmtFlags_FindTrailingSemicolon = 2, CreateStmtFlags_AllowUnterminatedExpression = 4, - CreateStmtFlags_AllowLocalFunction = 8, - CreateStmtFlags_ForceVariableDecl = 0x10, + CreateStmtFlags_AllowLocalFunction = 8, + CreateStmtFlags_ForceVariableDecl = 0x10, CreateStmtFlags_To_CreateExprFlags_Mask = 1 }; @@ -127,7 +127,7 @@ public: } }; -public: +public: BfAstAllocator* mAlloc; BfSystem* mSystem; BfSource* mSource; @@ -141,12 +141,12 @@ public: BfMethodDeclaration* mCurMethodDecl; BfAstNode* mLastBlockNode; bool mStmtHasError; - bool mPrevStmtHadError; + bool mPrevStmtHadError; bool mCompatMode; // Does C++ compatible parsing bool mAllowTypeWildcard; bool mIsFieldInitializer; bool mInParenExpr; - bool mSkipCurrentNodeAssert; + bool mSkipCurrentNodeAssert; BfVisitorPos mVisitorPos; int mDocumentCheckIdx; SizedArray mCurNamespaceStack; @@ -154,15 +154,15 @@ public: int mAssertCurrentNodeIdx; -public: +public: BfAstNode* Fail(const StringImpl& errorMsg, BfAstNode* refNode); BfAstNode* FailAfter(const StringImpl& errorMsg, BfAstNode* refNode); void AddErrorNode(BfAstNode* astNode, bool removeNode = true); - -public: + +public: bool StringEquals(BfAstNode* node, BfAstNode* node2); bool IsSemicolon(BfAstNode* node); - BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token); + BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token); BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB); BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC); BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC, BfToken tokenD); @@ -176,8 +176,8 @@ public: bool IsNodeRelevant(BfAstNode* astNode); bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode); void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner); - void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode); - + void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode); + bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode); BfAstNode* CreateAllocNode(BfTokenNode* newNode); BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false); @@ -195,12 +195,12 @@ public: void CreateQualifiedNames(BfAstNode* node); BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode); BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration); - BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken); + BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken); BfStatement* CreateAttributedStatement(BfTokenNode* tokenNode, CreateStmtFlags createStmtFlags = CreateStmtFlags_None); BfExpression* CreateAttributedExpression(BfTokenNode* tokenNode, bool onlyAllowIdentifier); BfDelegateBindExpression* CreateDelegateBindExpression(BfAstNode* allocNode); BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL); - BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block); + BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block); BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken); BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode); BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken); @@ -225,7 +225,7 @@ public: BfTypeReference* DoCreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None, int endNode = -1); BfTypeReference* CreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None); BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None); - BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken); + BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken); bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl* params, SizedArrayImpl* commas, bool alwaysIncludeBlock = false); BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial = false); BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode); diff --git a/IDEHelper/Compiler/BfResolvePass.cpp b/IDEHelper/Compiler/BfResolvePass.cpp index 5474cd2d..725a4cb3 100644 --- a/IDEHelper/Compiler/BfResolvePass.cpp +++ b/IDEHelper/Compiler/BfResolvePass.cpp @@ -1,14 +1,14 @@ -#include "BfResolvePass.h" +#include "BfResolvePass.h" #include "BfParser.h" #include "BfModule.h" USING_NS_BF; BfResolvePassData::BfResolvePassData() -{ +{ mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None; - mSymbolReferenceTypeDef = NULL; + mSymbolReferenceTypeDef = NULL; mSymbolReferenceLocalIdx = -1; mSymbolReferenceFieldIdx = -1; @@ -31,7 +31,7 @@ BfResolvePassData::~BfResolvePassData() auto parser = emitEntryKV.mValue.mParser; if (parser != NULL) { - delete parser->mSourceClassifier; + delete parser->mSourceClassifier; parser->mSourceClassifier = NULL; parser->mParserFlags = ParserFlag_None; parser->mCursorCheckIdx = -1; @@ -56,7 +56,7 @@ void BfResolvePassData::RecordReplaceNode(BfAstNode* node) auto parser = node->GetSourceData()->ToParserData(); if (node->GetSrcStart() >= parser->mSrcLength) return; - + while (true) { if (auto qualifiedName = BfNodeDynCast(node)) @@ -65,35 +65,35 @@ void BfResolvePassData::RecordReplaceNode(BfAstNode* node) } else break; - } + } RecordReplaceNode(parser, node->GetSrcStart(), node->GetSrcLength()); } void BfResolvePassData::HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferenceMethodIdx == methodDef->mIdx)) RecordReplaceNode(node); } void BfResolvePassData::HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferenceFieldIdx == fieldDef->mIdx)) RecordReplaceNode(node); } void BfResolvePassData::HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferencePropertyIdx == propDef->mIdx)) RecordReplaceNode(node); } void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx)) RecordReplaceNode(identifier); } @@ -106,14 +106,14 @@ void BfResolvePassData::HandleTypeGenericParam(BfAstNode* node, BfTypeDef* typeD void BfResolvePassData::HandleMethodGenericParam(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef, int genericParamIdx) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (genericParamIdx == mSymbolMethodGenericParamIdx)) RecordReplaceNode(node); } void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx) { - if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && + if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef->GetDefinition()) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx)) { if (origNameNode == NULL) @@ -122,7 +122,7 @@ void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIde int origLen = origNameNode->GetSrcLength(); int refLen = identifier->GetSrcLength(); - // The lengths can be different if we have one or more @'s prepended + // The lengths can be different if we have one or more @'s prepended RecordReplaceNode(identifier->GetSourceData()->ToParserData(), identifier->GetSrcStart() + (refLen - origLen), origLen); } } @@ -215,4 +215,4 @@ BfSourceClassifier* BfResolvePassData::GetSourceClassifier(BfParser* parser) if (parser == NULL) return NULL; return parser->mSourceClassifier; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfResolvePass.h b/IDEHelper/Compiler/BfResolvePass.h index 66dc4639..da95812e 100644 --- a/IDEHelper/Compiler/BfResolvePass.h +++ b/IDEHelper/Compiler/BfResolvePass.h @@ -14,7 +14,7 @@ enum BfResolveType BfResolveType_Autocomplete, BfResolveType_Autocomplete_HighPri, BfResolveType_GoToDefinition, - BfResolveType_GetSymbolInfo, + BfResolveType_GetSymbolInfo, BfResolveType_RenameSymbol, BfResolveType_ShowFileSymbolReferences, BfResolveType_GetNavigationData, @@ -64,17 +64,18 @@ public: BfResolveType mResolveType; Array mParsers; + Dictionary mCompatParserMap; BfAutoComplete* mAutoComplete; Array mAutoCompleteTempTypes; // Contains multiple values when we have nested types Dictionary mStaticSearchMap; - Dictionary mInternalAccessMap; + Dictionary mInternalAccessMap; Array mExteriorAutocompleteCheckNodes; - BfGetSymbolReferenceKind mGetSymbolReferenceKind; + BfGetSymbolReferenceKind mGetSymbolReferenceKind; String mQueuedReplaceTypeDef; BfTypeDef* mSymbolReferenceTypeDef; String mQueuedSymbolReferenceNamespace; - BfAtomComposite mSymbolReferenceNamespace; + BfAtomComposite mSymbolReferenceNamespace; int mSymbolReferenceLocalIdx; int mSymbolReferenceFieldIdx; int mSymbolReferenceMethodIdx; @@ -84,7 +85,7 @@ public: bool mIsClassifying; bool mHasCursorIdx; bool mHadEmits; - + typedef Dictionary FoundSymbolReferencesParserDataMap; FoundSymbolReferencesParserDataMap mFoundSymbolReferencesParserData; //std::vector mSymbolReferenceIdentifiers; @@ -93,7 +94,7 @@ public: public: void RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen); - void RecordReplaceNode(BfAstNode* node); + void RecordReplaceNode(BfAstNode* node); BfAstNode* FindBaseNode(BfAstNode* node); public: @@ -107,7 +108,7 @@ public: void HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef); void HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef); void HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef); - void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef); + void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef); void HandleNamespaceReference(BfAstNode* node, const BfAtomComposite& namespaceName); BfSourceClassifier* GetSourceClassifier(BfAstNode* astNode); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index f10f7037..2c2b15e3 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -42,7 +42,7 @@ void BfTypedValue::DbgCheckType() const BF_ASSERT(strncmp(stringRef.data(), "DEAD", 4) != 0); } }*/ - + #ifdef _DEBUG /*if (mValue != NULL) { @@ -58,8 +58,127 @@ bool BfTypedValue::IsValuelessType() const } bool BfTypedValue::CanModify() const -{ - return (((IsAddr()) || (mType->IsValuelessType())) && (!IsReadOnly())); +{ + return (((IsAddr()) || (mType->IsValuelessType())) && (!IsReadOnly())); +} + +////////////////////////////////////////////////////////////////////////// + +BfProtection BfUsingFieldData::MemberRef::GetProtection() const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->mProtection; + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->mProtection; + case Kind_Method: + return mTypeInstance->mTypeDef->mMethods[mIdx]->mProtection; + } + return BfProtection_Public; +} + +BfProtection BfUsingFieldData::MemberRef::GetUsingProtection() const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->mUsingProtection; + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->mUsingProtection; + case Kind_Method: + return mTypeInstance->mTypeDef->mMethods[mIdx]->mProtection; + } + return BfProtection_Public; +} + +BfTypeDef* BfUsingFieldData::MemberRef::GetDeclaringType(BfModule* curModule) const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->mDeclaringType; + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->mDeclaringType; + case Kind_Method: + return mTypeInstance->mTypeDef->mMethods[mIdx]->mDeclaringType; + case Kind_Local: + return curModule->GetActiveTypeDef(); + } + return NULL; +} + +String BfUsingFieldData::MemberRef::GetFullName(BfModule* curModule) const +{ + if (mKind == Kind_Local) + return curModule->mCurMethodState->mLocals[mIdx]->mName; + + String result = curModule->TypeToString(mTypeInstance); + if (!result.IsEmpty()) + result += "."; + + switch (mKind) + { + case Kind_Field: + result += mTypeInstance->mTypeDef->mFields[mIdx]->mName; + break; + case Kind_Property: + result += mTypeInstance->mTypeDef->mProperties[mIdx]->mName; + break; + case Kind_Method: + result += mTypeInstance->mTypeDef->mMethods[mIdx]->mName; + break; + } + return result; +} + +String BfUsingFieldData::MemberRef::GetName(BfModule* curModule) const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->mName; + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->mName; + case Kind_Method: + { + auto methodInstance = curModule->GetRawMethodInstance(mTypeInstance, mTypeInstance->mTypeDef->mMethods[mIdx]); + return curModule->MethodToString(methodInstance, BfMethodNameFlag_OmitTypeName); + } + case Kind_Local: + return curModule->mCurMethodState->mLocals[mIdx]->mName; + } + return ""; +} + +BfAstNode* BfUsingFieldData::MemberRef::GetRefNode(BfModule* curModule) const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->GetRefNode(); + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->GetRefNode(); + case Kind_Method: + return mTypeInstance->mTypeDef->mMethods[mIdx]->GetRefNode(); + case Kind_Local: + return curModule->mCurMethodState->mLocals[mIdx]->mNameNode; + } + return NULL; +} + +bool BfUsingFieldData::MemberRef::IsStatic() const +{ + switch (mKind) + { + case Kind_Field: + return mTypeInstance->mTypeDef->mFields[mIdx]->mIsStatic; + case Kind_Property: + return mTypeInstance->mTypeDef->mProperties[mIdx]->mIsStatic; + case Kind_Method: + return mTypeInstance->mTypeDef->mMethods[mIdx]->mIsStatic; + } + return false; } ////////////////////////////////////////////////////////////////////////// @@ -81,10 +200,10 @@ bool BfGenericParamInstance::IsEnum() ////////////////////////////////////////////////////////////////////////// bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::DependencyFlags flags) -{ +{ BF_ASSERT(dependentType != NULL); BF_ASSERT(dependentType->mRevision != -1); - + //auto itr = mTypeSet.insert(BfDependencyMap::TypeMap::value_type(dependentType, DependencyEntry(dependentType->mRevision, flags))); //if (!itr.second) @@ -100,7 +219,7 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen mMinDependDepth = tryDepth; } } - + dependencyEntry->mRevision = dependentType->mRevision; dependencyEntry->mFlags = flags; return true; @@ -108,13 +227,13 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen else { if (dependencyEntry->mRevision != dependentType->mRevision) - { + { dependencyEntry->mRevision = dependentType->mRevision; dependencyEntry->mFlags = flags; return true; } else - { + { if ((dependencyEntry->mFlags & flags) == flags) return false; dependencyEntry->mFlags = (DependencyFlags)(dependencyEntry->mFlags | flags); @@ -155,27 +274,26 @@ BfFieldDef* BfFieldInstance::GetFieldDef() ////////////////////////////////////////////////////////////////////////// BfType::BfType() -{ - mTypeId = -1; +{ + mTypeId = -1; mContext = NULL; mRevision = -1; - + //mLastUsedRevision = -1; - mDefineState = BfTypeDefineState_Undefined; - //mDICallbackVH = NULL; - //mInnerDICallbackVH = NULL; - mRebuildFlags = BfTypeRebuildFlag_None; - mAlign = -1; - mSize = -1; //mDICallbackVH = NULL; //mInnerDICallbackVH = NULL; - mDirty = true; + mRebuildFlags = BfTypeRebuildFlag_None; + mAlign = -1; + mSize = -1; + //mDICallbackVH = NULL; + //mInnerDICallbackVH = NULL; + mDirty = true; } BfModule* BfType::GetModule() -{ +{ if (mContext->mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude) return mContext->mScratchModule; else @@ -229,7 +347,7 @@ BfMethodInstance* BfNonGenericMethodRef::operator->() const } BfNonGenericMethodRef& BfNonGenericMethodRef::operator=(BfMethodInstance* methodInstance) -{ +{ if (methodInstance == NULL) { mTypeInstance = NULL; @@ -239,7 +357,7 @@ BfNonGenericMethodRef& BfNonGenericMethodRef::operator=(BfMethodInstance* method { mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner; mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx; - BF_ASSERT((methodInstance->GetNumGenericArguments() == 0) || + BF_ASSERT((methodInstance->GetNumGenericArguments() == 0) || ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation))); mSignatureHash = (int)mTypeInstance->mTypeDef->mSignatureHash; } @@ -296,7 +414,7 @@ BfMethodRef::operator BfMethodInstance* () const isSpecialied = true; break; } - + auto genericParam = (BfGenericParamType*)genericArg; if ((genericParam->mGenericParamKind != BfGenericParamKind_Method) || (genericParam->mGenericParamIdx != paramIdx)) { @@ -308,7 +426,7 @@ BfMethodRef::operator BfMethodInstance* () const } if (isSpecialied) - { + { BfMethodInstance** methodInstancePtr = NULL; if (methodSpecializationGroup.mMethodSpecializationMap->TryGetValue(mMethodGenericArguments, &methodInstancePtr)) return *methodInstancePtr; @@ -333,7 +451,7 @@ BfMethodRef& BfMethodRef::operator=(BfMethodInstance* methodInstance) mMethodRefFlags = BfMethodRefFlag_None; } else - { + { mTypeInstance = methodInstance->mMethodInstanceGroup->mOwner; mMethodNum = methodInstance->mMethodInstanceGroup->mMethodIdx; if (methodInstance->mMethodInfoEx != NULL) @@ -412,11 +530,10 @@ BfPropertyRef::BfPropertyRef(BfTypeInstance* typeInst, BfPropertyDef* propDef) } BfPropertyRef::operator BfPropertyDef*() const -{ +{ return mTypeInstance->mTypeDef->mProperties[mPropIdx]; } - ////////////////////////////////////////////////////////////////////////// /*BfMethodInstance* BfTypeInstance::GetVTableMethodInstance(int vtableIdx) @@ -428,7 +545,7 @@ BfPropertyRef::operator BfPropertyDef*() const static int gDelIdx = 0; BfType::~BfType() -{ +{ if (mContext != NULL) BfLogSys(mContext->mSystem, "~BfType %p\n", this); @@ -447,16 +564,16 @@ BfFieldInstance::~BfFieldInstance() BfType* BfFieldInstance::GetResolvedType() { - return mResolvedType; + return mResolvedType; } void BfFieldInstance::SetResolvedType(BfType* type) -{ +{ mResolvedType = type; } void BfFieldInstance::GetDataRange(int& dataIdx, int& dataCount) -{ +{ int minMergedDataIdx = mMergedDataIdx; int maxMergedDataIdx = minMergedDataIdx + 1; if (mResolvedType->IsStruct()) @@ -498,13 +615,15 @@ void BfFieldInstance::GetDataRange(int& dataIdx, int& dataCount) int BfFieldInstance::GetAlign(int packing) { int align = mResolvedType->mAlign; + if (IsAppendedObject()) + align = mResolvedType->ToTypeInstance()->mInstAlign; if (packing > 0) align = BF_MIN(align, packing); if (mCustomAttributes != NULL) { auto module = mOwner->mModule; for (auto& attrib : mCustomAttributes->mAttributes) - { + { if (attrib.mType->IsInstanceOf(module->mCompiler->mAlignAttributeTypeDef)) { align = 16; // System conservative default @@ -522,12 +641,18 @@ int BfFieldInstance::GetAlign(int packing) module->Fail("Alignment must be a power of 2", attrib.GetRefNode()); } } - } + } } } return align; } +bool BfFieldInstance::IsAppendedObject() +{ + auto fieldDef = GetFieldDef(); + return (fieldDef != NULL) && (fieldDef->mIsAppend) && (mResolvedType->IsObject()) && (mOwner->IsObject()); +} + ////////////////////////////////////////////////////////////////////////// int64 BfDeferredMethodCallData::GenerateMethodId(BfModule* module, int64 methodId) @@ -568,6 +693,12 @@ BfMethodCustomAttributes::~BfMethodCustomAttributes() BfMethodInstance* BfMethodParam::GetDelegateParamInvoke() { + if (mResolvedType->IsMethodRef()) + { + auto methodRefType = (BfMethodRefType*)mResolvedType; + return methodRefType->mMethodRef; + } + BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction()); auto bfModule = BfModule::GetModuleFor(mResolvedType); BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke"); @@ -577,13 +708,13 @@ BfMethodInstance* BfMethodParam::GetDelegateParamInvoke() BfMethodInfoEx::~BfMethodInfoEx() { for (auto genericParam : mGenericParams) - genericParam->Release(); + genericParam->Release(); delete mMethodCustomAttributes; delete mClosureInstanceInfo; } BfMethodInstance::~BfMethodInstance() -{ +{ Dispose(true); if (mHasMethodRefType) @@ -596,7 +727,7 @@ BfMethodInstance::~BfMethodInstance() } } - delete mMethodInfoEx; + delete mMethodInfoEx; } void BfMethodInstance::Dispose(bool isDeleting) @@ -604,7 +735,7 @@ void BfMethodInstance::Dispose(bool isDeleting) if (mIsDisposed) return; mIsDisposed = true; - + if (mMethodInstanceGroup != NULL) { BfLogSys(GetOwner()->mModule->mSystem, "BfMethodInstance::~BfMethodInstance %p Local:%d InCEMachine:%d Deleting:%d\n", this, mMethodDef->mIsLocalMethod, mInCEMachine, isDeleting); @@ -619,7 +750,7 @@ void BfMethodInstance::Dispose(bool isDeleting) auto module = GetOwner()->mModule; if (module->mCompiler->mCeMachine != NULL) module->mCompiler->mCeMachine->RemoveMethod(this); - } + } if (mMethodProcessRequest != NULL) { @@ -644,7 +775,7 @@ void BfMethodInstance::CopyFrom(BfMethodInstance* methodInstance) for (auto genericParam : mMethodInfoEx->mGenericParams) genericParam->AddRef(); mMethodInfoEx->mMethodCustomAttributes = NULL; - + if (mMethodInfoEx->mClosureInstanceInfo != NULL) { mMethodInfoEx->mClosureInstanceInfo = new BfClosureInstanceInfo(); @@ -667,7 +798,7 @@ BfImportKind BfMethodInstance::GetImportKind() auto customAttributes = GetCustomAttributes(); if (customAttributes == NULL) return BfImportKind_None; - + BfCustomAttribute* customAttribute = customAttributes->Get(module->mCompiler->mImportAttributeTypeDef); if (customAttribute == NULL) return BfImportKind_Import_Static; @@ -716,10 +847,10 @@ void BfMethodInstance::UndoDeclaration(bool keepIRFunction) if (mMethodInfoEx != NULL) { for (auto genericParam : mMethodInfoEx->mGenericParams) - genericParam->Release(); + genericParam->Release(); mMethodInfoEx->mGenericParams.Clear(); delete mMethodInfoEx->mMethodCustomAttributes; - mMethodInfoEx->mMethodCustomAttributes = NULL; + mMethodInfoEx->mMethodCustomAttributes = NULL; mMethodInfoEx->mGenericTypeBindings.Clear(); } @@ -727,7 +858,7 @@ void BfMethodInstance::UndoDeclaration(bool keepIRFunction) if (!keepIRFunction) mIRFunction = BfIRValue(); mParams.Clear(); - + mDefaultValues.Clear(); if (mMethodProcessRequest != NULL) { @@ -740,7 +871,7 @@ void BfMethodInstance::UndoDeclaration(bool keepIRFunction) mIsUnspecialized = false; mIsUnspecializedVariation = false; mDisallowCalling = false; - mIsIntrinsic = false; + mIsIntrinsic = false; mHasFailed = false; mFailedConstraints = false; } @@ -810,7 +941,7 @@ bool BfMethodInstance::HasParamsArray() } int BfMethodInstance::GetStructRetIdx(bool forceStatic) -{ +{ if ((mReturnType->IsComposite()) && (!mReturnType->IsValuelessType()) && (!GetLoweredReturnType(NULL, NULL, forceStatic)) && (!mIsIntrinsic)) { auto returnTypeInst = mReturnType->ToTypeInstance(); @@ -829,7 +960,7 @@ int BfMethodInstance::GetStructRetIdx(bool forceStatic) return 1; if ((mMethodDef->mIsMutating) || (!thisType->IsSplattable()) || ((!AllowsSplatting(-1)) && (!thisType->GetLoweredType(BfTypeUsage_Parameter)))) return 1; - return 0; + return 0; } return -1; @@ -848,7 +979,7 @@ bool BfMethodInstance::HasSelf() bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeCode* loweredTypeCode2, bool forceStatic) { // Win32 handler - if (((mMethodDef->mIsStatic) || (forceStatic)) && + if (((mMethodDef->mIsStatic) || (forceStatic)) && (mReturnType->IsComposite()) && ((mReturnType->mSize == 4) || (mReturnType->mSize == 8))) { @@ -870,7 +1001,7 @@ bool BfMethodInstance::GetLoweredReturnType(BfTypeCode* loweredTypeCode, BfTypeC } } - return mReturnType->GetLoweredType((mMethodDef->mIsStatic || forceStatic) ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2); + return mReturnType->GetLoweredType((mMethodDef->mIsStatic || forceStatic) ? BfTypeUsage_Return_Static : BfTypeUsage_Return_NonStatic, loweredTypeCode, loweredTypeCode2); } bool BfMethodInstance::WantsStructsAttribByVal(BfType* paramType) @@ -886,8 +1017,8 @@ bool BfMethodInstance::WantsStructsAttribByVal(BfType* paramType) } bool BfMethodInstance::IsSkipCall(bool bypassVirtual) -{ - if ((mMethodDef->mIsSkipCall) && +{ + if ((mMethodDef->mIsSkipCall) && ((!mMethodDef->mIsVirtual) || (bypassVirtual))) return true; return false; @@ -908,7 +1039,7 @@ bool BfMethodInstance::AlwaysInline() BfImportCallKind BfMethodInstance::GetImportCallKind() { if (GetImportKind() != BfImportKind_Import_Dynamic) - return BfImportCallKind_None; + return BfImportCallKind_None; if ((mHotMethod != NULL) && ((mHotMethod->mFlags & BfHotDepDataFlag_IsOriginalBuild) == 0)) return BfImportCallKind_GlobalVar_Hot; return BfImportCallKind_GlobalVar; @@ -947,7 +1078,7 @@ bool BfMethodInstance::AllowsSplatting(int paramIdx) bool BfMethodInstance::HasThis() { if (mMethodDef->mIsStatic) - return false; + return false; if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL)) return !mMethodInfoEx->mClosureInstanceInfo->mThisOverride->IsValuelessType(); return (!mMethodInstanceGroup->mOwner->IsValuelessType()); @@ -985,7 +1116,7 @@ bool BfMethodInstance::HasExplicitThis() { if (mMethodDef->mIsStatic) return false; - return mMethodInstanceGroup->mOwner->IsFunction(); + return mMethodInstanceGroup->mOwner->IsFunction(); } int BfMethodInstance::GetParamCount() @@ -1034,7 +1165,7 @@ void BfMethodInstance::GetParamName(int paramIdx, StringImpl& name, int& namePre } String BfMethodInstance::GetParamName(int paramIdx) -{ +{ StringT<256> paramName; int namePrefixCount = 0; GetParamName(paramIdx, paramName, namePrefixCount); @@ -1049,7 +1180,7 @@ String BfMethodInstance::GetParamName(int paramIdx, int& namePrefixCount) } BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParamsType) -{ +{ if (paramIdx == -1) { if ((mMethodInfoEx != NULL) && (mMethodInfoEx->mClosureInstanceInfo != NULL) && (mMethodInfoEx->mClosureInstanceInfo->mThisOverride != NULL)) @@ -1066,9 +1197,9 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool returnUnderlyingParams return thisType; } - BfMethodParam* methodParam = &mParams[paramIdx]; + BfMethodParam* methodParam = &mParams[paramIdx]; if (methodParam->mDelegateParamIdx != -1) - { + { BfMethodInstance* invokeMethodInstance = methodParam->GetDelegateParamInvoke(); return invokeMethodInstance->GetParamType(methodParam->mDelegateParamIdx, true); } @@ -1097,7 +1228,7 @@ bool BfMethodInstance::GetParamIsSplat(int paramIdx) if ((owner->IsValueType()) && (mMethodDef->mIsMutating || !AllowsSplatting(paramIdx))) return false; return owner->mIsSplattable; - } + } BfMethodParam* methodParam = &mParams[paramIdx]; if (methodParam->mDelegateParamIdx != -1) @@ -1138,7 +1269,7 @@ bool BfMethodInstance::IsParamSkipped(int paramIdx) GetModule()->PopulateType(paramType, BfPopulateType_Data); if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef())) return true; - return false; + return false; } bool BfMethodInstance::IsImplicitCapture(int paramIdx) @@ -1147,7 +1278,7 @@ bool BfMethodInstance::IsImplicitCapture(int paramIdx) return false; BfMethodParam* methodParam = &mParams[paramIdx]; if (methodParam->mParamDefIdx == -1) - return true; + return true; return false; } @@ -1239,7 +1370,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, module->PopulateType(mReturnType); BfTypeCode loweredReturnTypeCode = BfTypeCode_None; - BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; + BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None; if ((!module->mIsComptimeModule) && (GetLoweredReturnType(&loweredReturnTypeCode, &loweredReturnTypeCode2, forceStatic)) && (loweredReturnTypeCode != BfTypeCode_None)) { auto irReturnType = module->GetIRLoweredType(loweredReturnTypeCode, loweredReturnTypeCode2); @@ -1268,7 +1399,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, else { returnType = module->mBfIRBuilder->MapType(mReturnType); - } + } for (int paramIdx = -1; paramIdx < GetParamCount(); paramIdx++) { @@ -1286,7 +1417,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, if (HasExplicitThis()) checkType = GetParamType(0); else - checkType = GetOwner(); + checkType = GetOwner(); } } else @@ -1302,7 +1433,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, NOP; }*/ - bool checkLowered = false; + bool checkLowered = false; bool doSplat = false; if (paramIdx == -1) { @@ -1318,7 +1449,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, checkLowered = true; } else - { + { if ((checkType->IsComposite()) && (checkType->IsIncomplete())) module->PopulateType(checkType, BfPopulateType_Data); @@ -1349,17 +1480,17 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, if (loweredTypeCode2 != BfTypeCode_None) paramTypes.push_back(module->mBfIRBuilder->GetPrimitiveType(loweredTypeCode2)); continue; - } + } } if (checkType->CanBeValuelessType()) module->PopulateType(checkType, BfPopulateType_Data); if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef())) continue; - + if ((doSplat) && (!checkType->IsMethodRef())) - { - int splatCount = checkType->GetSplatCount(); + { + int splatCount = checkType->GetSplatCount(); if ((int)paramTypes.size() + splatCount > module->mCompiler->mOptions.mMaxSplatRegs) { auto checkTypeInst = checkType->ToTypeInstance(); @@ -1373,7 +1504,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, } auto _AddType = [&](BfType* type) - { + { if ((type->IsComposite()) || ((!doSplat) && (paramIdx == -1) && (type->IsTypedPrimitive()))) { auto typeInst = type->ToTypeInstance(); @@ -1396,14 +1527,14 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, }, checkType); } else - _AddType(checkType); + _AddType(checkType); if (checkType2 != NULL) _AddType(checkType2); } if ((!module->mIsComptimeModule) && (GetStructRetIdx(forceStatic) == 1)) - { + { BF_SWAP(paramTypes[0], paramTypes[1]); } } @@ -1421,13 +1552,12 @@ bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicit { if (mReturnType != other->mReturnType) return false; - + int implicitParamCountA = ignoreImplicitParams ? GetImplicitParamCount() : 0; int implicitParamCountB = ignoreImplicitParams ? other->GetImplicitParamCount() : 0; if (HasExplicitThis()) { - } // if (other->HasExplicitThis()) @@ -1441,21 +1571,21 @@ bool BfMethodInstance::IsExactMatch(BfMethodInstance* other, bool ignoreImplicit if (checkThis) { if (other->mMethodDef->mIsStatic != mMethodDef->mIsStatic) - return false; + return false; // { // // If we are static and we have to match a non-static method, allow us to do so if we have an explicitly defined 'this' param that matches -// +// // if (other->mMethodDef->mIsStatic) // return false; -// +// // if ((GetParamCount() > 0) && (GetParamName(0) == "this")) // { // auto thisType = GetParamType(0); // auto otherThisType = other->GetParamType(-1); // if (thisType != otherThisType) // return false; -// +// // implicitParamCountA++; // } // else @@ -1530,11 +1660,11 @@ void BfMethodInstance::ReportMemory(MemReporter* memReporter) memReporter->EndSection(); } - - memReporter->AddVec("Params", mParams, false); + + memReporter->AddVec("Params", mParams, false); if (!mDefaultValues.IsEmpty()) memReporter->AddVec("DefaultValues", mDefaultValues, false); - + memReporter->EndSection(); } @@ -1557,11 +1687,11 @@ BfModuleMethodInstance::BfModuleMethodInstance(BfMethodInstance* methodInstance) mFunc = BfIRValue(); // if (methodInstance->GetImportCallKind() == BfImportCallKind_Thunk) // { -// auto declModule = methodInstance->mDeclModule; +// auto declModule = methodInstance->mDeclModule; // BfIRValue* irFuncPtr = NULL; // if (declModule->mFuncReferences.TryGetValue(methodInstance, &irFuncPtr)) // mFunc = *irFuncPtr; -// } +// } } ////////////////////////////////////////////////////////////////////////// @@ -1591,7 +1721,7 @@ BfMethodInstanceGroup::BfMethodInstanceGroup(BfMethodInstanceGroup&& prev) noexc for (auto& pair : *mMethodSpecializationMap) pair.mValue->mMethodInstanceGroup = this; } - + prev.mDefaultCustomAttributes = NULL; prev.mRefCount = 0; prev.mDefault = NULL; @@ -1670,12 +1800,12 @@ int BfTypeInstance::GetSplatCount() } bool BfTypeInstance::IsString() -{ +{ return IsInstanceOf(mContext->mCompiler->mStringTypeDef); } int BfTypeInstance::GetOrigVTableSize() -{ +{ if (!mModule->mCompiler->mOptions.mHasVDataExtender) { BF_ASSERT(mHotTypeData == NULL); @@ -1690,7 +1820,7 @@ int BfTypeInstance::GetOrigVTableSize() } if (mBaseType != NULL) return mBaseType->GetOrigVTableSize() + (mVirtualMethodTableSize - mBaseType->mVirtualMethodTableSize); - return mVirtualMethodTableSize; + return mVirtualMethodTableSize; } int BfTypeInstance::GetSelfVTableSize() @@ -1704,7 +1834,7 @@ int BfTypeInstance::GetSelfVTableSize() } int BfTypeInstance::GetOrigSelfVTableSize() -{ +{ if (mBaseType != NULL) return GetOrigVTableSize() - GetOrigImplBaseVTableSize(); return GetOrigVTableSize(); @@ -1747,14 +1877,14 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) *wantSplat = false; if (!mIsUnion) - return NULL; + return NULL; BfTypeState typeState(this, mContext->mCurTypeState); typeState.mPopulateType = BfPopulateType_Data; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); int unionSize = 0; - BfType* unionInnerType = NULL; + BfType* unionInnerType = NULL; bool makeRaw = false; for (int fieldIdx = 0; fieldIdx < (int)mFieldInstances.size(); fieldIdx++) { @@ -1773,8 +1903,8 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) } if (fieldInstance->mDataIdx >= 0) - { - checkInnerType = fieldInstance->mResolvedType; + { + checkInnerType = fieldInstance->mResolvedType; } if (checkInnerType != NULL) @@ -1783,10 +1913,10 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) mModule->PopulateType(checkInnerType, checkInnerType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration); if (checkInnerType->mSize > unionSize) - unionSize = checkInnerType->mSize; + unionSize = checkInnerType->mSize; if ((!checkInnerType->IsValuelessType()) && (checkInnerType != unionInnerType)) - { + { if (unionInnerType == NULL) { unionInnerType = checkInnerType; @@ -1814,10 +1944,10 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) unionInnerType = NULL; makeRaw = true; } - } + } } } - } + } } BF_ASSERT(unionInnerType != this); @@ -1829,7 +1959,7 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat) *wantSplat = true; } else - { + { switch (unionSize) { case 0: return mModule->CreateSizedArrayType(mModule->GetPrimitiveType(BfTypeCode_Int8), 0); @@ -1881,7 +2011,7 @@ void BfTypeInstance::GetUnderlyingArray(BfType*& type, int& size, bool& isVector if (attributes->mCtorArgs.size() != 3) return; - auto typeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[0]); + auto typeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[0]); auto sizeConstant = mConstHolder->GetConstant(attributes->mCtorArgs[1]); auto isVectorConstant = mConstHolder->GetConstant(attributes->mCtorArgs[2]); if ((typeConstant == NULL) || (sizeConstant == NULL) || (isVectorConstant == NULL)) @@ -1908,7 +2038,7 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo // Odd Windows rule: composite returns for non-static methods are always sret if (typeUsage == BfTypeUsage_Return_NonStatic) return false; - } + } else { // Non-Win64 systems allow lowered splitting of composites over multiple params @@ -1933,7 +2063,7 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo { if ((mInstSize >= 4) && (mInstSize <= maxInstSize)) { - BfTypeCode types[8] = { BfTypeCode_None }; + BfTypeCode types[8] = { BfTypeCode_None }; std::function _CheckType = [&](BfType* type, int offset) { @@ -1952,13 +2082,13 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo } else { - types[offset / 4] = BfTypeCode_Object; + types[offset / 4] = BfTypeCode_Object; } } else if (type->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)type; - types[offset / 4] = primType->mTypeDef->mTypeCode; + types[offset / 4] = primType->mTypeDef->mTypeCode; } else if (type->IsSizedArray()) { @@ -2158,19 +2288,19 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo BfTypeCode typeCode = BfTypeCode_None; BfTypeCode pow2TypeCode = BfTypeCode_None; - + switch (mInstSize) { - case 1: + case 1: pow2TypeCode = BfTypeCode_Int8; break; - case 2: + case 2: pow2TypeCode = BfTypeCode_Int16; break; case 3: typeCode = BfTypeCode_Int24; break; - case 4: + case 4: pow2TypeCode = BfTypeCode_Int32; break; case 5: @@ -2182,7 +2312,7 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo case 7: typeCode = BfTypeCode_Int56; break; - case 8: + case 8: if (mModule->mSystem->mPtrSize == 8) { pow2TypeCode = BfTypeCode_Int64; @@ -2193,7 +2323,7 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo pow2TypeCode = BfTypeCode_Int64; break; } - break; + break; } if (pow2TypeCode != BfTypeCode_None) @@ -2202,7 +2332,7 @@ bool BfTypeInstance::GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCo *outTypeCode = pow2TypeCode; return true; } - + if ((mModule->mCompiler->mOptions.mPlatformType != BfPlatformType_Windows) && (mModule->mSystem->mPtrSize == 8)) { if (typeCode != BfTypeCode_None) @@ -2272,7 +2402,7 @@ bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId) { valueType = tupleType->mFieldInstances[0].mResolvedType; okTagId = -fieldInstance.mDataIdx - 1; - return true; + return true; } } break; @@ -2287,7 +2417,7 @@ void BfTypeInstance::ReportMemory(MemReporter* memReporter) memReporter->Add(sizeof(BfTypeInstance)); - int depSize = 0; + int depSize = 0; depSize += sizeof((int)mDependencyMap.mTypeSet.mAllocSize * sizeof(BfDependencyMap::TypeMap::EntryPair)); memReporter->Add("DepMap", depSize); memReporter->AddVec(mInterfaces, false); @@ -2295,12 +2425,12 @@ void BfTypeInstance::ReportMemory(MemReporter* memReporter) if (mCustomAttributes != NULL) mCustomAttributes->ReportMemory(memReporter); - + int methodCount = 0; memReporter->BeginSection("MethodData"); for (auto& methodInstGroup : mMethodInstanceGroups) { - memReporter->Add(sizeof(BfMethodInstanceGroup)); + memReporter->Add(sizeof(BfMethodInstanceGroup)); if (methodInstGroup.mDefault != NULL) { methodInstGroup.mDefault->ReportMemory(memReporter); @@ -2313,7 +2443,7 @@ void BfTypeInstance::ReportMemory(MemReporter* memReporter) { methodCount++; kv.mValue->ReportMemory(memReporter); - } + } } } memReporter->EndSection(); @@ -2324,17 +2454,17 @@ void BfTypeInstance::ReportMemory(MemReporter* memReporter) memReporter->AddMap("SpecializedMethodReferences", mSpecializedMethodReferences, false); memReporter->AddMap("LookupResults", mLookupResults, false); if (mConstHolder != NULL) - memReporter->Add("ConstHolder", mConstHolder->mTempAlloc.GetTotalAllocSize()); + memReporter->Add("ConstHolder", mConstHolder->mTempAlloc.GetTotalAllocSize()); if (mHotTypeData != NULL) { AutoMemReporter autoMemReporter(memReporter, "HotTypeData"); - memReporter->Add(sizeof(BfHotTypeData)); + memReporter->Add(sizeof(BfHotTypeData)); memReporter->AddVec(mHotTypeData->mTypeVersions, false); for (auto typeVersion : mHotTypeData->mTypeVersions) { memReporter->AddVec(typeVersion->mMembers, false); - memReporter->AddVec(typeVersion->mInterfaceMapping, false); + memReporter->AddVec(typeVersion->mInterfaceMapping, false); } memReporter->AddVec(mHotTypeData->mVTableEntries, false); for (auto& entry : mHotTypeData->mVTableEntries) @@ -2345,12 +2475,12 @@ void BfTypeInstance::ReportMemory(MemReporter* memReporter) } bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) -{ +{ if (activeTypeDef == NULL) return false; if (declaringTypeDef == activeTypeDef) return true; - return activeTypeDef->mProject->ContainsReference(declaringTypeDef->mProject); + return activeTypeDef->mProject->ContainsReference(declaringTypeDef->mProject); } bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) @@ -2370,10 +2500,10 @@ bool BfTypeInstance::IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProje bool BfTypeInstance::WantsGCMarking() { BF_ASSERT(mTypeDef->mTypeCode != BfTypeCode_Extension); - if (IsObjectOrInterface()) - return true; + if (IsObjectOrInterface()) + return true; if ((IsEnum()) && (!IsPayloadEnum())) - return false; + return false; BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed)); return mWantsGCMarking; } @@ -2409,7 +2539,7 @@ BfGenericTypeInfo::GenericParamsVector* BfTypeInstance::GetGenericParamsVector(B BfGenericExtensionEntry* genericExEntry = NULL; if (mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(declaringTypeDef, &genericExEntry)) return &genericExEntry->mGenericParams; - + return &mGenericTypeInfo->mGenericParams; } @@ -2428,7 +2558,7 @@ bool BfTypeInstance::IsAlwaysInclude() bool alwaysInclude = mTypeDef->mIsAlwaysInclude || mTypeDef->mProject->mAlwaysIncludeAll; if (mTypeOptionsIdx > 0) { - auto typeOptions = mModule->mSystem->GetTypeOptions(mTypeOptionsIdx); + auto typeOptions = mModule->mSystem->GetTypeOptions(mTypeOptionsIdx); typeOptions->Apply(alwaysInclude, BfOptionFlags_ReflectAlwaysIncludeType); } if ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_Type) != 0) @@ -2455,7 +2585,7 @@ bool BfTypeInstance::IsSpecializedByAutoCompleteMethod() } bool BfTypeInstance::IsNullable() -{ +{ return IsInstanceOf(mContext->mCompiler->mNullableTypeDef); } @@ -2472,7 +2602,7 @@ bool BfTypeInstance::HasVarConstraints() } bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeTypeDef, BfModule* module) -{ +{ if (mGenericTypeInfo == NULL) return true; if (mGenericTypeInfo->mGenericExtensionInfo == NULL) @@ -2483,7 +2613,7 @@ bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeT // The combined type declaration is the root type declaration, it's implicitly included if (typeDef->mTypeDeclaration == mTypeDef->mTypeDeclaration) return true; - + BfGenericExtensionEntry* genericExEntry = NULL; if (!mGenericTypeInfo->mGenericExtensionInfo->mExtensionMap.TryGetValue(typeDef, &genericExEntry)) return true; @@ -2515,12 +2645,12 @@ bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeT return true; } - + return genericExEntry->mConstraintsPassed; } void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter) -{ +{ memReporter->Add(sizeof(BfGenericTypeInfo)); memReporter->AddVec(mTypeGenericArguments, false); memReporter->AddVec(mGenericParams, false); @@ -2565,12 +2695,12 @@ bool BfTypeInstance::IsValuelessType() return false; } if (mTypeDef->mIsOpaque) - return false; - + return false; + BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); BF_ASSERT(mInstSize >= 0); if (mInstSize == 0) - { + { return true; } @@ -2615,7 +2745,7 @@ void BfTypeInstance::CalcHotVirtualData(Array* ifaceMapping) if (slotNum >= (int)ifaceMapping->size()) ifaceMapping->Resize(slotNum + 1); (*ifaceMapping)[slotNum] = iface.mInterfaceType->mTypeId; - } + } } if (mBaseType != NULL) mBaseType->CalcHotVirtualData(ifaceMapping); @@ -2626,7 +2756,7 @@ void BfTypeInstance::CalcHotVirtualData(Array* ifaceMapping) BfClosureType::BfClosureType(BfTypeInstance* srcDelegate, Val128 closureHash) : mSource(srcDelegate->mTypeDef->mSystem) -{ +{ BF_ASSERT(srcDelegate->IsDelegate()); mSrcDelegate = srcDelegate; mTypeDef = mSrcDelegate->mTypeDef; @@ -2656,21 +2786,21 @@ void BfClosureType::Init(BfProject* bfProject) mTypeDef = new BfTypeDef(); mTypeDef->mSystem = system; - mTypeDef->mSource = &mSource; + mTypeDef->mSource = &mSource; mTypeDef->mSource->mRefCount++; mTypeDef->mProject = bfProject; - mTypeDef->mTypeCode = srcTypeDef->mTypeCode; - mTypeDef->mName = system->GetAtom(srcTypeDef->mName->mString + mNameAdd); + mTypeDef->mTypeCode = srcTypeDef->mTypeCode; + mTypeDef->mName = system->GetAtom(srcTypeDef->mName->mString + mNameAdd); // Purposely leave out 'mOuterType' - this fails if the outer type is generic //mTypeDef->mOuterType = srcTypeDef->mOuterType; mTypeDef->mNamespace = srcTypeDef->mNamespace; system->AddNamespaceUsage(mTypeDef->mNamespace, mTypeDef->mProject); mTypeDef->mHash = srcTypeDef->mHash; - mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash; + mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash; // mTypeDef->mFullName = srcTypeDef->mFullName; // if (!mTypeDef->mFullName.mParts.IsEmpty()) // mTypeDef->mFullName.mParts.pop_back(); -// mTypeDef->mFullName.mParts.push_back(mTypeDef->mName); +// mTypeDef->mFullName.mParts.push_back(mTypeDef->mName); if (srcTypeDef->mFullName.mSize > 0) mTypeDef->mFullName.Set(srcTypeDef->mFullName.mParts, srcTypeDef->mFullName.mSize - 1, &mTypeDef->mName, 1); else @@ -2679,7 +2809,7 @@ void BfClosureType::Init(BfProject* bfProject) mTypeDef->mTypeCode = BfTypeCode_Object; mTypeDef->mIsDelegate = true; - mTypeDef->mIsClosure = true; + mTypeDef->mIsClosure = true; mTypeDef->mDefState = BfTypeDef::DefState_Defined; auto baseDirectTypeRef = BfAstNode::ZeroedAlloc(); @@ -2720,7 +2850,7 @@ void BfClosureType::Finish() ////////////////////////////////////////////////////////////////////////// BfDelegateType::~BfDelegateType() -{ +{ mMethodInstanceGroups.Clear(); delete mTypeDef; mTypeDef = NULL; @@ -2739,7 +2869,7 @@ BfTupleType::BfTupleType() { mCreatedTypeDef = false; mSource = NULL; - mTypeDef = NULL; + mTypeDef = NULL; mIsUnspecializedType = false; mIsUnspecializedTypeVariation = false; mGenericDepth = 0; @@ -2757,7 +2887,7 @@ BfTupleType::~BfTupleType() } void BfTupleType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance) -{ +{ auto srcTypeDef = valueTypeInstance->mTypeDef; auto system = valueTypeInstance->mModule->mSystem; @@ -2766,17 +2896,17 @@ void BfTupleType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance) for (auto field : mTypeDef->mFields) delete field; mTypeDef->mFields.Clear(); - mTypeDef->mSystem = system; + mTypeDef->mSystem = system; mTypeDef->mProject = bfProject; mTypeDef->mTypeCode = srcTypeDef->mTypeCode; mTypeDef->mName = system->mEmptyAtom; mTypeDef->mSystem = system; - + mTypeDef->mHash = srcTypeDef->mHash; - mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash; + mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash; mTypeDef->mTypeCode = BfTypeCode_Struct; - - mCreatedTypeDef = true; + + mCreatedTypeDef = true; } void BfTupleType::Dispose() @@ -2798,7 +2928,7 @@ BfFieldDef* BfTupleType::AddField(const StringImpl& name) void BfTupleType::Finish() { BF_ASSERT(!mTypeFailed); - + auto bfSystem = mTypeDef->mSystem; mSource = new BfSource(bfSystem); mTypeDef->mSource = mSource; @@ -2819,13 +2949,13 @@ BfBoxedType::~BfBoxedType() } BfType* BfBoxedType::GetModifiedElementType() -{ +{ if ((mBoxedFlags & BoxedFlags_StructPtr) != 0) { auto module = mModule; if (module == NULL) - module = mContext->mUnreifiedModule; - return module->CreatePointerType(mElementType); + module = mContext->mUnreifiedModule; + return module->CreatePointerType(mElementType); } return mElementType; } @@ -2875,7 +3005,7 @@ int BfMethodRefType::GetParamIdxFromDataIdx(int dataIdx) } bool BfMethodRefType::WantsDataPassedAsSplat(int dataIdx) -{ +{ if (dataIdx != -1) return false; return mMethodRef->GetParamIsSplat(mDataToParamIdx[dataIdx]); @@ -2884,7 +3014,7 @@ bool BfMethodRefType::WantsDataPassedAsSplat(int dataIdx) ////////////////////////////////////////////////////////////////////////// size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const -{ +{ size_t hash = typeVec.size(); BfResolvedTypeSet::LookupContext ctx; for (auto type : typeVec) @@ -2939,7 +3069,6 @@ BfCustomAttribute* BfCustomAttributes::Get(int idx) BfResolvedTypeSet::~BfResolvedTypeSet() { - } #define HASH_MIX(origHashVal, newHashVal) ((((origHashVal) << 5) - (origHashVal)) ^ (newHashVal)) @@ -2961,14 +3090,14 @@ BfResolvedTypeSet::~BfResolvedTypeSet() BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType) { - outType = NULL; + outType = NULL; BfConstResolver constResolver(ctx->mModule); - BfVariant variant; + BfVariant variant; constResolver.mBfEvalExprFlags = BfEvalExprFlags_NoCast; constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue); constResolver.mExpectingType = ctx->mModule->GetPrimitiveType(BfTypeCode_Int64); - auto result = constResolver.Resolve(expr); + auto result = constResolver.Resolve(expr); if (result) { // Limit the types of constants to prevent duplicate values with different types - we don't want to hash a typeref with an int32 @@ -2982,9 +3111,9 @@ BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression* outType = result.mType; if (result.mKind == BfTypedValueKind_GenericConstValue) - { + { return variant; - } + } else { variant = ctx->mModule->TypedValueToVariant(expr, result, true); @@ -3008,8 +3137,8 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i // } // return Hash(underlyingType, ctx, allowRef); // } -// else - +// else + if (type->IsBoxed()) { BfBoxedType* boxedType = (BfBoxedType*)type; @@ -3021,14 +3150,14 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i BfArrayType* arrayType = (BfArrayType*)type; int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8); return (elemHash << 5) - elemHash; - } + } else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef()) - { + { auto typeInst = (BfTypeInstance*)type; int hashVal = HASH_DELEGATE; - + auto delegateInfo = type->GetDelegateInfo(); - + hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed + 1)); auto methodDef = typeInst->mTypeDef->mMethods[0]; @@ -3041,19 +3170,19 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i BF_ASSERT(infoParamCount == methodDef->mParams.size()); for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++) - { + { // Parse attributes? hashVal = HASH_MIX(hashVal, Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed + 1)); String paramName = methodDef->mParams[paramIdx]->mName; int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length()); hashVal = HASH_MIX(hashVal, nameHash); } - + if (delegateInfo->mHasVarArgs) hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT); return hashVal; - } + } else if (type->IsTypeInstance()) { BfTypeInstance* typeInst = (BfTypeInstance*)type; @@ -3067,7 +3196,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i if (closureType->mIsUnique) return false; hashVal = ((hashVal ^ (int)closureType->mClosureHash.mLow) << 5) - hashVal; - } + } else if (type->IsTuple()) { hashVal = HASH_VAL_TUPLE; @@ -3076,8 +3205,8 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; - - auto fieldType = fieldInstance->mResolvedType; + + auto fieldType = fieldInstance->mResolvedType; hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1)); BfFieldDef* fieldDef = NULL; @@ -3091,7 +3220,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i nameHash = (int)Hash64(nameStr, strlen(nameStr)); } else - { + { nameHash = (int)Hash64(fieldDef->mName.c_str(), (int)fieldDef->mName.length()); } hashVal = HASH_MIX(hashVal, nameHash); @@ -3100,7 +3229,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i else if (type->IsGenericTypeInstance()) { BfTypeInstance* genericType = (BfTypeInstance*)type; - for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments) + for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments) hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_None, hashSeed + 1)); } return hashVal; @@ -3109,7 +3238,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i { BfPrimitiveType* primType = (BfPrimitiveType*)type; return primType->mTypeDef->mHash; - } + } else if (type->IsPointer()) { BfPointerType* pointerType = (BfPointerType*) type; @@ -3126,7 +3255,7 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i auto refType = (BfRefType*)type; int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refType->mRefKind); return (elemHash << 5) - elemHash; - } + } else if (type->IsModifiedTypeType()) { auto modifiedTypeType = (BfModifiedTypeType*)type; @@ -3154,15 +3283,15 @@ int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, i hashVal = ((hashVal ^ (int)sizedArray->mElementCount) << 5) - hashVal; return hashVal; - } + } else if (type->IsMethodRef()) - { + { auto methodRefType = (BfMethodRefType*)type; if (methodRefType->IsNull()) return 0; return (int)((int)(intptr)(methodRefType->mMethodRef) << 5) ^ (int)(intptr)(methodRefType->mOwner) ^ methodRefType->mOwnerRevision; - } + } else if (type->IsConstExprValue()) { BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; @@ -3194,8 +3323,8 @@ void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupCon bool allowUnboundGeneric = ((ctx->mResolveFlags & BfResolveTypeRefFlag_AllowUnboundGeneric) != 0) && (hashSeed == 0); BfAstNode* genericArgTypeRef = NULL; - if (genericIdx < genericTypeRef->mGenericArguments.mSize) - genericArgTypeRef = genericTypeRef->mGenericArguments[genericIdx]; + if (genericIdx < genericTypeRef->mGenericArguments.mSize) + genericArgTypeRef = genericTypeRef->mGenericArguments[genericIdx]; if (allowUnboundGeneric) { @@ -3217,7 +3346,7 @@ void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupCon { ctx->mIsUnboundGeneric = true; argHashVal = (((int)BfGenericParamKind_Type + 0xB00) << 8) ^ (genericIdx + 1); - argHashVal = HASH_MIX(argHashVal, hashSeed + 1); + argHashVal = HASH_MIX(argHashVal, hashSeed + 1); } else { @@ -3226,7 +3355,7 @@ void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupCon return; } } - + hashVal = HASH_MIX(hashVal, argHashVal); } } @@ -3252,7 +3381,7 @@ BfResolveTypeRefFlags BfResolvedTypeSet::GetResolveFlags(BfAstNode* typeRef, Loo } int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed) -{ +{ auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, GetResolveFlags(typeRef, ctx, flags)); if (resolvedType == NULL) { @@ -3293,11 +3422,11 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) && ((typeRef->IsNamedTypeReference()) || (BfNodeIsA(typeRef)))) - { + { BfTypeDef* typeDef = ctx->mRootTypeDef; - + int hashVal = typeDef->mHash; - + if (typeDef->mGenericParamDefs.size() != 0) { auto checkTypeInstance = ctx->mModule->mCurTypeInstance; @@ -3305,7 +3434,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa checkTypeInstance = checkTypeInstance->GetUnderlyingType()->ToTypeInstance(); auto outerType = ctx->mModule->mSystem->GetOuterTypeNonPartial(typeDef); - + BfTypeDef* commonOuterType; if (typeRef == ctx->mRootTypeRef) commonOuterType = FindRootCommonOuterType(outerType, ctx, checkTypeInstance); @@ -3336,12 +3465,12 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa ctx->mFailed = true; return 0; } - + BF_ASSERT(checkTypeInstance->IsGenericTypeInstance()); auto curGenericTypeInst = (BfTypeInstance*)checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); for (int i = 0; i < numParentGenericParams; i++) - { + { hashVal = HASH_MIX(hashVal, Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx, BfHashFlag_None, hashSeed + 1)); } } @@ -3366,6 +3495,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa return 0; } + int typeAliasHash = 0; + + bool isInnerTypeAlias = false; + // Don't translate aliases for the root type, just element types if (ctx->mRootTypeRef == typeRef) { @@ -3373,38 +3506,15 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa ctx->mRootTypeDef = elementTypeDef; } else if (elementTypeDef->mTypeCode == BfTypeCode_TypeAlias) - { - BfTypeVector genericArgs; - for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments) - { - auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, NULL, BfPopulateType_Identity, GetResolveFlags(genericArgTypeRef, ctx, flags)); - if (argType != NULL) - genericArgs.Add(argType); - else - ctx->mFailed = true; - } - - if (!ctx->mFailed) - { - auto resolvedType = ctx->mModule->ResolveTypeDef(elementTypeDef, genericArgs); - if ((resolvedType != NULL) && (resolvedType->IsTypeAlias())) - { - auto underlyingType = resolvedType->GetUnderlyingType(); - if (underlyingType == NULL) - { - ctx->mFailed = true; - return 0; - } - int hashVal = Hash(underlyingType, ctx, flags, hashSeed); - hashSeed = 0; - return hashVal; - } - } + { + isInnerTypeAlias = true; } - + + BfTypeVector typeAliasGenericArgs; + bool fullyQualified = false; int hashVal = elementTypeDef->mHash; - + BfTypeInstance* outerType = NULL; int checkIdx = 0; @@ -3417,7 +3527,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa fullyQualified = true; if ((elementTypeDef->mOuterType != NULL) && (!elementTypeDef->mOuterType->mGenericParamDefs.IsEmpty())) { - auto resolvedType = ctx->mModule->ResolveTypeRef(checkTypeRef, BfPopulateType_Identity, + auto resolvedType = ctx->mModule->ResolveTypeRef(checkTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(GetResolveFlags(checkTypeRef, ctx, flags) | BfResolveTypeRefFlag_IgnoreLookupError)); if (resolvedType == NULL) { @@ -3440,16 +3550,21 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { checkTypeRef = qualifiedTypeRef->mLeft; continue; - } + } break; } - + if (fullyQualified) - { + { if (outerType != NULL) { for (auto genericArg : outerType->mGenericTypeInfo->mTypeGenericArguments) - hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + { + if (isInnerTypeAlias) + typeAliasGenericArgs.Add(genericArg); + else + hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + } } } else @@ -3469,12 +3584,46 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa auto parentTypeInstance = checkTypeInstance; int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); for (int i = 0; i < numParentGenericParams; i++) - hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + { + if (isInnerTypeAlias) + typeAliasGenericArgs.Add(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); + else + hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1)); + } } } } - HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed); + if (isInnerTypeAlias) + { + for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments) + { + auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, NULL, BfPopulateType_Identity, GetResolveFlags(genericArgTypeRef, ctx, flags)); + if (argType != NULL) + typeAliasGenericArgs.Add(argType); + else + ctx->mFailed = true; + } + + if (!ctx->mFailed) + { + auto resolvedType = ctx->mModule->ResolveTypeDef(elementTypeDef, typeAliasGenericArgs); + if ((resolvedType != NULL) && (resolvedType->IsTypeAlias())) + { + auto underlyingType = resolvedType->GetUnderlyingType(); + if (underlyingType == NULL) + { + ctx->mFailed = true; + return 0; + } + int hashVal = Hash(underlyingType, ctx, flags, hashSeed); + hashSeed = 0; + return hashVal; + } + } + } + else + HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed); return hashVal; } @@ -3484,10 +3633,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++) { - BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx]; + BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx]; hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, BfHashFlag_None, hashSeed + 1)); - int nameHash = 0; + int nameHash = 0; BfIdentifierNode* fieldName = NULL; if (fieldIdx < (int)tupleTypeRef->mFieldNames.size()) fieldName = tupleTypeRef->mFieldNames[fieldIdx]; @@ -3539,8 +3688,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue); constResolver.mExpectingType = intType; BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize); + if (typedVal.mKind == BfTypedValueKind_GenericConstValue) { + ctx->mResolvedValueMap[sizeExpr] = typedVal; int elemHash = Hash(typedVal.mType, ctx, BfHashFlag_None, hashSeed); hashVal = ((hashVal ^ elemHash) << 5) - hashVal; return hashVal; @@ -3552,7 +3703,8 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa SetAndRestoreValue prevIgnoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true); typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType); } - + ctx->mResolvedValueMap[sizeExpr] = typedVal; + if (typedVal) { auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue); @@ -3585,8 +3737,8 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } } - } - + } + hashVal = ((hashVal ^ (int)elementCount) << 5) - hashVal; return hashVal; } @@ -3613,7 +3765,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } else if (auto pointerType = BfNodeDynCastExact(typeRef)) - { + { int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR; return (elemHash << 5) - elemHash; } @@ -3622,10 +3774,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa if (ctx->mRootTypeRef == typeRef) ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef; - int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash; + int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash; hashVal = HASH_MIX(hashVal, Hash(nullableType->mElementType, ctx, BfHashFlag_None, hashSeed + 1)); return hashVal; - } + } else if (auto refType = BfNodeDynCastExact(typeRef)) { if ((flags & BfHashFlag_AllowRef) != 0) @@ -3644,10 +3796,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa return (elemHash << 5) - elemHash; } else - { + { ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, GetResolveFlags(typeRef, ctx, flags)); // To throw an error... ctx->mFailed = true; - return 0; + return 0; //return Hash(refType->mElementType, ctx); } } @@ -3693,23 +3845,28 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa // Don't allow 'var' ctx->mModule->Fail("Invalid use of 'var'", typeRef); ctx->mFailed = true; - return 0; + return 0; } else if (auto letType = BfNodeDynCastExact(typeRef)) { // Don't allow 'let' ctx->mModule->Fail("Invalid use of 'let'", typeRef); ctx->mFailed = true; - return 0; + return 0; } else if (auto retTypeTypeRef = BfNodeDynCastExact(typeRef)) - { + { // Don't cause infinite loop, but if we have an inner 'rettype' then try to directly resolve that -- // Only use the HAS_RETTYPE for root-level rettype insertions if (ctx->mRootTypeRef != retTypeTypeRef) { auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, GetResolveFlags(retTypeTypeRef, ctx, flags)); - if ((type != NULL) && (type->IsRef())) + if (type == NULL) + { + ctx->mFailed = true; + return 0; + } + if (type->IsRef()) type = type->GetUnderlyingType(); return Hash(type, ctx, flags, hashSeed); } @@ -3725,7 +3882,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { // 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, hashSeed); - } + } else if (auto delegateTypeRef = BfNodeDynCastExact(typeRef)) { int hashVal = HASH_DELEGATE; @@ -3733,10 +3890,10 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa hashVal = HASH_MIX(hashVal, Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed + 1)); else ctx->mFailed = true; - + bool isFirstParam = true; - for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < delegateTypeRef->mParams.size(); paramIdx++) { auto param = delegateTypeRef->mParams[paramIdx]; // Parse attributes? @@ -3756,13 +3913,13 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa if (auto dotTypeRef = BfNodeDynCastExact(fieldType)) { if (dotTypeRef->mDotToken->mToken == BfToken_DotDotDot) - { + { hashVal = HASH_MIX(hashVal, HASH_DOTDOTDOT); continue; } } } - + if (fieldType != NULL) hashVal = HASH_MIX(hashVal, Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef), hashSeed + 1)); hashVal = HASH_MIX(hashVal, HashNode(param->mNameNode)); @@ -3770,7 +3927,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } return hashVal; - } + } else if (auto exprModTypeRef = BfNodeDynCastExact(typeRef)) { auto cachedResolvedType = ctx->GetCachedResolvedType(typeRef); @@ -3783,9 +3940,9 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { BfMethodState methodState; SetAndRestoreValue prevMethodState(ctx->mModule->mCurMethodState, &methodState, false); - if (ctx->mModule->mCurMethodState == NULL) + if (ctx->mModule->mCurMethodState == NULL) prevMethodState.Set(); - methodState.mTempKind = BfMethodState::TempKind_NonStatic; + methodState.mTempKind = BfMethodState::TempKind_NonStatic; SetAndRestoreValue ignoreWrites(ctx->mModule->mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue allowUninitReads(ctx->mModule->mCurMethodState->mAllowUinitReads, true); @@ -3801,7 +3958,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa auto typeType = ctx->mModule->ResolveTypeDef(ctx->mModule->mCompiler->mTypeTypeDef); exprFlags = (BfEvalExprFlags)(exprFlags | BfEvalExprFlags_Comptime | BfEvalExprFlags_NoCast); result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, typeType, exprFlags); - if ((result.mType != NULL) && (!result.mType->IsInteger()) && (result.mType != typeType) && + if ((result.mType != NULL) && (!result.mType->IsInteger()) && (result.mType != typeType) && (!result.mType->IsInstanceOf(ctx->mModule->mCompiler->mReflectTypeIdTypeDef))) result = ctx->mModule->Cast(exprModTypeRef->mTarget, result, typeType); } @@ -3810,9 +3967,9 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa result = ctx->mModule->CreateValueFromExpression(exprModTypeRef->mTarget, NULL, BfEvalExprFlags_DeclType); } } - + if ((result) && (exprModTypeRef->mToken->mToken == BfToken_Comptype)) - { + { auto constant = ctx->mModule->mBfIRBuilder->GetConstant(result.mValue); if (constant != NULL) { @@ -3822,9 +3979,20 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa cachedResolvedType = typeOf->mType; } else if (constant->mConstType == BfConstType_Undef) - { + { ctx->mHadVar = true; cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var); + + auto typeState = ctx->mModule->mContext->mCurTypeState; + if ((typeState != NULL) && (typeState->mType != NULL) && (typeState->mType->IsTypeInstance())) + { + auto typeInst = typeState->mType->ToTypeInstance(); + if (typeInst->mDefineState == BfTypeDefineState_ResolvingBaseType) + { + // Make sure we regenerate this type + ctx->mModule->mContext->mFailTypes.TryAdd(typeState->mType->ToTypeInstance(), BfFailKind_Deep); + } + } } else if (BfIRConstHolder::IsInt(constant->mTypeCode)) { @@ -3845,7 +4013,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa } } } - + if (cachedResolvedType == NULL) ctx->mModule->Fail("Constant System.Type value required", exprModTypeRef->mTarget); } @@ -3864,7 +4032,7 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { ctx->mFailed = true; return 0; - } + } int hashVal = Hash(cachedResolvedType, ctx, flags, hashSeed); hashSeed = 0; @@ -3879,11 +4047,11 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa return 0; } - BfVariant result; + BfVariant result; BfType* resultType = NULL; if (constExprTypeRef->mConstExpr != NULL) { - result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType); + result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType); if ((resultType != NULL) && (resultType->IsGenericParam())) { int hashVal = Hash(resultType, ctx, BfHashFlag_None, hashSeed); @@ -3898,12 +4066,12 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa return 0; } - auto hashVal = ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE; - hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; + auto hashVal = ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE; + hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal; return hashVal; } - else if (auto dotTypeRef = BfNodeDynCastExact(typeRef)) - { + else if (auto dotTypeRef = BfNodeDynCastExact(typeRef)) + { ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, GetResolveFlags(dotTypeRef, ctx, flags)); ctx->mFailed = true; return 0; @@ -3941,7 +4109,7 @@ int BfResolvedTypeSet::Hash(BfAstNode* typeRefNode, LookupContext* ctx, BfHashFl } ctx->mResolvedTypeMap[typeRefNode] = result; - return Hash(result, ctx, false, hashSeed); + return Hash(result, ctx, false, hashSeed); } bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) @@ -3965,13 +4133,13 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) if (lhsArrayType->mDimensions != rhsArrayType->mDimensions) return false; return lhsArrayType->mGenericTypeInfo->mTypeGenericArguments[0] == rhsArrayType->mGenericTypeInfo->mTypeGenericArguments[0]; - } + } else if (lhs->IsTypeInstance()) { if ((!rhs->IsTypeInstance()) || (rhs->IsBoxed())) return false; BfTypeInstance* lhsInst = (BfTypeInstance*)lhs; - BfTypeInstance* rhsInst = (BfTypeInstance*)rhs; + BfTypeInstance* rhsInst = (BfTypeInstance*)rhs; if (lhs->IsClosure()) { @@ -3985,13 +4153,13 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return false; return lhsClosure->mClosureHash == rhsClosure->mClosureHash; } - + if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef()) { if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef()) return false; if (lhs->IsDelegate() != rhs->IsDelegate()) - return false; + return false; BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo(); BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo(); if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate) @@ -4019,7 +4187,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) } return true; } - + if (lhs->IsTuple()) { if (!rhs->IsTuple()) @@ -4042,14 +4210,14 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) { char c = lhsFieldDef->mName[0]; if ((c < '0') || (c > '9')) - return false; + return false; } else { auto rhsFieldDef = rhsFieldInstance->GetFieldDef(); if (lhsFieldDef->mName != rhsFieldDef->mName) return false; - } + } } return true; } @@ -4088,7 +4256,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) BfPointerType* lhsPtrType = (BfPointerType*)lhs; BfPointerType* rhsPtrType = (BfPointerType*)rhs; return lhsPtrType->mElementType == rhsPtrType->mElementType; - } + } else if (lhs->IsGenericParam()) { if (!rhs->IsGenericParam()) @@ -4097,7 +4265,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) BfGenericParamType* rhsGenericParamType = (BfGenericParamType*)rhs; return (lhsGenericParamType->mGenericParamKind == rhsGenericParamType->mGenericParamKind) && (lhsGenericParamType->mGenericParamIdx == rhsGenericParamType->mGenericParamIdx); - } + } else if (lhs->IsRef()) { if (!rhs->IsRef()) @@ -4112,7 +4280,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return false; BfModifiedTypeType* lhsRetTypeType = (BfModifiedTypeType*)lhs; BfModifiedTypeType* rhsRetTypeType = (BfModifiedTypeType*)rhs; - return (lhsRetTypeType->mModifiedKind == rhsRetTypeType->mModifiedKind) && + return (lhsRetTypeType->mModifiedKind == rhsRetTypeType->mModifiedKind) && (lhsRetTypeType->mElementType == rhsRetTypeType->mElementType); } else if (lhs->IsConcreteInterfaceType()) @@ -4141,7 +4309,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return (lhsMethodRefType->mMethodRef == rhsMethodRefType->mMethodRef) && (lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) && (lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision); - } + } else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue())) { if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue()) @@ -4150,10 +4318,10 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) BfConstExprValueType* lhsConstExprValueType = (BfConstExprValueType*)lhs; BfConstExprValueType* rhsConstExprValueType = (BfConstExprValueType*)rhs; - return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) && + return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) && (lhsConstExprValueType->mValue.mInt64 == rhsConstExprValueType->mValue.mInt64); } - else + else { BF_FATAL("Not handled"); } @@ -4220,7 +4388,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType { if (!Equals(lhsArgType, genericArgTypeRef, ctx)) return false; - } + } } } @@ -4231,7 +4399,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType { int genericParamOffset = 0; bool isFullyQualified = false; - BfTypeInstance* outerType = NULL; + BfTypeInstance* outerType = NULL; if (auto genericInstTypeRef = BfNodeDynCast(rhs)) { @@ -4256,7 +4424,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType lhsCheckType = ctx->mModule->GetOuterType(lhsCheckType); } if (lhsCheckType != outerType) - return false; + return false; if (outerType->mGenericTypeInfo != NULL) genericParamOffset = (int)outerType->mGenericTypeInfo->mTypeGenericArguments.mSize; @@ -4288,7 +4456,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfTypeInstance* lhsGenericType, BfType rootOuterTypeInstance = ctx->mModule->mCurTypeInstance; if ((rhsTypeDef == ctx->mRootTypeDef) && (ctx->mRootOuterTypeInstance != NULL)) rootOuterTypeInstance = ctx->mRootOuterTypeInstance; - + if (rhsGenericTypeInstRef == NULL) { if (auto rhsNullableTypeRef = BfNodeDynCastExact(rhs)) @@ -4405,7 +4573,7 @@ BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* t return typeDefTypeRef->mTypeDef; } - auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); + auto type = mModule->ResolveTypeRef(typeReference, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue); if (type == NULL) return NULL; if (outType != NULL) @@ -4419,7 +4587,7 @@ BfTypeDef* BfResolvedTypeSet::LookupContext::ResolveToTypeDef(BfTypeReference* t } bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx) -{ +{ auto rhsType = ctx->mModule->ResolveTypeDef(rhsTypeDef, BfPopulateType_Identity); if (rhsType == NULL) { @@ -4433,7 +4601,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhs bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx) { //BP_ZONE("BfResolvedTypeSet::Equals"); - + if (ctx->mRootTypeRef != rhs) { if (auto retTypeRef = BfNodeDynCastExact(rhs)) @@ -4455,17 +4623,17 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx->mFailed = true; return false; } - return lhs == rhsResolvedType; + return lhs == rhsResolvedType; } } - + if (auto declTypeRef = BfNodeDynCastExact(rhs)) { auto cachedResolveType = ctx->GetCachedResolvedType(rhs); BF_ASSERT(cachedResolveType != NULL); return lhs == cachedResolveType; } - + // Strip off 'const' - it's just an error when applied to a typeRef in Beef auto constTypeRef = BfNodeDynCastExact(rhs); if (constTypeRef != NULL) @@ -4500,15 +4668,15 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* auto rhsDelegateType = BfNodeDynCastExact(rhs); if (rhsDelegateType == NULL) return false; - + bool wantGeneric = false; - - BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo(); - + + BfDelegateInfo* lhsDelegateInfo = lhs->GetDelegateInfo(); + auto lhsTypeInstance = lhs->ToTypeInstance(); BfMethodDef* invokeMethodDef = lhsTypeInstance->mTypeDef->mMethods[0]; BF_ASSERT(invokeMethodDef->mName == "Invoke"); - + bool rhsIsDelegate = rhsDelegateType->mTypeToken->GetToken() == BfToken_Delegate; if ((lhs->IsDelegate()) != rhsIsDelegate) @@ -4519,14 +4687,14 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* if (type->IsTypeGenericParam()) wantGeneric = true; }; - + BfCallingConvention rhsCallingConvention = BfCallingConvention_Unspecified; if (ctx->mRootTypeRef == rhsDelegateType) rhsCallingConvention = ctx->mCallingConvention; else ctx->mModule->GetDelegateTypeRefAttributes(rhsDelegateType, rhsCallingConvention); if (lhsDelegateInfo->mCallingConvention != rhsCallingConvention) - return false; + return false; if (!Equals(lhsDelegateInfo->mReturnType, rhsDelegateType->mReturnType, ctx)) return false; _CheckType(lhsDelegateInfo->mReturnType); @@ -4543,21 +4711,21 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return false; bool handled = false; - auto lhsThisType = lhsDelegateInfo->mParams[0]; + auto lhsThisType = lhsDelegateInfo->mParams[0]; auto rhsThisType = ctx->mModule->ResolveTypeRef(param0->mTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoWarnOnMut | BfResolveTypeRefFlag_AllowRef)); bool wantsMutating = false; if (rhsThisType->IsRef()) - { + { if (lhsThisType != rhsThisType->GetUnderlyingType()) return false; - wantsMutating = (lhsThisType->IsValueType()) || (lhsThisType->IsGenericParam()); + wantsMutating = (lhsThisType->IsValueType()) || (lhsThisType->IsGenericParam()); } else { if (lhsThisType != rhsThisType) - return false; + return false; } if (invokeMethodDef->mIsMutating != wantsMutating) return false; @@ -4574,7 +4742,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return false; for (int paramIdx = paramRefOfs; paramIdx < lhsDelegateInfo->mParams.size(); paramIdx++) { - auto paramTypeRef = rhsDelegateType->mParams[paramIdx]->mTypeRef; + auto paramTypeRef = rhsDelegateType->mParams[paramIdx]->mTypeRef; if (!Equals(lhsDelegateInfo->mParams[paramIdx], paramTypeRef, ctx)) return false; _CheckType(lhsDelegateInfo->mParams[paramIdx]); @@ -4597,9 +4765,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return true; } else if (lhs->IsTypeInstance()) - { - BfTypeInstance* lhsInst = (BfTypeInstance*) lhs; - + { + BfTypeInstance* lhsInst = (BfTypeInstance*) lhs; + if (lhs->IsTuple()) { if (!rhs->IsA()) @@ -4652,12 +4820,12 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* BfTypeInstance* lhsGenericType = (BfTypeInstance*) lhs; return GenericTypeEquals(lhsGenericType, &lhsGenericType->mGenericTypeInfo->mTypeGenericArguments, rhs, rhsTypeDef, ctx); - } + } else { if (rhs->IsA()) return false; - + if (!rhs->IsTypeDefTypeReference()) { if (rhs->IsA()) @@ -4673,7 +4841,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return true; } } - + return false; } auto rhsTypeDef = ctx->ResolveToTypeDef(rhs); @@ -4681,7 +4849,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return false; return lhsInst->IsInstanceOf(rhsTypeDef); - } + } } else if (lhs->IsPrimitiveType()) { @@ -4706,20 +4874,20 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return true; } - BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs; - auto rhsTypeDef = ctx->ResolveToTypeDef(rhs); -// if (rhsTypeDef->mTypeCode == BfTypeCode_TypeAlias) -// return Equals(lhs, rhs, rhsTypeDef, ctx); + BfPrimitiveType* lhsPrimType = (BfPrimitiveType*)lhs; + auto rhsTypeDef = ctx->ResolveToTypeDef(rhs); +// if (rhsTypeDef->mTypeCode == BfTypeCode_TypeAlias) +// return Equals(lhs, rhs, rhsTypeDef, ctx); return lhsPrimType->mTypeDef == rhsTypeDef; } else if (lhs->IsPointer()) { auto rhsPointerTypeRef = BfNodeDynCastExact(rhs); if (rhsPointerTypeRef == NULL) - return false; - BfPointerType* lhsPtrType = (BfPointerType*)lhs; + return false; + BfPointerType* lhsPtrType = (BfPointerType*)lhs; return Equals(lhsPtrType->mElementType, rhsPointerTypeRef->mElementType, ctx); - } + } else if (lhs->IsGenericParam()) { auto lhsGenericParamType = (BfGenericParamType*)lhs; @@ -4733,7 +4901,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* return false; BfType* resultType = NULL; - result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType); + result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType); return resultType == lhs; } @@ -4793,12 +4961,9 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* BF_ASSERT(sizeExpr != NULL); if (sizeExpr != NULL) { - SetAndRestoreValue prevIgnoreError(ctx->mModule->mIgnoreErrors, true); - BfConstResolver constResolver(ctx->mModule); BfType* intType = ctx->mModule->GetPrimitiveType(BfTypeCode_IntPtr); - constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowGenericConstValue); - constResolver.mExpectingType = intType; - BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize); + BfTypedValue typedVal; + ctx->mResolvedValueMap.TryGetValue(sizeExpr, &typedVal); if (typedVal.mKind == BfTypedValueKind_GenericConstValue) { if (!lhs->IsUnknownSizedArrayType()) @@ -4809,11 +4974,12 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* } if (typedVal) typedVal = ctx->mModule->Cast(sizeExpr, typedVal, intType); + if (typedVal) - { + { if (lhs->IsUnknownSizedArrayType()) - return false; - + return false; + auto constant = ctx->mModule->mBfIRBuilder->GetConstant(typedVal.mValue); if ((constant->mConstType == BfConstType_Undef) || (!BfIRBuilder::IsInt(constant->mTypeCode))) { @@ -4822,15 +4988,15 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* else { elementCount = (intptr)constant->mInt64; - BF_ASSERT(elementCount >= 0); // Should have been caught in hash + BF_ASSERT(elementCount >= 0); // Should have been caught in hash } } } - + return lhsArrayType->mElementCount == elementCount; } else if (lhs->IsMethodRef()) - { + { // Always make these unique. The MethodInstance value will change on rebuild anyway return false; } @@ -4860,7 +5026,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* else { BF_FATAL("Not handled"); - } + } return false; } @@ -4893,9 +5059,9 @@ void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::EntryRef entry) // { // entry->mPrev->mNext = entry->mNext; // if (entry->mNext != NULL) -// entry->mNext->mPrev = entry->mPrev; -// } -// +// entry->mNext->mPrev = entry->mPrev; +// } +// // mSize--; bool found = false; @@ -4908,12 +5074,12 @@ void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::EntryRef entry) if (checkEntryIdx == entry.mIndex) { *srcCheckEntryPtr = checkEntry->mNext; - found = true; + found = true; } srcCheckEntryPtr = &checkEntry->mNext; checkEntryIdx = checkEntry->mNext; } - + BF_ASSERT(found); BF_ASSERT(entry->mValue == NULL); FreeIdx(entry.mIndex); @@ -4923,33 +5089,33 @@ void BfResolvedTypeSet::RemoveEntry(BfResolvedTypeSet::EntryRef entry) // { // return ++Iterator(this); // } -// +// // BfResolvedTypeSet::Iterator BfResolvedTypeSet::end() // { // Iterator itr(this); // itr.mCurBucket = HashSize; // return itr; // } -// +// // BfResolvedTypeSet::Iterator BfResolvedTypeSet::erase(BfResolvedTypeSet::Iterator& itr) // { // auto next = itr; // ++next; -// +// // auto cur = itr.mCurEntry; -// +// // auto& hashHead = itr.mTypeSet->mHashHeads[itr.mCurBucket]; -// +// // if (hashHead == cur) // hashHead = cur->mNext; -// if (cur->mPrev != NULL) -// cur->mPrev->mNext = cur->mNext; +// if (cur->mPrev != NULL) +// cur->mPrev->mNext = cur->mNext; // if (cur->mNext != NULL) -// cur->mNext->mPrev = cur->mPrev; +// cur->mNext->mPrev = cur->mPrev; // delete cur; -// +// // //BfLogSys("Deleting node %@ from bucket %d\n", cur, itr.mCurBucket); -// +// // mSize--; // return next; // } @@ -4965,8 +5131,8 @@ BfHotTypeVersion::~BfHotTypeVersion() BfHotTypeData::~BfHotTypeData() { for (auto version : mTypeVersions) - { - version->Deref(); + { + version->Deref(); } } @@ -4977,7 +5143,7 @@ BfHotTypeVersion* BfHotTypeData::GetTypeVersion(int hotCommitedIdx) BfHotTypeVersion* hotTypeVersion = mTypeVersions[checkIdx]; if (hotTypeVersion->mDeclHotCompileIdx <= hotCommitedIdx) return hotTypeVersion; - } + } return NULL; } @@ -4988,7 +5154,7 @@ BfHotTypeVersion* BfHotTypeData::GetLatestVersion() BfHotTypeVersion* BfHotTypeData::GetLatestVersionHead() { - auto lastestVersion = mTypeVersions.back(); + auto lastestVersion = mTypeVersions.back(); for (int versionIdx = (int)mTypeVersions.size() - 1; versionIdx >= 0; versionIdx--) { auto checkVersion = mTypeVersions[versionIdx]; @@ -5016,9 +5182,9 @@ void BfHotTypeData::ClearVersionsAfter(int hotIdx) } void BfHotDepData::Deref() -{ +{ mRefCount--; - BF_ASSERT(mRefCount >= 0); + BF_ASSERT(mRefCount >= 0); if (mRefCount == 0) { @@ -5050,7 +5216,7 @@ void BfHotDepData::Deref() break; case BfHotDepDataKind_VirtualDecl: delete (BfHotVirtualDeclaration*)this; - break; + break; default: BF_FATAL("Not handled"); } @@ -5058,7 +5224,7 @@ void BfHotDepData::Deref() } void BfHotMethod::Clear(bool keepDupMethods) -{ +{ if (mPrevVersion != NULL) { mPrevVersion->Deref(); @@ -5067,10 +5233,10 @@ void BfHotMethod::Clear(bool keepDupMethods) if (mSrcTypeVersion != NULL) { - mSrcTypeVersion->Deref(); + mSrcTypeVersion->Deref(); mSrcTypeVersion = NULL; - } - + } + if ((keepDupMethods) && ((mFlags & BfHotDepDataFlag_HasDup) != 0)) { int writeIdx = 0; @@ -5096,7 +5262,6 @@ void BfHotMethod::Clear(bool keepDupMethods) } mReferences.Clear(); } - } BfHotMethod::~BfHotMethod() @@ -5121,7 +5286,7 @@ String BfTypeUtils::HashEncode64(uint64 val) uint64 flippedNum = (uint64)-(int64)val; // Only flip if the encoded result would actually be shorter if (flippedNum <= 0x00FFFFFFFFFFFFFFLL) - { + { val = flippedNum; outStr.Append('_'); } @@ -5131,7 +5296,7 @@ String BfTypeUtils::HashEncode64(uint64 val) { int charIdx = val % 0x3F; val /= 0x3F; - outStr.Append(cHash64bToChar[charIdx]); + outStr.Append(cHash64bToChar[charIdx]); } return outStr; @@ -5157,7 +5322,7 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode) return ""; if (auto typeDefTypeRef = BfNodeDynCast(typeRef)) - { + { if (!typeDefTypeRef->mTypeDef->mNamespace.IsEmpty()) return typeDefTypeRef->mTypeDef->mNamespace.ToString() + "." + typeDefTypeRef->mTypeDef->mName->mString; else @@ -5165,12 +5330,12 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode) } if (typeRef->IsNamedTypeReference()) - { + { return typeRef->ToString(); } if (auto ptrType = BfNodeDynCast(typeRef)) - return TypeToString(ptrType->mElementType) + "*"; + return TypeToString(ptrType->mElementType) + "*"; if (auto ptrType = BfNodeDynCast(typeRef)) { String name = TypeToString(ptrType->mElementType) + "["; @@ -5220,7 +5385,7 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode) { if (i > 0) name += ", "; - name += TypeToString(tupleTypeRef->mFieldTypes[i]); + name += TypeToString(tupleTypeRef->mFieldTypes[i]); if ((i < tupleTypeRef->mFieldNames.size()) && (tupleTypeRef->mFieldNames[i] != NULL)) { name += " "; @@ -5246,9 +5411,9 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode) bool BfTypeUtils::TypeEquals(BfType* typeA, BfType* typeB, BfTypeInstance* selfType) { if (typeA->IsUnspecializedTypeVariation()) - typeA = selfType->mModule->ResolveSelfType(typeA, selfType); + typeA = selfType->mModule->ResolveSelfType(typeA, selfType); if (typeB->IsUnspecializedTypeVariation()) - typeB = selfType->mModule->ResolveSelfType(typeB, selfType); + typeB = selfType->mModule->ResolveSelfType(typeB, selfType); return typeA == typeB; } @@ -5260,7 +5425,7 @@ String BfTypeUtils::TypeToString(BfTypeDef* typeDef, BfTypeNameFlags typeNameFla } bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags) -{ +{ auto checkTypeDef = typeDef; char needsSep = 0; @@ -5268,7 +5433,7 @@ bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFl { if (TypeToString(str, checkTypeDef->mOuterType, typeNameFlags)) { - if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0) + if ((typeNameFlags & BfTypeNameFlag_InternalName) != 0) needsSep = '+'; else needsSep = '.'; @@ -5280,15 +5445,15 @@ bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFl { typeDef->mNamespace.ToString(str); needsSep = '.'; - } + } } if (needsSep != 0) str += needsSep; - + if (((typeNameFlags & BfTypeNameFlag_HideGlobalName) != 0) && (typeDef->IsGlobalsContainer())) return false; - + typeDef->mName->ToString(str); if (typeDef->mGenericParamDefs.size() != 0) @@ -5296,7 +5461,7 @@ bool BfTypeUtils::TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFl int prevGenericParamCount = 0; if (checkTypeDef->mOuterType != NULL) prevGenericParamCount = (int)typeDef->mOuterType->mGenericParamDefs.size(); - + if (prevGenericParamCount != (int)checkTypeDef->mGenericParamDefs.size()) { str += "<"; @@ -5332,4 +5497,4 @@ BfConstExprValueType::~BfConstExprValueType() { // mContext->mTypeConstExprCount--; // BF_ASSERT(mContext->mTypeConstExprCount == 0); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index f2f69ec6..98c054c0 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -28,7 +28,7 @@ enum BfResolveTypeRefFlags BfResolveTypeRefFlag_AllowGenericMethodParamConstValue = 0x20, BfResolveTypeRefFlag_AllowGenericParamConstValue = 0x10 | 0x20, BfResolveTypeRefFlag_AutoComplete = 0x40, - BfResolveTypeRefFlag_FromIndirectSource = 0x80, // Such as a type alias or a generic parameter + BfResolveTypeRefFlag_FromIndirectSource = 0x80, // Such as a type alias or a generic parameter BfResolveTypeRefFlag_Attribute = 0x100, BfResolveTypeRefFlag_NoReify = 0x200, BfResolveTypeRefFlag_NoCreate = 0x400, @@ -40,7 +40,8 @@ enum BfResolveTypeRefFlags BfResolveTypeRefFlag_AllowGlobalsSelf = 0x10000, BfResolveTypeRefFlag_AllowImplicitConstExpr = 0x20000, BfResolveTypeRefFlag_AllowUnboundGeneric = 0x40000, - BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000 + BfResolveTypeRefFlag_ForceUnboundGeneric = 0x80000, + BfResolveTypeRefFlag_IgnoreProtection = 0x100000 }; enum BfTypeNameFlags : uint16 @@ -52,9 +53,9 @@ enum BfTypeNameFlags : uint16 BfTypeNameFlag_OmitOuterType = 8, BfTypeNameFlag_ReduceName = 0x10, BfTypeNameFlag_UseArrayImplType = 0x20, - BfTypeNameFlag_DisambiguateDups = 0x40, // Add a disambiguation if mDupDetectedRevision is set + BfTypeNameFlag_DisambiguateDups = 0x40, // Add a disambiguation if mDupDetectedRevision is set BfTypeNameFlag_AddGlobalContainerName = 0x80, - BfTypeNameFlag_InternalName = 0x100, // Use special delimiters to remove ambiguities (ie: '+' for inner types) + BfTypeNameFlag_InternalName = 0x100, // Use special delimiters to remove ambiguities (ie: '+' for inner types) BfTypeNameFlag_HideGlobalName = 0x200, BfTypeNameFlag_ExtendedInfo = 0x400, BfTypeNameFlag_ShortConst = 0x800, @@ -123,7 +124,7 @@ public: DependencyFlag_Allocates = 0x800000, DependencyFlag_NameReference = 0x1000000, DependencyFlag_VirtualCall = 0x2000000, - DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild + DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild DependencyFlag_ValueTypeSizeDep = 0x8000000, // IE: int32[DepType.cVal] DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef) @@ -131,18 +132,18 @@ public: struct DependencyEntry { - int mRevision; + int mRevision; DependencyFlags mFlags; DependencyEntry(int revision, DependencyFlags flags) { - mRevision = revision; - mFlags = flags; + mRevision = revision; + mFlags = flags; } }; public: - typedef Dictionary TypeMap; + typedef Dictionary TypeMap; DependencyFlags mFlagsUnion; TypeMap mTypeSet; int mMinDependDepth; @@ -154,11 +155,11 @@ public: mFlagsUnion = DependencyFlag_None; } - bool AddUsedBy(BfType* dependentType, DependencyFlags flags); + bool AddUsedBy(BfType* dependentType, DependencyFlags flags); bool IsEmpty(); TypeMap::iterator begin(); TypeMap::iterator end(); - TypeMap::iterator erase(TypeMap::iterator& itr); + TypeMap::iterator erase(TypeMap::iterator& itr); }; class BfDepContext @@ -179,7 +180,7 @@ enum BfHotDepDataKind : int8 BfHotDepDataKind_Unknown, BfHotDepDataKind_TypeVersion, BfHotDepDataKind_ThisType, - BfHotDepDataKind_Allocation, + BfHotDepDataKind_Allocation, BfHotDepDataKind_Method, BfHotDepDataKind_DupMethod, BfHotDepDataKind_DevirtualizedMethod, @@ -217,7 +218,7 @@ public: #ifdef _DEBUG virtual ~BfHotDepData() - { + { BF_ASSERT(mRefCount == 0); } #endif @@ -226,12 +227,12 @@ public: struct BfHotTypeDataEntry { public: - String mFuncName; // Name of original virtual function, not overrides + String mFuncName; // Name of original virtual function, not overrides }; class BfHotTypeVersion : public BfHotDepData { -public: +public: Val128 mDataHash; // Determines when the user's declaration changed - changes do not cascade into including types BfHotTypeVersion* mBaseType; Array mMembers; // Struct members directly included (not via pointers) @@ -239,13 +240,13 @@ public: int mCommittedHotCompileIdx; int mTypeId; - Array mInterfaceMapping; + Array mInterfaceMapping; bool mPopulatedInterfaceMapping; BfHotTypeVersion() { mBaseType = NULL; - mDataKind = BfHotDepDataKind_TypeVersion; + mDataKind = BfHotDepDataKind_TypeVersion; mPopulatedInterfaceMapping = 0; } @@ -266,7 +267,7 @@ public: ~BfHotThisType() { - mTypeVersion->Deref(); + mTypeVersion->Deref(); } }; @@ -284,7 +285,7 @@ public: ~BfHotAllocation() { - mTypeVersion->Deref(); + mTypeVersion->Deref(); } }; @@ -293,24 +294,24 @@ public: class BfHotMethod : public BfHotDepData { -public: +public: #ifdef BF_DBG_HOTMETHOD_NAME String mMangledName; #endif #ifdef BF_DBG_HOTMETHOD_IDX int mMethodIdx; -#endif - BfHotTypeVersion* mSrcTypeVersion; +#endif + BfHotTypeVersion* mSrcTypeVersion; Array mReferences; - BfHotMethod* mPrevVersion; + BfHotMethod* mPrevVersion; BfHotMethod() { #ifdef BF_DBG_HOTMETHOD_IDX mMethodIdx = -1; -#endif +#endif mDataKind = BfHotDepDataKind_Method; - mSrcTypeVersion = NULL; + mSrcTypeVersion = NULL; mPrevVersion = NULL; } void Clear(bool keepDupMethods = false); @@ -336,7 +337,6 @@ public: } }; - class BfHotDevirtualizedMethod : public BfHotDepData { public: @@ -351,7 +351,7 @@ public: ~BfHotDevirtualizedMethod() { - mMethod->Deref(); + mMethod->Deref(); } }; @@ -369,7 +369,7 @@ public: ~BfHotFunctionReference() { - mMethod->Deref(); + mMethod->Deref(); } }; @@ -387,7 +387,7 @@ public: ~BfHotInnerMethod() { - mMethod->Deref(); + mMethod->Deref(); } }; @@ -405,15 +405,15 @@ public: ~BfHotVirtualDeclaration() { - mMethod->Deref(); + mMethod->Deref(); } }; class BfHotDataReferenceBuilder { -public: - HashSet mAllocatedData; // Any usage that depends on size or layout - HashSet mUsedData; // Any usage that depends on size or layout +public: + HashSet mAllocatedData; // Any usage that depends on size or layout + HashSet mUsedData; // Any usage that depends on size or layout HashSet mCalledMethods; HashSet mDevirtualizedCalledMethods; HashSet mFunctionPtrs; @@ -430,7 +430,7 @@ enum BfTypeRebuildFlags BfTypeRebuildFlag_StaticChange = 1, BfTypeRebuildFlag_NonStaticChange = 2, BfTypeRebuildFlag_MethodInlineInternalsChange = 4, - BfTypeRebuildFlag_MethodSignatureChange = 8, + BfTypeRebuildFlag_MethodSignatureChange = 8, BfTypeRebuildFlag_ConstEvalChange = 0x10, BfTypeRebuildFlag_ConstEvalFieldChange = 0x20, BfTypeRebuildFlag_DeleteQueued = 0x40, @@ -457,7 +457,7 @@ enum BfTypeDefineState : uint8 BfTypeDefineState_Undefined, BfTypeDefineState_Declaring, BfTypeDefineState_Declared, - BfTypeDefineState_ResolvingBaseType, + BfTypeDefineState_ResolvingBaseType, BfTypeDefineState_HasInterfaces_Direct, BfTypeDefineState_CETypeInit, BfTypeDefineState_CEPostTypeInit, @@ -472,7 +472,7 @@ class BfDelegateInfo { public: Array mDirectAllocNodes; - BfType* mReturnType; + BfType* mReturnType; Array mParams; bool mHasExplicitThis; bool mHasVarArgs; @@ -498,7 +498,7 @@ enum BfTypeUsage { BfTypeUsage_Unspecified, BfTypeUsage_Return_Static, - BfTypeUsage_Return_NonStatic, + BfTypeUsage_Return_NonStatic, BfTypeUsage_Parameter, }; @@ -506,28 +506,28 @@ class BfType { public: BfTypeRebuildFlags mRebuildFlags; - + BfContext* mContext; int mTypeId; int mRevision; - - // For Objects, align and size is ref-sized (object*). + + // For Objects, align and size is ref-sized (object*). // Use mInstSize/mInstAlign for actual data size/align - int mSize; - int16 mAlign; + int mSize; + int16 mAlign; bool mDirty; BfTypeDefineState mDefineState; public: - BfType(); + BfType(); virtual ~BfType(); - + BfTypeInstance* FindUnderlyingTypeInstance(); virtual BfModule* GetModule(); - - int GetStride() { return BF_ALIGN(mSize, mAlign); } - bool IsSizeAligned() { return (mSize == 0) || (mSize % mAlign == 0); } + + int GetStride() { return BF_ALIGN(mSize, mAlign); } + bool IsSizeAligned() { return (mSize == 0) || (mSize % mAlign == 0); } virtual bool IsInstanceOf(BfTypeDef* typeDef) { return false; } virtual bool HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; } @@ -537,11 +537,11 @@ public: virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; } virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); } virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; } - + virtual BfDependedType* ToDependedType() { return NULL; } virtual BfTypeInstance* ToTypeInstance() { return NULL; } virtual BfTypeInstance* ToGenericTypeInstance() { return NULL; } - virtual BfPrimitiveType* ToPrimitiveType() { return NULL; } + virtual BfPrimitiveType* ToPrimitiveType() { return NULL; } virtual bool IsDependendType() { return false; } virtual int GetGenericDepth() { return 0; } virtual bool IsTypeInstance() { return false; } @@ -559,10 +559,10 @@ public: virtual bool IsValuelessType() { BF_ASSERT(mSize != -1); BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); return mSize == 0; } virtual bool IsSelf() { return false; } virtual bool IsDot() { return false; } - virtual bool IsVar() { return false; } + virtual bool IsVar() { return false; } virtual bool IsLet() { return false; } virtual bool IsNull(){ return false; } - virtual bool IsNullable() { return false; } + virtual bool IsNullable() { return false; } virtual bool IsBoxed() { return false; } virtual bool IsInterface() { return false; } virtual bool IsEnum() { return false; } @@ -572,7 +572,7 @@ public: virtual bool IsStruct() { return false; } virtual bool IsStructPtr() { return false; } virtual bool IsUnion() { return false; } - virtual bool IsStructOrStructPtr() { return false; } + virtual bool IsStructOrStructPtr() { return false; } virtual bool IsObject() { return false; } virtual bool IsObjectOrStruct() { return false; } virtual bool IsObjectOrInterface() { return false; } @@ -580,18 +580,18 @@ public: virtual bool IsSizedArray() { return false; } virtual bool IsUndefSizedArray() { return false; } virtual bool IsUnknownSizedArrayType() { return false; } - virtual bool IsArray() { return false; } + virtual bool IsArray() { return false; } virtual bool IsDelegate() { return false; } virtual bool IsFunction() { return false; } virtual bool IsDelegateOrFunction() { return false; } virtual bool IsDelegateFromTypeRef() { return false; } virtual bool IsFunctionFromTypeRef() { return false; } virtual BfDelegateInfo* GetDelegateInfo() { return NULL; } - virtual bool IsValueType() { return false; } + virtual bool IsValueType() { return false; } virtual bool IsOpaque() { return false; } - virtual bool IsValueTypeOrValueTypePtr() { return false; } + virtual bool IsValueTypeOrValueTypePtr() { return false; } virtual bool IsWrappableType() { return false; } - virtual bool IsPrimitiveType() { return false; } + virtual bool IsPrimitiveType() { return false; } virtual BfTypeCode GetTypeCode() { return BfTypeCode_None; } virtual bool IsBoolean() { return false; } virtual bool IsInteger() { return false; } @@ -602,22 +602,22 @@ public: virtual bool IsSignedInt() { return false; } virtual bool IsIntUnknown() { return false; } virtual bool IsChar() { return false; } - virtual bool IsFloat() { return false; } + virtual bool IsFloat() { return false; } virtual bool IsPointer() { return false; } virtual bool IsAllocType() { return false; } - virtual bool IsIntPtrable() { return false; } - virtual bool IsRef() { return false; } + virtual bool IsIntPtrable() { return false; } + virtual bool IsRef() { return false; } virtual bool IsMut() { return false; } virtual bool IsIn() { return false; } virtual bool IsOut() { return false; } virtual bool IsGenericParam() { return false; } virtual bool IsTypeGenericParam() { return false; } virtual bool IsMethodGenericParam() { return false; } - virtual bool IsClosure() { return false; } + virtual bool IsClosure() { return false; } virtual bool IsMethodRef() { return false; } virtual bool IsTuple() { return false; } virtual bool IsOnDemand() { return false; } - virtual bool IsTemporary() { return false; } + virtual bool IsTemporary() { return false; } virtual bool IsModifiedTypeType() { return false; } virtual bool IsConcreteInterfaceType() { return false; } virtual bool IsTypeAlias() { return false; } @@ -626,7 +626,7 @@ public: virtual bool IsDependentOnUnderlyingType() { return false; } virtual bool WantsGCMarking() { return false; } virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) { return false; } - virtual BfType* GetUnderlyingType() { return NULL; } + virtual BfType* GetUnderlyingType() { return NULL; } virtual bool HasWrappedRepresentation() { return IsWrappableType(); } virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; } @@ -647,7 +647,7 @@ public: mGenericDepth = 0; } - virtual int GetGenericDepth() override { return mGenericDepth; } + virtual int GetGenericDepth() override { return mGenericDepth; } }; // This is explicitly used for generics @@ -658,7 +658,7 @@ class BfPrimitiveType : public BfType { public: BfTypeDef* mTypeDef; - + public: virtual bool IsPrimitiveType() override { return true; } virtual BfTypeCode GetTypeCode() override { return mTypeDef->mTypeCode; } @@ -671,31 +671,31 @@ public: virtual bool IsBoolean() override { return mTypeDef->mTypeCode == BfTypeCode_Boolean; } virtual bool IsIntegral() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); } virtual bool IsIntegralOrBool() override { return (mTypeDef->mTypeCode >= BfTypeCode_Boolean) && (mTypeDef->mTypeCode <= BfTypeCode_Char32); } - virtual bool IsInteger() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_UIntUnknown); } + virtual bool IsInteger() override { return (mTypeDef->mTypeCode >= BfTypeCode_Int8) && (mTypeDef->mTypeCode <= BfTypeCode_UIntUnknown); } virtual bool IsIntPtr() override { return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr); } - virtual bool IsIntPtrable() override - { + virtual bool IsIntPtrable() override + { return (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_UIntPtr) || ((mTypeDef->mSystem->mPtrSize == 8) && ((mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_UInt64))) || ((mTypeDef->mSystem->mPtrSize == 4) && ((mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_UInt32))); } - virtual bool IsSigned() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || - (mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || + virtual bool IsSigned() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || + (mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); } - virtual bool IsSignedInt() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || + virtual bool IsSignedInt() override { return (mTypeDef->mTypeCode == BfTypeCode_Int8) || (mTypeDef->mTypeCode == BfTypeCode_Int16) || (mTypeDef->mTypeCode == BfTypeCode_Int32) || (mTypeDef->mTypeCode == BfTypeCode_Int64) || (mTypeDef->mTypeCode == BfTypeCode_IntPtr) || (mTypeDef->mTypeCode == BfTypeCode_IntUnknown); } virtual bool IsIntUnknown() override { return (mTypeDef->mTypeCode == BfTypeCode_IntUnknown) || (mTypeDef->mTypeCode == BfTypeCode_UIntUnknown); } virtual bool IsChar() override { return (mTypeDef->mTypeCode == BfTypeCode_Char8) || (mTypeDef->mTypeCode == BfTypeCode_Char16) || (mTypeDef->mTypeCode == BfTypeCode_Char32); } virtual bool IsFloat() override { return (mTypeDef->mTypeCode == BfTypeCode_Float) || (mTypeDef->mTypeCode == BfTypeCode_Double); } virtual bool IsNull() override { return mTypeDef->mTypeCode == BfTypeCode_NullPtr; } - virtual bool IsVoid() override { return mTypeDef->mTypeCode == BfTypeCode_None; } + virtual bool IsVoid() override { return mTypeDef->mTypeCode == BfTypeCode_None; } virtual bool CanBeValuelessType() override { return mTypeDef->mTypeCode == BfTypeCode_None; } virtual bool IsValuelessType() override { return mTypeDef->mTypeCode == BfTypeCode_None; } virtual bool IsSelf() override { return mTypeDef->mTypeCode == BfTypeCode_Self; } virtual bool IsDot() override { return mTypeDef->mTypeCode == BfTypeCode_Dot; } - virtual bool IsVar() override { return mTypeDef->mTypeCode == BfTypeCode_Var; } + virtual bool IsVar() override { return mTypeDef->mTypeCode == BfTypeCode_Var; } virtual bool IsLet() override { return mTypeDef->mTypeCode == BfTypeCode_Let; } virtual bool IsUnspecializedType() override { return mTypeDef->mTypeCode == BfTypeCode_Self; } virtual bool IsUnspecializedTypeVariation() override { return mTypeDef->mTypeCode == BfTypeCode_Self; } @@ -719,7 +719,7 @@ public: public: BfDeferredMethodCallData() - { + { mAlign = 0; mSize = 0; mMethodId = 0; @@ -747,7 +747,7 @@ public: class BfMethodParam { -public: +public: BfType* mResolvedType; int16 mParamDefIdx; int16 mDelegateParamIdx; @@ -758,7 +758,7 @@ public: public: BfMethodParam() - { + { mResolvedType = NULL; mParamDefIdx = -1; mDelegateParamIdx = -1; @@ -766,7 +766,7 @@ public: mWasGenericParam = false; mIsSplat = false; mReferencedInConstPass = false; - } + } BfMethodInstance* GetDelegateParamInvoke(); }; @@ -834,7 +834,7 @@ public: { mThisOverride = NULL; mLocalMethod = NULL; - mCaptureClosureState = NULL; + mCaptureClosureState = NULL; } }; @@ -849,7 +849,7 @@ public: BfTypeVector mMethodGenericArguments; Dictionary mGenericTypeBindings; BfMethodCustomAttributes* mMethodCustomAttributes; - int mMinDependDepth; + int mMinDependDepth; BfMethodInfoEx() { @@ -857,10 +857,10 @@ public: mForeignType = NULL; mClosureInstanceInfo = NULL; mMethodCustomAttributes = NULL; - mMinDependDepth = -1; + mMinDependDepth = -1; } - - ~BfMethodInfoEx(); + + ~BfMethodInfoEx(); }; enum BfImportCallKind @@ -872,7 +872,7 @@ enum BfImportCallKind class BfMethodInstance { -public: +public: int mVirtualTableIdx; BfIRFunction mIRFunction; // Only valid for owning module int16 mAppendAllocAlign; @@ -892,12 +892,12 @@ public: bool mIsAutocompleteMethod:1; bool mRequestedByAutocomplete : 1; bool mIsClosure:1; - bool mMayBeConst:1; // Only used for calcAppend currently + bool mMayBeConst:1; // Only used for calcAppend currently bool mIsForeignMethodDef:1; bool mAlwaysInline:1; bool mIsIntrinsic:1; bool mHasMethodRefType:1; - bool mDisallowCalling:1; + bool mDisallowCalling:1; bool mIsInnerOverride:1; bool mInCEMachine:1; bool mCeCancelled:1; @@ -908,19 +908,19 @@ public: BfMethodInstanceGroup* mMethodInstanceGroup; BfMethodDef* mMethodDef; BfType* mReturnType; - Array mParams; + Array mParams; Array mDefaultValues; BfModule* mDeclModule; - BfMethodProcessRequest* mMethodProcessRequest; - BfMethodInfoEx* mMethodInfoEx; - int64 mIdHash; // Collisions are (essentially) benign + BfMethodProcessRequest* mMethodProcessRequest; + BfMethodInfoEx* mMethodInfoEx; + int64 mIdHash; // Collisions are (essentially) benign BfHotMethod* mHotMethod; public: BfMethodInstance() - { - mVirtualTableIdx = -1; - mIsUnspecialized = false; + { + mVirtualTableIdx = -1; + mIsUnspecialized = false; mIsUnspecializedVariation = false; mIsReified = true; mHasStartedDeclaration = false; @@ -935,7 +935,7 @@ public: mIsAutocompleteMethod = false; mRequestedByAutocomplete = false; mIsClosure = false; - mMayBeConst = true; + mMayBeConst = true; mIsForeignMethodDef = false; mAlwaysInline = false; mIsIntrinsic = false; @@ -949,14 +949,14 @@ public: mComptimeFlags = BfComptimeFlag_None; mCallingConvention = BfCallingConvention_Unspecified; mMethodInstanceGroup = NULL; - mMethodDef = NULL; - mReturnType = NULL; + mMethodDef = NULL; + mReturnType = NULL; mIdHash = 0; - mAppendAllocAlign = -1; + mAppendAllocAlign = -1; mEndingAppendAllocAlign = -1; - mDeclModule = NULL; + mDeclModule = NULL; mMethodProcessRequest = NULL; - mMethodInfoEx = NULL; + mMethodInfoEx = NULL; mHotMethod = NULL; } @@ -973,14 +973,14 @@ public: BfImportKind GetImportKind(); BfMethodFlags GetMethodFlags(); void UndoDeclaration(bool keepIRFunction = false); - BfTypeInstance* GetOwner(); + BfTypeInstance* GetOwner(); BfModule* GetModule(); bool IsSpecializedGenericMethod(); bool IsSpecializedGenericMethodOrType(); bool IsSpecializedByAutoCompleteMethod(); bool IsOrInUnspecializedVariation(); bool HasExternConstraints(); - bool HasThis(); + bool HasThis(); bool IsVirtual(); BfType* GetThisType(); int GetThisIdx(); @@ -988,17 +988,17 @@ public: bool HasParamsArray(); int GetStructRetIdx(bool forceStatic = false); bool HasSelf(); - bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL, bool forceStatic = false); + bool GetLoweredReturnType(BfTypeCode* loweredTypeCode = NULL, BfTypeCode* loweredTypeCode2 = NULL, bool forceStatic = false); bool WantsStructsAttribByVal(BfType* paramType); bool IsAutocompleteMethod() { /*return mIdHash == -1;*/ return mIsAutocompleteMethod; } - bool IsSkipCall(bool bypassVirtual = false); + bool IsSkipCall(bool bypassVirtual = false); bool IsVarArgs(); bool AlwaysInline(); - BfImportCallKind GetImportCallKind(); + BfImportCallKind GetImportCallKind(); bool IsTestMethod(); bool AllowsSplatting(int paramIdx); int GetParamCount(); - int GetImplicitParamCount(); + int GetImplicitParamCount(); void GetParamName(int paramIdx, StringImpl& name, int& namePrefixCount); String GetParamName(int paramIdx); String GetParamName(int paramIdx, int& namePrefixCount); @@ -1016,8 +1016,8 @@ public: void GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl& paramTypes, bool forceStatic = false); int GetIRFunctionParamCount(BfModule* module); - bool IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams = false, bool checkThis = false); - bool IsReifiedAndImplemented(); + bool IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams = false, bool checkThis = false); + bool IsReifiedAndImplemented(); BfMethodInfoEx* GetMethodInfoEx(); BfCustomAttributes* GetCustomAttributes() @@ -1087,14 +1087,14 @@ public: public: BfModuleMethodInstance() { - mMethodInstance = NULL; + mMethodInstance = NULL; } - BfModuleMethodInstance(BfMethodInstance* methodInstance); + BfModuleMethodInstance(BfMethodInstance* methodInstance); BfModuleMethodInstance(BfMethodInstance* methodInstance, BfIRValue func) : mFunc(func) { - mMethodInstance = methodInstance; + mMethodInstance = methodInstance; } operator bool() const @@ -1114,7 +1114,7 @@ class BfGenericParamType : public BfType public: BfGenericParamKind mGenericParamKind; int mGenericParamIdx; - + public: bool IsGenericParam() override { return true; } bool IsTypeGenericParam() override { return mGenericParamKind == BfGenericParamKind_Type; } @@ -1137,7 +1137,7 @@ public: virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); } virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedType(); } virtual bool IsReified() override { return mElementType->IsReified(); } - virtual bool IsDependentOnUnderlyingType() override { return true; } + virtual bool IsDependentOnUnderlyingType() override { return true; } virtual bool IsAllocType() override { return mModifiedKind == BfToken_AllocType; } virtual BfType* GetUnderlyingType() override { return mElementType; } }; @@ -1172,9 +1172,9 @@ public: } }; -class BfGenericParamInstance +class BfGenericParamInstance { -public: +public: BfGenericParamFlags mGenericParamFlags; BfType* mExternType; Array mInterfaceConstraints; @@ -1197,7 +1197,7 @@ public: { if (--mRefCount == 0) delete this; - } + } virtual ~BfGenericParamInstance() { @@ -1206,7 +1206,7 @@ public: virtual BfConstraintDef* GetConstraintDef() = 0; virtual BfGenericParamDef* GetGenericParamDef() = 0; virtual BfExternalConstraintDef* GetExternConstraintDef() = 0; - virtual String GetName() = 0; + virtual String GetName() = 0; virtual BfAstNode* GetRefNode() = 0; bool IsEnum(); }; @@ -1328,7 +1328,7 @@ public: #define BF_VALCOMP(val) if (val != 0) return val struct BfTypeVectorHash -{ +{ size_t operator()(const BfTypeVector& val) const; }; @@ -1341,10 +1341,10 @@ struct BfTypeVectorEquals class BfMethodInstanceGroup { public: - BfTypeInstance* mOwner; - BfMethodInstance* mDefault; + BfTypeInstance* mOwner; + BfMethodInstance* mDefault; typedef Dictionary MapType; - MapType* mMethodSpecializationMap; + MapType* mMethodSpecializationMap; BfCustomAttributes* mDefaultCustomAttributes; int mMethodIdx; int mRefCount; // External references from BfMethodRefType @@ -1365,13 +1365,13 @@ public: mExplicitlyReflected = false; mHasEmittedReference = false; } - + BfMethodInstanceGroup(BfMethodInstanceGroup&& prev) noexcept; - ~BfMethodInstanceGroup(); + ~BfMethodInstanceGroup(); bool IsImplemented() { - return (mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || + return (mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (mOnDemandKind == BfMethodOnDemandKind_Referenced) || (mOnDemandKind == BfMethodOnDemandKind_InWorkList); } @@ -1380,8 +1380,8 @@ public: class BfFieldInstance { public: - BfTypeInstance* mOwner; - BfType* mResolvedType; + BfTypeInstance* mOwner; + BfType* mResolvedType; BfCustomAttributes* mCustomAttributes; int mConstIdx; int mFieldIdx; @@ -1397,16 +1397,16 @@ public: int mLastRevisionReferenced; public: - BfFieldDef* GetFieldDef(); + BfFieldDef* GetFieldDef(); BfFieldInstance(BfFieldInstance&& copyFrom) { mCustomAttributes = copyFrom.mCustomAttributes; copyFrom.mCustomAttributes = NULL; - mOwner = copyFrom.mOwner; + mOwner = copyFrom.mOwner; mResolvedType = copyFrom.mResolvedType; - + mCustomAttributes = copyFrom.mCustomAttributes; mConstIdx = copyFrom.mConstIdx; mFieldIdx = copyFrom.mFieldIdx; @@ -1414,12 +1414,12 @@ public: mMergedDataIdx = copyFrom.mMergedDataIdx; mDataOffset = copyFrom.mDataOffset; mDataSize = copyFrom.mDataSize; - mFieldIncluded = copyFrom.mFieldIncluded; + mFieldIncluded = copyFrom.mFieldIncluded; mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase; mIsThreadLocal = copyFrom.mIsThreadLocal; - mIsInferredType = copyFrom.mIsInferredType; + mIsInferredType = copyFrom.mIsInferredType; mHadConstEval = copyFrom.mHadConstEval; - mLastRevisionReferenced = copyFrom.mLastRevisionReferenced; + mLastRevisionReferenced = copyFrom.mLastRevisionReferenced; } BfFieldInstance(const BfFieldInstance& copyFrom) @@ -1447,10 +1447,10 @@ public: BfFieldInstance() { mFieldIdx = -1; - mOwner = NULL; + mOwner = NULL; mResolvedType = NULL; mIsEnumPayloadCase = false; - mCustomAttributes = NULL; + mCustomAttributes = NULL; mConstIdx = -1; mDataIdx = -1; mMergedDataIdx = -1; @@ -1461,7 +1461,7 @@ public: mIsInferredType = false; mHadConstEval = false; mLastRevisionReferenced = -1; - } + } ~BfFieldInstance(); @@ -1469,6 +1469,7 @@ public: void SetResolvedType(BfType* type); void GetDataRange(int& dataIdx, int& dataCount); int GetAlign(int packing); + bool IsAppendedObject(); }; enum BfMethodRefKind @@ -1485,7 +1486,7 @@ public: { int mMethodNum; BfMethodRefKind mKind; - }; + }; int mSignatureHash; BfNonGenericMethodRef() @@ -1503,7 +1504,7 @@ public: BfNonGenericMethodRef& operator=(BfMethodInstance* methodInstance); bool operator==(const BfNonGenericMethodRef& methodRef) const; bool operator==(BfMethodInstance* methodInstance) const; - + struct Hash { size_t operator()(const BfNonGenericMethodRef& val) const; @@ -1526,13 +1527,13 @@ enum BfMethodRefFlags : uint8 class BfMethodRef { -public: +public: BfTypeInstance* mTypeInstance; union { int mMethodNum; BfMethodRefKind mKind; - }; + }; Array mMethodGenericArguments; int mSignatureHash; BfMethodRefFlags mMethodRefFlags; @@ -1545,7 +1546,7 @@ public: mMethodRefFlags = BfMethodRefFlag_None; } - BfMethodRef(BfMethodInstance* methodInstance); + BfMethodRef(BfMethodInstance* methodInstance); operator BfMethodInstance*() const; bool IsNull() { return mTypeInstance == NULL; }; @@ -1553,9 +1554,9 @@ public: BfMethodRef& operator=(BfMethodInstance* methodInstance); bool operator==(const BfMethodRef& methodRef) const; bool operator==(BfMethodInstance* methodInstance) const; - + struct Hash - { + { size_t operator()(const BfMethodRef& val) const; }; @@ -1608,18 +1609,18 @@ public: } BfPropertyRef(BfTypeInstance* typeInst, BfPropertyDef* propDef); - + operator BfPropertyDef*() const; }; class BfTypeInterfaceEntry { -public: +public: BfTypeDef* mDeclaringType; BfTypeInstance* mInterfaceType; int mStartInterfaceTableIdx; int mStartVirtualIdx; // Relative to start of virtual interface methods - bool mIsRedeclared; + bool mIsRedeclared; }; class BfTypeInterfaceMethodEntry @@ -1654,7 +1655,7 @@ enum BfAttributeTargets : int32 BfAttributeTargets_Parameter = 0x0800, BfAttributeTargets_Delegate = 0x1000, BfAttributeTargets_Function = 0x2000, - BfAttributeTargets_ReturnValue = 0x4000, + BfAttributeTargets_ReturnValue = 0x4000, BfAttributeTargets_GenericParameter = 0x8000, BfAttributeTargets_Invocation = 0x10000, BfAttributeTargets_MemberAccess = 0x20000, @@ -1693,25 +1694,25 @@ public: class BfHotTypeData { -public: +public: Array mTypeVersions; - Array mVTableEntries; // Doesn't fill in until we rebuild or delete type + Array mVTableEntries; // Doesn't fill in until we rebuild or delete type int mVTableOrigLength; int mOrigInterfaceMethodsLength; bool mPendingDataChange; bool mHadDataChange; // True if we have EVER had a hot data change - + public: BfHotTypeData() { mVTableOrigLength = -1; - mOrigInterfaceMethodsLength = -1; + mOrigInterfaceMethodsLength = -1; mPendingDataChange = false; mHadDataChange = false; } ~BfHotTypeData(); - + BfHotTypeVersion* GetTypeVersion(int hotCommitedIdx); BfHotTypeVersion* GetLatestVersion(); BfHotTypeVersion* GetLatestVersionHead(); // The oldest version that has the same data @@ -1722,7 +1723,7 @@ struct BfTypeLookupEntry { BfAtomComposite mName; int mNumGenericParams; - uint32 mAtomUpdateIdx; + uint32 mAtomUpdateIdx; BfTypeDef* mUseTypeDef; bool operator==(const BfTypeLookupEntry& rhs) const @@ -1799,10 +1800,10 @@ struct BfVirtualMethodEntry struct BfSpecializedMethodRefInfo { bool mHasReifiedRef; - + BfSpecializedMethodRefInfo() { - mHasReifiedRef = false; + mHasReifiedRef = false; } }; @@ -1819,21 +1820,93 @@ public: Array mNamespaces; }; +class BfUsingFieldData +{ +public: + struct MemberRef + { + enum Kind + { + Kind_None, + Kind_Field, + Kind_Property, + Kind_Method, + Kind_Local + }; + + BfTypeInstance* mTypeInstance; + Kind mKind; + int mIdx; + + MemberRef() + { + mTypeInstance = NULL; + mKind = Kind_None; + mIdx = -1; + } + + MemberRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef) + { + mTypeInstance = typeInst; + mKind = Kind_Field; + mIdx = fieldDef->mIdx; + } + + MemberRef(BfTypeInstance* typeInst, BfMethodDef* methodDef) + { + mTypeInstance = typeInst; + mKind = Kind_Method; + mIdx = methodDef->mIdx; + } + + MemberRef(BfTypeInstance* typeInst, BfPropertyDef* propDef) + { + mTypeInstance = typeInst; + mKind = Kind_Property; + mIdx = propDef->mIdx; + } + + BfProtection GetProtection() const; + BfProtection GetUsingProtection() const; + BfTypeDef* GetDeclaringType(BfModule* curModule) const; + String GetFullName(BfModule* curModule) const; + String GetName(BfModule* curModule) const; + BfAstNode* GetRefNode(BfModule* curModule) const; + bool IsStatic() const; + }; + + struct Entry + { + SizedArray, 1> mLookups; + }; + +public: + Dictionary mEntries; + Dictionary mMethods; + HashSet mAwaitingPopulateSet; +}; + class BfTypeInfoEx { public: + BfUsingFieldData* mUsingFieldData; BfType* mUnderlyingType; int64 mMinValue; int64 mMaxValue; BfTypeInfoEx() { + mUsingFieldData = NULL; mUnderlyingType = NULL; mMinValue = 0; mMaxValue = 0; } -}; + ~BfTypeInfoEx() + { + delete mUsingFieldData; + } +}; class BfGenericExtensionEntry { @@ -1863,7 +1936,7 @@ public: void Clear() { - mExtensionMap.Clear(); + mExtensionMap.Clear(); } }; @@ -1882,7 +1955,7 @@ public: bool mValidatedGenericConstraints; bool mHadValidateErrors; bool mInitializedGenericParams; - bool mFinishedGenericParams; + bool mFinishedGenericParams; Array mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension int32 mMaxGenericDepth; @@ -1900,7 +1973,7 @@ public: } ~BfGenericTypeInfo(); - + void ReportMemory(MemReporter* memReporter); }; @@ -1929,41 +2002,41 @@ public: BfTypeInfoEx* mTypeInfoEx; BfGenericTypeInfo* mGenericTypeInfo; BfCeTypeInfo* mCeTypeInfo; - Array mInterfaces; - Array mInterfaceMethodTable; + Array mInterfaces; + Array mInterfaceMethodTable; Array mMethodInstanceGroups; Array mOperatorInfo; Array mVirtualMethodTable; Array mReifyMethodDependencies; - BfHotTypeData* mHotTypeData; - int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning) + BfHotTypeData* mHotTypeData; + int mVirtualMethodTableSize; // With hot reloading, mVirtualMethodTableSize can be larger than mInterfaceMethodTable (live vtable versioning) Array mFieldInstances; - Array mInternalMethods; + Array mInternalMethods; Dictionary mStaticSearchMap; Dictionary mInternalAccessMap; Array mOwnedLocalMethods; // Local methods in CEMachine bool mHasStaticInitMethod; bool mHasStaticDtorMethod; - bool mHasStaticMarkMethod; + bool mHasStaticMarkMethod; bool mHasTLSFindMethod; - BfIRConstHolder* mConstHolder; + BfIRConstHolder* mConstHolder; Dictionary mSpecializedMethodReferences; // Includes both specialized methods and OnDemand methods - // We store lookup results so we can rebuild this type if a name resolves differently due to a new type being created (ie: a type name found first in + // We store lookup results so we can rebuild this type if a name resolves differently due to a new type being created (ie: a type name found first in Dictionary mLookupResults; - + int mTypeOptionsIdx; - int mMergedFieldDataCount; + int mMergedFieldDataCount; int mInstAlign; - int mInstSize; + int mInstSize; int16 mInheritDepth; int16 mSlotNum; BfAlwaysIncludeFlags mAlwaysIncludeFlags; bool mHasBeenInstantiated; bool mIsReified; bool mIsTypedPrimitive; - bool mIsCRepr; - bool mIsUnion; + bool mIsCRepr; + bool mIsUnion; uint8 mPacking; bool mIsSplattable; bool mHasUnderlyingArray; @@ -1974,16 +2047,16 @@ public: bool mResolvingConstField; bool mSkipTypeProtectionChecks; bool mNeedsMethodProcessing; - bool mBaseTypeMayBeIncomplete; + bool mBaseTypeMayBeIncomplete; bool mHasParameterizedBase; // Generic, array, etc - bool mIsFinishingType; - bool mHasPackingHoles; + bool mIsFinishingType; + bool mHasPackingHoles; bool mWantsGCMarking; - bool mHasDeclError; + bool mHasDeclError; public: BfTypeInstance() - { + { mModule = NULL; mSignatureRevision = -1; mLastNonGenericUsedRevision = -1; @@ -2004,19 +2077,19 @@ public: mCeTypeInfo = NULL; //mClassVData = NULL; mVirtualMethodTableSize = 0; - mHotTypeData = NULL; + mHotTypeData = NULL; mHasStaticInitMethod = false; mHasStaticMarkMethod = false; - mHasStaticDtorMethod = false; + mHasStaticDtorMethod = false; mHasTLSFindMethod = false; mSlotNum = -1; mTypeOptionsIdx = -2; // -2 = not checked, -1 = none mInstSize = -1; mInstAlign = -1; - mInheritDepth = 0; + mInheritDepth = 0; mIsTypedPrimitive = false; mTypeIncomplete = true; - mIsCRepr = false; + mIsCRepr = false; mIsUnion = false; mTypeFailed = false; mTypeWarned = false; @@ -2026,20 +2099,20 @@ public: mBaseTypeMayBeIncomplete = false; mIsFinishingType = false; mResolvingConstField = false; - mHasPackingHoles = false; + mHasPackingHoles = false; mAlwaysIncludeFlags = BfAlwaysIncludeFlag_None; - mHasBeenInstantiated = false; + mHasBeenInstantiated = false; mWantsGCMarking = false; mHasParameterizedBase = false; mHasDeclError = false; mMergedFieldDataCount = 0; mConstHolder = NULL; } - - ~BfTypeInstance(); - + + ~BfTypeInstance(); + virtual void Dispose(); - void ReleaseData(); + void ReleaseData(); virtual bool IsInstanceOf(BfTypeDef* typeDef) override { if (typeDef == NULL) return false; return typeDef->GetDefinition() == mTypeDef->GetDefinition(); } virtual BfModule* GetModule() override { return mModule; } @@ -2047,11 +2120,11 @@ public: virtual bool IsDependentOnUnderlyingType() override { return true; } virtual BfPrimitiveType* ToPrimitiveType() override { return IsBoxed() ? GetUnderlyingType()->ToPrimitiveType() : NULL; } virtual bool HasWrappedRepresentation() override { return IsTypedPrimitive(); } - - int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; } - virtual bool HasTypeFailed() override { return mTypeFailed; } - virtual bool IsReified() override { return mIsReified; } - virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); } + + int GetEndingInstanceAlignment() { if (mInstSize % mInstAlign == 0) return mInstAlign; return mInstSize % mInstAlign; } + virtual bool HasTypeFailed() override { return mTypeFailed; } + virtual bool IsReified() override { return mIsReified; } + virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); } virtual bool IsFinishingType() override { return mIsFinishingType; } virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); } virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; } @@ -2061,7 +2134,7 @@ public: virtual bool IsInterface() override { return mTypeDef->mTypeCode == BfTypeCode_Interface; } virtual bool IsValueType() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); } virtual bool IsOpaque() override { return mTypeDef->mIsOpaque; } - virtual bool IsStruct() override { return ((mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mIsTypedPrimitive); } + virtual bool IsStruct() override { return ((mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mIsTypedPrimitive); } virtual bool IsUnion() override { return mIsUnion; } virtual bool IsDelegate() override { return mTypeDef->mIsDelegate; } virtual bool IsFunction() override { return mTypeDef->mIsFunction; } @@ -2073,23 +2146,23 @@ public: virtual bool IsTypedPrimitive() override { return mIsTypedPrimitive; } virtual bool IsStructOrStructPtr() override { return mTypeDef->mTypeCode == BfTypeCode_Struct; } virtual bool IsValueTypeOrValueTypePtr() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); } - virtual bool IsObject() override { return mTypeDef->mTypeCode == BfTypeCode_Object; } + virtual bool IsObject() override { return mTypeDef->mTypeCode == BfTypeCode_Object; } virtual bool IsObjectOrStruct() override { return (mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Struct); } virtual bool IsObjectOrInterface() override { return (mTypeDef->mTypeCode == BfTypeCode_Object) || (mTypeDef->mTypeCode == BfTypeCode_Interface); } virtual BfType* GetUnderlyingType() override; - //virtual bool IsValuelessType() override { return (mIsTypedPrimitive) && (mInstSize == 0); } + //virtual bool IsValuelessType() override { return (mIsTypedPrimitive) && (mInstSize == 0); } virtual bool CanBeValuelessType() override { return (mTypeDef->mTypeCode == BfTypeCode_Struct) || (mTypeDef->mTypeCode == BfTypeCode_Enum); } virtual bool IsValuelessType() override; virtual bool HasPackingHoles() override { return mHasPackingHoles; } virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) override; - virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override; + virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) override; virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProjectSet* visibleProjectSet) override; virtual bool WantsGCMarking() override; virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) override; BfGenericTypeInfo* GetGenericTypeInfo() { return mGenericTypeInfo; } - virtual int GetGenericDepth() { return (mGenericTypeInfo != NULL) ? mGenericTypeInfo->mMaxGenericDepth : 0; } - + virtual int GetGenericDepth() { return (mGenericTypeInfo != NULL) ? mGenericTypeInfo->mMaxGenericDepth : 0; } + virtual BfTypeInstance* ToGenericTypeInstance() override { return (mGenericTypeInfo != NULL) ? this : NULL; } virtual bool IsGenericTypeInstance() override { return mGenericTypeInfo != NULL; } virtual bool IsSpecializedType() override { return (mGenericTypeInfo != NULL) && (!mGenericTypeInfo->mIsUnspecialized); } @@ -2097,7 +2170,7 @@ public: virtual bool IsUnspecializedType() override { return (mGenericTypeInfo != NULL) && (mGenericTypeInfo->mIsUnspecialized); } virtual bool IsUnspecializedTypeVariation() override { return (mGenericTypeInfo != NULL) && (mGenericTypeInfo->mIsUnspecializedVariation); } virtual bool IsNullable() override; - virtual bool HasVarConstraints(); + virtual bool HasVarConstraints(); virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) override; virtual BfTypeInstance* GetImplBaseType() { return mBaseType; } @@ -2107,22 +2180,22 @@ public: void CalcHotVirtualData(/*Val128& vtHash, */Array* ifaceMapping); int GetOrigVTableSize(); int GetSelfVTableSize(); - int GetOrigSelfVTableSize(); + int GetOrigSelfVTableSize(); int GetImplBaseVTableSize(); int GetOrigImplBaseVTableSize(); int GetIFaceVMethodSize(); BfType* GetUnionInnerType(bool* wantSplat = NULL); - BfPrimitiveType* GetDiscriminatorType(int* outDataIdx = NULL); + BfPrimitiveType* GetDiscriminatorType(int* outDataIdx = NULL); void GetUnderlyingArray(BfType*& type, int& size, bool& isVector); bool HasEquivalentLayout(BfTypeInstance* compareTo); BfIRConstHolder* GetOrCreateConstHolder(); - BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder); + BfIRValue CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder); int GetInstStride() { return BF_ALIGN(mInstSize, mInstAlign); } - bool HasOverrideMethods(); + bool HasOverrideMethods(); bool GetResultInfo(BfType*& valueType, int& okTagId); BfGenericTypeInfo::GenericParamsVector* GetGenericParamsVector(BfTypeDef* declaringTypeDef); void GenerateProjectsReferenced(); - bool IsAlwaysInclude(); + bool IsAlwaysInclude(); bool HasBeenInstantiated() { return mHasBeenInstantiated || ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_AssumeInstantiated) != 0); } bool IncludeAllMethods() { return ((mAlwaysIncludeFlags & BfAlwaysIncludeFlag_IncludeAllMethods) != 0); } bool DefineStateAllowsStaticMethods() { return mDefineState >= BfTypeDefineState_HasInterfaces_Direct; } @@ -2195,11 +2268,11 @@ public: virtual bool IsObjectOrInterface() override { return true; } virtual bool IsDependentOnUnderlyingType() override { return true; } virtual BfType* GetUnderlyingType() override { return mElementType; } - + virtual BfTypeInstance* ToGenericTypeInstance() override { return mElementType->ToGenericTypeInstance(); } virtual bool IsSpecializedType() override { return !mElementType->IsUnspecializedType(); } virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); } - virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); } + virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); } virtual BfTypeInstance* GetImplBaseType() override { return (mBoxedBaseType != NULL) ? mBoxedBaseType : mBaseType; } @@ -2219,10 +2292,10 @@ public: public: BfTypeAliasType() { - mAliasToType = NULL; + mAliasToType = NULL; } - virtual bool IsTypeAlias() override { return true; } + virtual bool IsTypeAlias() override { return true; } virtual BfType* GetUnderlyingType() override { return mAliasToType; } virtual bool WantsGCMarking() override { return mAliasToType->WantsGCMarking(); } }; @@ -2231,17 +2304,17 @@ enum BfCaptureType { BfCaptureType_None, BfCaptureType_Copy, - BfCaptureType_Reference, + BfCaptureType_Reference, }; class BfClosureType : public BfTypeInstance { public: Val128 mClosureHash; // Includes base type and capture info - BfTypeInstance* mSrcDelegate; + BfTypeInstance* mSrcDelegate; bool mCreatedTypeDef; String mNameAdd; - BfSource mSource; + BfSource mSource; Array mDirectAllocNodes; bool mIsUnique; @@ -2254,13 +2327,13 @@ public: BfMethodDef* AddDtor(); void Finish(); - virtual bool IsClosure() override { return true; } - virtual bool IsOnDemand() override { return true; } + virtual bool IsClosure() override { return true; } + virtual bool IsOnDemand() override { return true; } }; class BfDelegateType : public BfTypeInstance { -public: +public: BfDelegateInfo mDelegateInfo; bool mIsUnspecializedType; bool mIsUnspecializedTypeVariation; @@ -2274,10 +2347,10 @@ public: mGenericDepth = 0; } ~BfDelegateType(); - + virtual void Dispose() override; virtual bool IsOnDemand() override { return true; } - + virtual bool IsDelegate() override { return mTypeDef->mIsDelegate; } virtual bool IsDelegateFromTypeRef() override { return mTypeDef->mIsDelegate; } @@ -2297,12 +2370,12 @@ class BfTupleType : public BfTypeInstance { public: bool mCreatedTypeDef; - String mNameAdd; + String mNameAdd; BfSource* mSource; bool mIsUnspecializedType; bool mIsUnspecializedTypeVariation; int mGenericDepth; - + public: BfTupleType(); ~BfTupleType(); @@ -2313,7 +2386,7 @@ public: void Finish(); virtual bool IsOnDemand() override { return true; } - virtual bool IsTuple() override { return true; } + virtual bool IsTuple() override { return true; } virtual bool IsUnspecializedType() override { return mIsUnspecializedType; } virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; } @@ -2361,7 +2434,7 @@ public: String mMangledMethodName; BfTypeInstance* mOwner; int mOwnerRevision; - bool mIsAutoCompleteMethod; + bool mIsAutoCompleteMethod; Array mParamToDataIdx; Array mDataToParamIdx; bool mIsUnspecialized; @@ -2369,17 +2442,17 @@ public: public: BfMethodRefType() - { + { mMethodRef = NULL; mOwner = NULL; mOwnerRevision = -1; - mIsAutoCompleteMethod = false; + mIsAutoCompleteMethod = false; mIsUnspecialized = false; mIsUnspecializedVariation = false; } - ~BfMethodRefType(); - + ~BfMethodRefType(); + //virtual bool IsValuelessType() override { return mSize != 0; } virtual bool IsValueType() override { return true; } virtual bool IsComposite() override { return true; } @@ -2393,15 +2466,14 @@ public: virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedVariation; } int GetCaptureDataCount(); - BfType* GetCaptureType(int captureDataIdx); + BfType* GetCaptureType(int captureDataIdx); int GetDataIdxFromParamIdx(int paramIdx); int GetParamIdxFromDataIdx(int dataIdx); bool WantsDataPassedAsSplat(int dataIdx); - + //virtual BfType* GetUnderlyingType() override { return mOwner; } }; - class BfRefType : public BfType { public: @@ -2427,7 +2499,7 @@ public: virtual bool IsIncomplete() override { CheckElement(); return mDefineState < BfTypeDefineState_Defined; } virtual bool IsReified() override { return mElementType->IsReified(); } - virtual bool IsRef() override { return true; } + virtual bool IsRef() override { return true; } virtual bool IsMut() override { return mRefKind == RefKind_Mut; } virtual bool IsIn() override { return mRefKind == RefKind_In; } virtual bool IsOut() override { return mRefKind == RefKind_Out; } @@ -2436,7 +2508,7 @@ public: virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType(); } virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation(); } virtual bool CanBeValuelessType() override { return mElementType->CanBeValuelessType(); } - virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); } + virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); } }; class BfArrayType : public BfTypeInstance @@ -2472,11 +2544,11 @@ public: mElementCount = 0; mGenericDepth = 0; mWantsGCMarking = false; - } + } virtual bool IsSizedArray() override { return true; } virtual bool IsUndefSizedArray() override { return mElementCount == -1; } - + virtual bool IsWrappableType() override { return true; } virtual bool IsValueType() override { return true; } // Is a type of struct virtual bool IsValueTypeOrValueTypePtr() override { return true; } @@ -2500,7 +2572,7 @@ public: // This is used when a sized array is sized by a const generic argument class BfUnknownSizedArrayType : public BfSizedArrayType { -public: +public: BfType* mElementCountSource; public: @@ -2518,7 +2590,7 @@ public: virtual BfType* GetUnderlyingType() override { return mElementType; } virtual bool IsUnspecializedType() override { return mElementType->IsUnspecializedType() || mElementCountSource->IsUnspecializedType(); } virtual bool IsUnspecializedTypeVariation() override { return mElementType->IsUnspecializedTypeVariation() || mElementCountSource->IsUnspecializedTypeVariation(); } - virtual bool CanBeValuelessType() override { return true; } + virtual bool CanBeValuelessType() override { return true; } // Leave the default "zero sized" definition //virtual bool IsValuelessType() override { return mElementType->IsValuelessType(); } }; @@ -2529,7 +2601,7 @@ public: BfType* mType; BfVariant mValue; -public: +public: ~BfConstExprValueType(); virtual bool IsConstExprValue() override { return true; } @@ -2541,20 +2613,20 @@ public: /*class BfCustomAttributeArgument { -public: +public: llvm::Constant* mConstParam; };*/ class BfCustomAttributeSetProperty { -public: +public: BfPropertyRef mPropertyRef; BfTypedValue mParam; }; class BfCustomAttributeSetField { -public: +public: BfFieldRef mFieldRef; BfTypedValue mParam; }; @@ -2582,7 +2654,7 @@ public: class BfCustomAttributes { public: - Array mAttributes; + Array mAttributes; bool Contains(BfTypeDef* typeDef); BfCustomAttribute* Get(BfTypeDef* typeDef); BfCustomAttribute* Get(BfType* type); @@ -2593,7 +2665,6 @@ public: class BfResolvedTypeSetFuncs : public MultiHashSetFuncs { - }; class BfResolvedTypeSet : public MultiHashSet @@ -2606,7 +2677,7 @@ public: BfHashFlag_AllowGenericParamConstValue = 2, BfHashFlag_AllowDotDotDot = 4, }; - + struct BfExprResult { BfVariant mValue; @@ -2614,15 +2685,16 @@ public: }; class LookupContext - { + { public: BfModule* mModule; BfTypeReference* mRootTypeRef; - BfTypeDef* mRootTypeDef; + BfTypeDef* mRootTypeDef; BfTypeInstance* mRootOuterTypeInstance; BfType* mRootResolvedType; Dictionary mResolvedTypeMap; - BfResolveTypeRefFlags mResolveFlags; + Dictionary mResolvedValueMap; + BfResolveTypeRefFlags mResolveFlags; BfCallingConvention mCallingConvention; bool mHadVar; bool mFailed; @@ -2647,7 +2719,7 @@ public: void SetCachedResolvedType(BfTypeReference* typeReference, BfType* type); BfType* ResolveTypeRef(BfTypeReference* typeReference); - BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL); + BfTypeDef* ResolveToTypeDef(BfTypeReference* typeReference, BfType** outType = NULL); }; public: @@ -2663,7 +2735,7 @@ public: 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 int Hash(BfAstNode* typeRefNode, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0); - + static bool Equals(BfType* lhs, BfType* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfAstNode* rhs, LookupContext* ctx); @@ -2673,16 +2745,16 @@ public: BfResolvedTypeSet() { Rehash(9973); - } + } ~BfResolvedTypeSet(); - + template bool Insert(T* findType, LookupContext* ctx, BfResolvedTypeSet::EntryRef* entryPtr) { CheckRehash(); - int tryCount = 0; + int tryCount = 0; ctx->mFailed = false; BfHashFlags hashFlags = BfHashFlag_AllowRef; @@ -2694,7 +2766,7 @@ public: int hashVal = Hash(findType, ctx, hashFlags); if ((ctx->mFailed) || (ctx->mHadVar)) - { + { return false; } int bucket = (hashVal & 0x7FFFFFFF) % mHashSize; @@ -2720,14 +2792,14 @@ public: } BF_ASSERT(tryCount < 10); } - + if ((ctx->mResolveFlags & BfResolveTypeRefFlag_NoCreate) != 0) return false; - *entryPtr = AddRaw(hashVal); + *entryPtr = AddRaw(hashVal); return true; } - + // Iterator begin(); // Iterator end(); // Iterator erase(Iterator& itr); @@ -2814,7 +2886,7 @@ public: else if (checkType->IsSizedArray()) GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength); else if (checkType->IsMethodRef()) - GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength); + GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength); } static BfPrimitiveType* GetPrimitiveType(BfModule* module, BfTypeCode typeCode); @@ -2829,10 +2901,10 @@ public: PopulateType(checkTypeInstance->mModule, checkTypeInstance); if (checkType->IsStruct()) - { + { if (checkTypeInstance->mBaseType != NULL) - SplatIterate(dataLambda, checkTypeInstance->mBaseType); - + SplatIterate(dataLambda, checkTypeInstance->mBaseType); + if (checkTypeInstance->mIsUnion) { BfType* unionInnerType = checkTypeInstance->GetUnionInnerType(); diff --git a/IDEHelper/Compiler/BfSource.cpp b/IDEHelper/Compiler/BfSource.cpp index 0458081b..ce731961 100644 --- a/IDEHelper/Compiler/BfSource.cpp +++ b/IDEHelper/Compiler/BfSource.cpp @@ -16,7 +16,7 @@ BfSource::BfSource(BfSystem* bfSystem) if (bfSystem != NULL) mAstAllocManager = &gBfParserCache->mAstAllocManager; mSrc = NULL; - + mSrcLength = 0; mSrcAllocSize = -1; @@ -36,7 +36,7 @@ BfSource::BfSource(BfSystem* bfSystem) BfSource::~BfSource() { - int sourceCount = gSourceCount--; + int sourceCount = gSourceCount--; delete mSourceData; @@ -65,7 +65,7 @@ BfErrorNode* BfSource::CreateErrorNode(BfAstNode* astNode) } void BfSource::AddErrorNode(BfAstNode* astNode) -{ +{ mPendingErrorNodes.push_back(CreateErrorNode(astNode)); } @@ -85,10 +85,10 @@ int BfSource::AllocChars(int charCount) mSrcAllocSize = newAllocSize; BF_ASSERT(mSourceData->ToParser() != NULL); - mSourceData->mSrc = mSrc; + mSourceData->mSrc = mSrc; HadSrcRealloc(); - } + } int retVal = mSrcLength; mSrcLength += charCount; @@ -130,7 +130,7 @@ void BfSource::FinishSideNodes() } void BfSource::Close() -{ +{ // if (mAlloc->mSource == NULL) // { // BF_ASSERT(mErrorRootNode == NULL); @@ -149,4 +149,4 @@ void BfSource::Close() } mIsClosed = true; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfSource.h b/IDEHelper/Compiler/BfSource.h index 10848d15..9f1d221b 100644 --- a/IDEHelper/Compiler/BfSource.h +++ b/IDEHelper/Compiler/BfSource.h @@ -21,7 +21,7 @@ public: ExternalNodesState_Failed }; -public: +public: const char* mSrc; int mSrcLength; BfAstAllocManager* mAstAllocManager; @@ -30,7 +30,7 @@ public: BfRootNode* mSidechannelRootNode; // Holds comments and preprocessor nodes BfRootNode* mRootNode; BfRootNode* mErrorRootNode; - + BfSizedArray mExteriorNodes; int mExteriorNodesCheckIdx; // 0 = unchecked, -1 = failed, >0 means success and equals the BfSystem.mTypesIdx @@ -76,7 +76,7 @@ public: BfAstAllocator* mAlloc; const char* mSrc; int mSrcLength; - int mSrcAllocSize; + int mSrcAllocSize; bool mParsingFailed; bool mIsClosed; uint8* mAstScratch; @@ -86,28 +86,28 @@ public: BfRootNode* mSidechannelRootNode; // Holds comments and preprocessor nodes BfRootNode* mRootNode; BfRootNode* mErrorRootNode; - + BfParser* mNextRevision; BfParser* mPrevRevision; SizedArray mPendingSideNodes; SizedArray mPendingErrorNodes; -public: +public: bool WantsStats(); public: BfSource(BfSystem* bfSystem); virtual ~BfSource(); - virtual BfParser* ToParser() { return NULL; } + virtual BfParser* ToParser() { return NULL; } virtual void HadSrcRealloc() {} - + BfErrorNode* CreateErrorNode(BfAstNode* astNode); - void AddErrorNode(BfAstNode* astNode); - int AllocChars(int charCount); + void AddErrorNode(BfAstNode* astNode); + int AllocChars(int charCount); void FinishSideNodes(); - virtual void Close(); // Writing done, return unused pages but retain used pages + virtual void Close(); // Writing done, return unused pages but retain used pages }; NS_BF_END; \ No newline at end of file diff --git a/IDEHelper/Compiler/BfSourceClassifier.cpp b/IDEHelper/Compiler/BfSourceClassifier.cpp index 983c227d..388460ec 100644 --- a/IDEHelper/Compiler/BfSourceClassifier.cpp +++ b/IDEHelper/Compiler/BfSourceClassifier.cpp @@ -8,7 +8,7 @@ BfSourceClassifier::BfSourceClassifier(BfParser* bfParser, CharData* charData) { mParser = bfParser; mCharData = charData; - mSkipMethodInternals = false; + mSkipMethodInternals = false; mSkipTypeDeclarations = false; mSkipAttributes = false; mIsSideChannel = false; @@ -23,7 +23,7 @@ BfSourceClassifier::BfSourceClassifier(BfParser* bfParser, CharData* charData) void BfSourceClassifier::ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags) { if (node != NULL) - { + { ModifyFlags(node->GetSrcStart(), node->GetSrcEnd(), andFlags, orFlags); } } @@ -35,8 +35,8 @@ void BfSourceClassifier::ModifyFlags(int startPos, int endPos, uint8 andFlags, u endPos = std::min(endPos, mParser->mOrigSrcLength); for (int i = startPos; i < endPos; i++) - { - mCharData[i].mDisplayPassId = mClassifierPassId; + { + mCharData[i].mDisplayPassId = mClassifierPassId; mCharData[i].mDisplayFlags = (mCharData[i].mDisplayFlags & andFlags) | orFlags; } } @@ -62,13 +62,13 @@ void BfSourceClassifier::SetElementType(BfAstNode * node, BfTypeCode typeCode) } void BfSourceClassifier::SetHighestElementType(int startPos, int endPos, BfSourceElementType elementType) -{ +{ if (!mEnabled) return; endPos = BF_MIN(endPos, mParser->mOrigSrcLength); for (int i = startPos; i < endPos; i++) - { + { auto& charData = mCharData[i]; charData.mDisplayPassId = mClassifierPassId; charData.mDisplayTypeId = BF_MAX(charData.mDisplayTypeId, (uint8)elementType); @@ -100,15 +100,15 @@ void BfSourceClassifier::VisitMembers(BfBlock* node) { mPrevNode = NULL; for (auto& childNodeRef : *node) - { + { BfAstNode* child = childNodeRef; child->Accept(this); - mPrevNode = child; + mPrevNode = child; } } bool BfSourceClassifier::IsInterestedInMember(BfAstNode* node, bool forceSkip) -{ +{ if ((mSkipMethodInternals || forceSkip) && (mParser->mCursorIdx != -1) && (!node->Contains(mParser->mCursorIdx, 1, 0))) return false; @@ -121,16 +121,16 @@ void BfSourceClassifier::HandleLeafNode(BfAstNode* node) return; int nodeStart = node->GetSrcStart(); - int srcStart = nodeStart; + int srcStart = nodeStart; int triviaStart = node->GetTriviaStart(); if (triviaStart != -1) { srcStart = triviaStart; - + if ((mIsSideChannel) && (mPrevNode != NULL)) srcStart = std::max(mPrevNode->GetSrcEnd(), srcStart); } - + if (nodeStart != srcStart) SetElementType(srcStart, nodeStart, BfSourceElementType_Normal); //SetElementType(srcStart, node->GetSrcEnd(), BfSourceElementType_Normal); @@ -140,7 +140,6 @@ void BfSourceClassifier::HandleLeafNode(BfAstNode* node) void BfSourceClassifier::Visit(BfAstNode* node) { - } void BfSourceClassifier::Visit(BfErrorNode* errorNode) @@ -153,7 +152,7 @@ void BfSourceClassifier::Visit(BfFieldDeclaration* fieldDecl) { if (!IsInterestedInMember(fieldDecl)) return; - + BfElementVisitor::Visit(fieldDecl); VisitChild(fieldDecl->mConstSpecifier); @@ -188,12 +187,12 @@ void BfSourceClassifier::Visit(BfPreprocessorNode* preprocessorNode) if (!mPreserveFlags) ModifyFlags(preprocessorNode, ~BfSourceElementFlag_CompilerFlags_Mask, 0); SetElementType(preprocessorNode, BfSourceElementType_Normal); - - Visit(preprocessorNode->ToBase()); + + Visit(preprocessorNode->ToBase()); } void BfSourceClassifier::Visit(BfCommentNode* commentNode) -{ +{ HandleLeafNode(commentNode); Visit(commentNode->ToBase()); @@ -236,7 +235,7 @@ void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective) } } - BfElementVisitor::Visit(attributeDirective); + BfElementVisitor::Visit(attributeDirective); VisitChild(attributeDirective->mAttrCloseToken); @@ -262,7 +261,7 @@ void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective) for (auto& arg : attributeDirective->mArguments) VisitChild(arg); for (auto& comma : attributeDirective->mCommas) - VisitChild(comma); + VisitChild(comma); VisitChild(attributeDirective->mNextAttribute); } @@ -280,7 +279,7 @@ void BfSourceClassifier::Visit(BfIdentifierNode* identifier) } void BfSourceClassifier::Visit(BfQualifiedNameNode* qualifiedName) -{ +{ Visit((BfAstNode*)qualifiedName); VisitChild(qualifiedName->mLeft); @@ -406,11 +405,11 @@ void BfSourceClassifier::Visit(BfLiteralExpression* literalExpr) void BfSourceClassifier::Visit(BfStringInterpolationExpression* stringInterpolationExpression) { HandleLeafNode(stringInterpolationExpression); - + Visit(stringInterpolationExpression->ToBase()); SetElementType(stringInterpolationExpression, BfSourceElementType_Literal); - VisitChild(stringInterpolationExpression->mAllocNode); + VisitChild(stringInterpolationExpression->mAllocNode); for (auto& expr : stringInterpolationExpression->mExpressions) { SetElementType(expr, BfSourceElementType_Normal); @@ -423,7 +422,7 @@ void BfSourceClassifier::Visit(BfTokenNode* tokenNode) HandleLeafNode(tokenNode); Visit(tokenNode->ToBase()); - + if (BfTokenIsKeyword(tokenNode->GetToken())) SetElementType(tokenNode, BfSourceElementType_Keyword); else @@ -436,15 +435,15 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) Visit(invocationExpr->ToBase()); //BP_ZONE("BfSourceClassifier BfInvocationExpression"); - + BfAstNode* target = invocationExpr->mTarget; if (target == NULL) return; - + VisitChild(invocationExpr->mOpenParen); VisitChild(invocationExpr->mCloseParen); VisitChild(invocationExpr->mGenericArgs); - + if (auto scopedTarget = BfNodeDynCast(target)) { VisitChild(target); @@ -458,27 +457,27 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mDot); VisitChild(qualifiedName->mRight); - identifier = qualifiedName->mRight; + identifier = qualifiedName->mRight; } else if ((identifier = BfNodeDynCast(target))) { VisitChild(target); // Leave as BfAttributedIdentifierNode if that's the case - identifier = target; + identifier = target; } else if (auto qualifiedName = BfNodeDynCast(target)) { VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mDot); VisitChild(qualifiedName->mRight); - identifier = qualifiedName->mRight; + identifier = qualifiedName->mRight; } else if (auto memberRefExpr = BfNodeDynCast(target)) { VisitChild(memberRefExpr->mTarget); VisitChild(memberRefExpr->mDotToken); VisitChild(memberRefExpr->mMemberName); - identifier = memberRefExpr->mMemberName; + identifier = memberRefExpr->mMemberName; } else { @@ -490,9 +489,9 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) if (auto attrIdentifier = BfNodeDynCast(identifier)) { VisitChild(attrIdentifier->mAttributes); - identifier = attrIdentifier->mIdentifier; + identifier = attrIdentifier->mIdentifier; } - + if (identifier != NULL) SetElementType(identifier, BfSourceElementType_Method); } @@ -551,7 +550,7 @@ void BfSourceClassifier::Visit(BfDestructorDeclaration* dtorDeclaration) } void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration) -{ +{ if (!IsInterestedInMember(methodDeclaration)) return; @@ -559,8 +558,8 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration) SetAndRestoreValue prevMember(mCurMember, methodDeclaration); - BfElementVisitor::Visit(methodDeclaration); - + BfElementVisitor::Visit(methodDeclaration); + SetElementType(methodDeclaration->mNameNode, BfSourceElementType_Method); if (methodDeclaration->mGenericParams != NULL) @@ -582,7 +581,7 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration) if (typeRef != NULL) { if (auto namedTypeRef = BfNodeDynCast(typeRef)) - SetElementType(typeRef, BfSourceElementType_GenericParam); + SetElementType(typeRef, BfSourceElementType_GenericParam); else VisitChild(typeRef); } @@ -651,7 +650,7 @@ void BfSourceClassifier::Handle(BfTypeDeclaration* typeDeclaration) llvm::SmallVector mBaseClasses; llvm::SmallVector mBaseClassCommas; - + if (typeDeclaration->mGenericParams != NULL) { for (auto& genericParam : typeDeclaration->mGenericParams->mGenericParams) @@ -694,12 +693,25 @@ void BfSourceClassifier::MarkSkipped(BfAstNode* node) MarkSkipped(node->GetSrcStart(), node->GetSrcEnd()); } +void BfSourceClassifier::DeferNodes(BfBlock* block) +{ + for (auto child : *block) + mDeferredNodes.Add(child); +} + +void BfSourceClassifier::FlushDeferredNodes() +{ + for (auto node : mDeferredNodes) + VisitChild(node); + mDeferredNodes.Clear(); +} + void BfSourceClassifier::Visit(BfTypeAliasDeclaration* typeDeclaration) { if (typeDeclaration->mIgnoreDeclaration) return; - BfElementVisitor::Visit(typeDeclaration); + BfElementVisitor::Visit(typeDeclaration); } void BfSourceClassifier::Visit(BfUsingDirective* usingDirective) @@ -722,7 +734,7 @@ void BfSourceClassifier::Visit(BfUsingDirective* usingDirective) void BfSourceClassifier::Visit(BfUsingModDirective* usingDirective) { - BfElementVisitor::Visit(usingDirective); + BfElementVisitor::Visit(usingDirective); } void BfSourceClassifier::Visit(BfNamespaceDeclaration* namespaceDeclaration) @@ -747,7 +759,7 @@ bool BfSourceClassifier::WantsSkipParentMethod(BfAstNode* node) { if (!mSkipMethodInternals) return false; - + #ifdef BF_AST_HAS_PARENT_MEMBER if (node->mParent->IsA()) { @@ -785,7 +797,7 @@ void BfSourceClassifier::Visit(BfGenericConstraintsDeclaration* genericConstrain } void BfSourceClassifier::Visit(BfBlock* block) -{ +{ if (WantsSkipParentMethod(block)) return; if (block->mOpenBrace != NULL) @@ -800,7 +812,7 @@ void BfSourceClassifier::Visit(BfRootNode* rootNode) // Clear off the flags at the end ModifyFlags(mParser->mRootNode->GetSrcEnd(), mParser->mOrigSrcLength, 0, 0); - VisitMembers(rootNode); + VisitMembers(rootNode); } void BfSourceClassifier::Visit(BfInlineAsmStatement* asmStmt) @@ -809,7 +821,7 @@ void BfSourceClassifier::Visit(BfInlineAsmStatement* asmStmt) Visit(asmStmt->mOpenBrace); if (asmStmt->mCloseBrace != NULL) Visit(asmStmt->mCloseBrace); - + //VisitMembers(asmStmt); } diff --git a/IDEHelper/Compiler/BfSourceClassifier.h b/IDEHelper/Compiler/BfSourceClassifier.h index fc15edd0..169ad52e 100644 --- a/IDEHelper/Compiler/BfSourceClassifier.h +++ b/IDEHelper/Compiler/BfSourceClassifier.h @@ -12,7 +12,7 @@ enum BfSourceElementType BfSourceElementType_Normal, BfSourceElementType_Keyword, BfSourceElementType_Literal, - BfSourceElementType_Identifier, + BfSourceElementType_Identifier, BfSourceElementType_Comment, BfSourceElementType_Method, BfSourceElementType_Type, @@ -48,7 +48,7 @@ class BfSourceClassifier : public BfElementVisitor public: struct CharData { - char mChar; + char mChar; uint8 mDisplayPassId; uint8 mDisplayTypeId; uint8 mDisplayFlags; @@ -58,8 +58,8 @@ public: }; public: - BfParser* mParser; - CharData* mCharData; + BfParser* mParser; + CharData* mCharData; bool mEnabled; bool mSkipMethodInternals; bool mSkipTypeDeclarations; @@ -70,6 +70,7 @@ public: BfAstNode* mPrevNode; BfAstNode* mCurMember; BfLocalMethodDeclaration* mCurLocalMethodDeclaration; + Array mDeferredNodes; public: void HandleLeafNode(BfAstNode* node); @@ -86,6 +87,8 @@ public: void Handle(BfTypeDeclaration* typeDeclaration); void MarkSkipped(int startPos, int endPos); void MarkSkipped(BfAstNode* node); + void DeferNodes(BfBlock* block); + void FlushDeferredNodes(); public: BfSourceClassifier(BfParser* bfParser, CharData* charData); @@ -93,7 +96,7 @@ public: virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints) override; virtual void Visit(BfAstNode* node) override; - virtual void Visit(BfErrorNode* errorNode) override; + virtual void Visit(BfErrorNode* errorNode) override; virtual void Visit(BfFieldDeclaration* fieldDecl) override; virtual void Visit(BfFieldDtorDeclaration* fieldDtorDecl) override; virtual void Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection) override; @@ -101,10 +104,10 @@ public: virtual void Visit(BfCommentNode* commentNode) override; virtual void Visit(BfAttributeDirective* attributeDirective) override; virtual void Visit(BfIdentifierNode* identifier) override; - virtual void Visit(BfQualifiedNameNode* identifier) override; + virtual void Visit(BfQualifiedNameNode* identifier) override; virtual void Visit(BfThisExpression* thisExpr) override; virtual void Visit(BfBaseExpression* baseExpr) override; - virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override; + virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override; virtual void Visit(BfQualifiedTypeReference* qualifiedType) override; virtual void Visit(BfRefTypeRef* typeRef) override; virtual void Visit(BfArrayTypeRef* arrayType) override; @@ -115,11 +118,11 @@ public: virtual void Visit(BfLiteralExpression* literalExpr) override; virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression) override; virtual void Visit(BfTokenNode* tokenNode) override; - virtual void Visit(BfInvocationExpression* invocationExpr) override; + virtual void Visit(BfInvocationExpression* invocationExpr) override; virtual void Visit(BfIndexerExpression* indexerExpr) override; - virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override; - virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override; - virtual void Visit(BfMethodDeclaration* methodDeclaration) override; + virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override; + virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override; + virtual void Visit(BfMethodDeclaration* methodDeclaration) override; virtual void Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration) override; virtual void Visit(BfPropertyDeclaration* propertyDeclaration) override; virtual void Visit(BfTypeDeclaration* typeDeclaration) override; diff --git a/IDEHelper/Compiler/BfSourcePositionFinder.cpp b/IDEHelper/Compiler/BfSourcePositionFinder.cpp index 56bc5f33..c67112aa 100644 --- a/IDEHelper/Compiler/BfSourcePositionFinder.cpp +++ b/IDEHelper/Compiler/BfSourcePositionFinder.cpp @@ -13,5 +13,5 @@ BfSourcePositionFinder::BfSourcePositionFinder(BfParser* bfParser, int findPosit void BfSourcePositionFinder::Visit(BfAstNode* node) { if ((mFindPosition >= node->GetSrcStart()) && (mFindPosition <= node->GetSrcEnd())) - mClosestElement = node; -} + mClosestElement = node; +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfSourcePositionFinder.h b/IDEHelper/Compiler/BfSourcePositionFinder.h index eeceae97..7c5c9adc 100644 --- a/IDEHelper/Compiler/BfSourcePositionFinder.h +++ b/IDEHelper/Compiler/BfSourcePositionFinder.h @@ -16,7 +16,7 @@ public: BfSourcePositionFinder(BfParser* bfParser, int findPosition); using BfStructuralVisitor::Visit; - virtual void Visit(BfAstNode* node) override; + virtual void Visit(BfAstNode* node) override; }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index c824101e..7ea10734 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -41,8 +41,8 @@ USING_NS_BF; bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData) -{ - if ((((mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) || +{ + if ((((mCompiler->mIsResolveOnly) && (!mIsComptimeModule)) || (mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL)) { // For resolve entries, we only keep deferred blocks because we need to process them later so we can @@ -56,10 +56,10 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc deferredCallEntry->mIgnored = true; scopeData->mDeferredCallEntries.PushBack(deferredCallEntry); return true; - } + } // We don't need to do a "clear handlers" if we're just adding another dyn to an existing dyn list - bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData); + bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData); if (mCurMethodState->mPendingNullConditional != NULL) isDyn = true; @@ -78,7 +78,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc SizedArray origParamTypes; BfIRType origReturnType; deferredCallEntry->mModuleMethodInstance.mMethodInstance->GetIRFunctionInfo(this, origReturnType, origParamTypes); - + int sretIdx = deferredCallEntry->mModuleMethodInstance.mMethodInstance->GetStructRetIdx(); BF_ASSERT(origParamTypes.size() == deferredCallEntry->mScopeArgs.size() + ((sretIdx != -1) ? 1 : 0)); @@ -90,7 +90,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc paramIdx++; auto scopeArg = deferredCallEntry->mScopeArgs[argIdx]; - if ((scopeArg.IsConst()) || (scopeArg.IsFake())) + if ((scopeArg.IsConst()) || (scopeArg.IsFake())) continue; auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); @@ -130,9 +130,9 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc AddDependency(deferredCallEntryType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Allocates); mBfIRBuilder->PopulateType(deferredCallEntryType); auto deferredCallEntryTypePtr = CreatePointerType(deferredCallEntryType); - + UpdateSrcPos(mCurMethodInstance->mMethodDef->GetRefNode(), BfSrcPosFlag_NoSetDebugLoc); - + if (listEntry == NULL) { listEntry = new BfDeferredCallEntry(); @@ -183,10 +183,10 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc } mCurMethodState->mCurScope->ClearHandlers(scopeData); - scopeData->mDeferredCallEntries.PushFront(listEntry); + scopeData->mDeferredCallEntries.PushFront(listEntry); } - BfIRValue deferredAlloca; + BfIRValue deferredAlloca; SizedArray types; SizedArray memberNames; int instAlign = 1; @@ -200,19 +200,19 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc { HashContext hashCtx; hashCtx.Mixin(deferredCallEntry->mDeferredBlock->GetSrcStart()); - + auto parserData = deferredCallEntry->mDeferredBlock->GetParserData(); - if (parserData != NULL) + if (parserData != NULL) hashCtx.MixinStr(parserData->mFileName); - + int64 blockId = BfDeferredMethodCallData::GenerateMethodId(this, hashCtx.Finish64()); deferredCallEntry->mBlockId = blockId; auto deferType = deferredCallEntryType; - BfIRType deferIRType; + BfIRType deferIRType; auto int64Type = GetPrimitiveType(BfTypeCode_Int64); - + types.push_back(int64Type); memberNames.push_back("__methodId"); @@ -228,9 +228,9 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc SizedArray llvmTypes; SizedArray diFieldTypes; - + typeName = StrFormat("_BF_DeferredData_%s", BfTypeUtils::HashEncode64(blockId).c_str()); - + auto valueType = ResolveTypeDef(mCompiler->mValueTypeTypeDef); llvmTypes.push_back(mBfIRBuilder->MapType(valueType)); @@ -252,18 +252,18 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc memberPositions.push_back(dataPos); dataPos += type->mSize; - } + } } instSize = dataPos; deferIRType = mBfIRBuilder->CreateStructType(typeName); mBfIRBuilder->StructSetBody(deferIRType, llvmTypes, instSize, instAlign, false); - + auto prevInsertPoint = mBfIRBuilder->GetInsertBlock(); if (!isLooped) mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); deferredAlloca = mBfIRBuilder->CreateAlloca(deferIRType); - mBfIRBuilder->SetAllocaAlignment(deferredAlloca, instAlign); + mBfIRBuilder->SetAllocaAlignment(deferredAlloca, instAlign); mBfIRBuilder->SetAllocaNoChkStkHint(deferredAlloca); if (!isLooped) mBfIRBuilder->SetInsertPoint(prevInsertPoint); @@ -315,11 +315,11 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc deferredMethodCallData = new BfDeferredMethodCallData(); mDeferredMethodCallData[methodInstance] = deferredMethodCallData; deferredMethodCallData->mMethodId = BfDeferredMethodCallData::GenerateMethodId(this, methodInstance->mIdHash); - + auto int64Type = GetPrimitiveType(BfTypeCode_Int64); auto methodDef = moduleMethodInstance.mMethodInstance->mMethodDef; auto thisType = moduleMethodInstance.mMethodInstance->mMethodInstanceGroup->mOwner; - + types.push_back(int64Type); memberNames.push_back("__methodId"); @@ -340,9 +340,9 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc memberNames.push_back(methodInstance->GetParamName(paramIdx)); } - SizedArray llvmTypes; + SizedArray llvmTypes; - //String typeName; + //String typeName; typeName += StrFormat("_BF_DeferredData_%s", BfTypeUtils::HashEncode64(deferredMethodCallData->mMethodId).c_str()); BfLogSysM("Building type: %s from methodInstance:%p\n", typeName.c_str(), methodInstance); @@ -386,10 +386,10 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc mBfIRBuilder->SetInsertPoint(mCurMethodState->mIRHeadBlock); deferredAlloca = mBfIRBuilder->CreateAlloca(BfIRType(deferredMethodCallData->mDeferType)); mBfIRBuilder->ClearDebugLocation(deferredAlloca); - mBfIRBuilder->SetAllocaAlignment(deferredAlloca, deferredMethodCallData->mAlign); + mBfIRBuilder->SetAllocaAlignment(deferredAlloca, deferredMethodCallData->mAlign); mBfIRBuilder->SetAllocaNoChkStkHint(deferredAlloca); if (!isLooped) - mBfIRBuilder->SetInsertPoint(prevInsertPoint); + mBfIRBuilder->SetInsertPoint(prevInsertPoint); auto gepInstance = mBfIRBuilder->CreateInBoundsGEP(deferredAlloca, 0, 1); auto prevVal = mBfIRBuilder->CreateLoad(listEntry->mDynCallTail); @@ -446,20 +446,20 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc } else { - auto val = mBfIRBuilder->CreateLoad(llvmArgs[argIdx]); + auto val = mBfIRBuilder->CreateLoad(llvmArgs[argIdx]); mBfIRBuilder->CreateStore(val, gepInstance); argIdx++; } } else - { + { mBfIRBuilder->CreateStore(llvmArgs[argIdx], gepInstance); argIdx++; } } mBfIRBuilder->CreateStore(mBfIRBuilder->CreateBitCast(deferredAlloca, mBfIRBuilder->MapType(deferredCallEntryTypePtr)), listEntry->mDynCallTail); - + deferredCallEntry->mDeferredAlloca = deferredAlloca; listEntry->mDynList.PushFront(deferredCallEntry); } @@ -511,18 +511,18 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc diFieldTypes.push_back(memberType); } } - + int diFlags = 0; mBfIRBuilder->DbgMakePermanent(diForwardDecl, BfIRMDNode(), diFieldTypes); deferDIType = mBfIRBuilder->DbgCreatePointerType(diForwardDecl); if (deferredMethodCallData != NULL) - deferredMethodCallData->mDeferDIType = deferDIType; + deferredMethodCallData->mDeferDIType = deferDIType; } - + // We don't actually want to see this, and it doesn't emit properly in LLVM CodeView anyway - it only accepts static allocs, // not dynamic allocas - String varName = StrFormat("$__deferredCall_%d", mCurMethodState->mDeferredLoopListEntryCount); - mCurMethodState->mDeferredLoopListEntryCount++; + String varName = StrFormat("$__deferredCall_%d", mCurMethodState->mDeferredLoopListEntryCount); + mCurMethodState->mDeferredLoopListEntryCount++; auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope, varName, mCurFilePosition.mFileInstance->mDIFile, mCurFilePosition.mCurLine, deferDIType); mBfIRBuilder->DbgInsertDeclare(deferredAlloca, diVariable); @@ -549,7 +549,7 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod for (auto arg : llvmArgs) { - deferredCallEntry->mScopeArgs.push_back(arg); + deferredCallEntry->mScopeArgs.push_back(arg); } deferredCallEntry->mSrcNode = srcNode; deferredCallEntry->mBypassVirtual = bypassVirtual; @@ -560,11 +560,11 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod } void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl& llvmArgs, BfDeferredBlockFlags flags) -{ +{ if (moduleMethodInstance.mMethodInstance->GetOwner()->IsInstanceOf(mCompiler->mInternalTypeDef)) { if (moduleMethodInstance.mMethodInstance->mMethodDef->mName.StartsWith("SetDeleted")) - { + { intptr typeSize = 0; intptr typeAlign = 1; intptr clearSize = 0; @@ -576,7 +576,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz if ((moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted") || (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedArray")) - { + { auto constant = mBfIRBuilder->GetConstant(llvmArgs[1]); if (constant != NULL) typeSize = constant->mInt64; @@ -584,7 +584,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz if (constant != NULL) typeAlign = constant->mInt64; if (llvmArgs.size() >= 4) - arraySize = llvmArgs[3]; + arraySize = llvmArgs[3]; intptr allocSize = typeSize; if (arraySize) @@ -610,7 +610,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz clearSize = typeSize; arraySize = llvmArgs[1]; isDynSize = true; - } + } else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted1") { clearSize = 1; @@ -665,7 +665,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz mBfIRBuilder->SetInsertPoint(ddDoneBlock); if ((flags & BfDeferredBlockFlag_MoveNewBlocksToEnd) != 0) - { + { mCurMethodState->mCurScope->mAtEndBlocks.push_back(ddSize1Block); mCurMethodState->mCurScope->mAtEndBlocks.push_back(ddDoneBlock); } @@ -736,7 +736,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz BF_ASSERT(llvmArgs.size() == 3); auto sizeConstant = mBfIRBuilder->GetConstant(llvmArgs[1]); int clearSize = BF_MIN(sizeConstant->mInt32, 32); - + auto alignConstant = mBfIRBuilder->GetConstant(llvmArgs[2]); int clearAlign = alignConstant->mInt32; @@ -752,7 +752,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz if ((isDtor) && (methodInstance->GetParamCount() != 0)) { // Dtor declared with params - AssertErrorState(); + AssertErrorState(); return; } @@ -778,7 +778,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz (!skipAccessCheck)) { EmitObjectAccessCheck(BfTypedValue(llvmArgs[0], methodOwner)); - } + } BfExprEvaluator expressionEvaluator(this); expressionEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, ((flags & BfDeferredBlockFlag_BypassVirtual) != 0), llvmArgs); @@ -798,11 +798,11 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz mCurMethodState->mCurScope->mAtEndBlocks.push_back(nullLabel); } } - } + } } void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks) -{ +{ if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (deferredCallEntry.mHandlerCount > 0)) { // We only want to process deferred blocks once, otherwise it could significantly slow down autocompletion @@ -821,7 +821,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov { // Only show warnings on the first pass // For errors, show on the first pass OR as long as we haven't gotten any errors within this method. I'm not sure if there's a case - // where the first emission succeeds but a subsequent one would fail, but we leave this logic to handle that possibility + // where the first emission succeeds but a subsequent one would fail, but we leave this logic to handle that possibility SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, (deferredCallEntry.mHandlerCount > 1) && (mCurMethodInstance->mHasFailed)); SetAndRestoreValue prevIgnoreWarnings(mIgnoreWarnings, (deferredCallEntry.mHandlerCount > 1)); @@ -841,17 +841,17 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov { auto addr = CreateAlloca(localVar->mResolvedType); mBfIRBuilder->CreateAlignedStore(localVar->mValue, addr, localVar->mResolvedType->mAlign); - localVar->mAddr = addr; - } + localVar->mAddr = addr; + } AddLocalVariableDef(localVar, true); } - + SetAndRestoreValue prevCustomAttribute(mCurMethodState->mEmitRefNode, deferredCallEntry.mEmitRefNode); - VisitEmbeddedStatement(deferredCallEntry.mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock); + VisitEmbeddedStatement(deferredCallEntry.mDeferredBlock, NULL, BfEmbeddedStatementFlags_IsDeferredBlock); RestoreScopeState(); return; } - + auto args = deferredCallEntry.mScopeArgs; if (deferredCallEntry.mArgsNeedLoad) { @@ -878,7 +878,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov } void BfModule::EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail) -{ +{ int64 collisionId = 0; struct _CallInfo @@ -889,7 +889,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr //typedef std::map MapType; //MapType methodInstanceMap; - Dictionary methodInstanceMap; + Dictionary methodInstanceMap; int blockCount = 0; HashSet nullCheckMethodSet; @@ -897,7 +897,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr BfDeferredCallEntry* deferredCallEntry = callEntries.mHead; while (deferredCallEntry != NULL) { - BfModuleMethodInstance moduleMethodInstance = deferredCallEntry->mModuleMethodInstance; + BfModuleMethodInstance moduleMethodInstance = deferredCallEntry->mModuleMethodInstance; int64 methodId = 0; if (moduleMethodInstance.mMethodInstance != NULL) { @@ -916,7 +916,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr // Only bypass virtual if ALL these calls are devirtualized callInfo->mBypassVirtual &= deferredCallEntry->mBypassVirtual; } - } + } else blockCount++; if (deferredCallEntry->mDoNullCheck) @@ -933,12 +933,12 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr BfIRBlock condBB = mBfIRBuilder->CreateBlock("deferCall.cond", true); if (moveBlocks) mCurMethodState->mCurScope->mAtEndBlocks.push_back(condBB); - mBfIRBuilder->CreateBr(condBB); + mBfIRBuilder->CreateBr(condBB); auto deferredCallEntryType = ResolveTypeDef(mCompiler->mDeferredCallTypeDef); auto deferredCallEntryTypePtr = CreatePointerType(deferredCallEntryType); - BfIRBlock bodyBB = mBfIRBuilder->CreateBlock("deferCall.body"); + BfIRBlock bodyBB = mBfIRBuilder->CreateBlock("deferCall.body"); if (moveBlocks) mCurMethodState->mCurScope->mAtEndBlocks.push_back(bodyBB); BfIRBlock endBB = mBfIRBuilder->CreateBlock("deferCall.end"); @@ -950,21 +950,21 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr BfIRValue deferredCallTail; mBfIRBuilder->SetInsertPoint(condBB); - deferredCallTail = mBfIRBuilder->CreateLoad(callTail); + deferredCallTail = mBfIRBuilder->CreateLoad(callTail); auto isNotNull = mBfIRBuilder->CreateIsNotNull(deferredCallTail); ValueScopeEnd(valueScopeStart); - mBfIRBuilder->CreateCondBr(isNotNull, bodyBB, exitBB); + mBfIRBuilder->CreateCondBr(isNotNull, bodyBB, exitBB); mBfIRBuilder->AddBlock(bodyBB); mBfIRBuilder->SetInsertPoint(bodyBB); - - BfIRValue switchInst; + + BfIRValue switchInst; bool wantsSwitch = ((int)methodInstanceMap.size() + blockCount) > 1; if (blockCount > 0) { // A block may embed a switch so we need a switch whenever we have blocks wantsSwitch = true; - } + } if (mCurMethodState->mCancelledDeferredCall) wantsSwitch = true; if (wantsSwitch) @@ -972,7 +972,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr if (IsTargetingBeefBackend()) deferredCallTail = mBfIRBuilder->CreateLoad(callTail); auto idPtr = mBfIRBuilder->CreateInBoundsGEP(deferredCallTail, 0, 1); // mMethodId - auto id = mBfIRBuilder->CreateLoad(idPtr); + auto id = mBfIRBuilder->CreateLoad(idPtr); switchInst = mBfIRBuilder->CreateSwitch(id, exitBB, (int)methodInstanceMap.size()); ValueScopeEnd(valueScopeStart); } @@ -984,7 +984,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr deferredCallEntry = callEntries.mHead; while (deferredCallEntry != NULL) - { + { auto block = deferredCallEntry->mDeferredBlock; if (block == NULL) { @@ -1058,7 +1058,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr BfModuleMethodInstance moduleMethodInstance = deferredCallEntry->mModuleMethodInstance; if (moduleMethodInstance.mMethodInstance != NULL) { - auto deferredMethodCallData = mDeferredMethodCallData[moduleMethodInstance.mMethodInstance]; + auto deferredMethodCallData = mDeferredMethodCallData[moduleMethodInstance.mMethodInstance]; //methodInstanceMap.insert(MapType::value_type(deferredMethodCallData->mMethodId, moduleMethodInstance)); _CallInfo* callInfo = NULL; if (methodInstanceMap.TryAdd(deferredMethodCallData->mMethodId, NULL, &callInfo)) @@ -1092,31 +1092,31 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr if (moveBlocks) mCurMethodState->mCurScope->mAtEndBlocks.push_back(caseBB); mBfIRBuilder->AddSwitchCase(switchInst, GetConstValue64(methodId), caseBB); - mBfIRBuilder->SetInsertPoint(caseBB); + mBfIRBuilder->SetInsertPoint(caseBB); } - + if (IsTargetingBeefBackend()) - deferredCallTail = mBfIRBuilder->CreateLoad(callTail); + deferredCallTail = mBfIRBuilder->CreateLoad(callTail); auto nextPtr = mBfIRBuilder->CreateInBoundsGEP(deferredCallTail, 0, 2); // mNext auto next = mBfIRBuilder->CreateLoad(nextPtr); mBfIRBuilder->CreateStore(next, callTail); - deferredCallInst = mBfIRBuilder->CreateBitCast(deferredCallTail, deferredMethodCallData->mDeferTypePtr); + deferredCallInst = mBfIRBuilder->CreateBitCast(deferredCallTail, deferredMethodCallData->mDeferTypePtr); int paramIdx = 0; if (!methodDef->mIsStatic) paramIdx = -1; - SizedArray llvmArgs; + SizedArray llvmArgs; for (int argIdx = 0; paramIdx < methodInstance->GetParamCount(); argIdx++, paramIdx++) { auto argPtr = mBfIRBuilder->CreateInBoundsGEP(deferredCallInst, 0, argIdx + 2); bool isStruct = false; bool doSplat = methodInstance->GetParamIsSplat(paramIdx);; - BfTypedValue typedVal; + BfTypedValue typedVal; if (paramIdx == -1) { - typedVal = BfTypedValue(argPtr, methodOwner, true); + typedVal = BfTypedValue(argPtr, methodOwner, true); } else { @@ -1142,11 +1142,11 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr if (paramIdx >= methodInstance->GetParamCount()) break; auto paramType = methodInstance->GetParamType(paramIdx); - isStruct = paramType->IsStruct(); + isStruct = paramType->IsStruct(); } if (isStruct) - { + { llvmArgs.push_back(argPtr); } else @@ -1167,7 +1167,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList& callEntr ValueScopeEnd(valueScopeStart); mBfIRBuilder->CreateBr(condBB); } - + if (endBB) { mBfIRBuilder->AddBlock(endBB); @@ -1197,15 +1197,24 @@ void BfModule::TryInitVar(BfAstNode* checkNode, BfLocalVariable* localVar, BfTyp bool isDynamicCast = false; if (varType->IsGenericParam()) - { - auto genericParamType = (BfGenericParamType*) varType; - auto genericParam = GetGenericParamInstance(genericParamType); - auto typeConstraint = genericParam->mTypeConstraint; - if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & BfGenericParamFlag_Class)) - typeConstraint = mContext->mBfObjectType; - if (typeConstraint != NULL) - varType = typeConstraint; - initValue = GetDefaultTypedValue(varType); + { + int pass = 0; + while (varType->IsGenericParam()) + { + auto genericParamType = (BfGenericParamType*)varType; + + auto genericParam = GetGenericParamInstance(genericParamType); + auto typeConstraint = genericParam->mTypeConstraint; + if ((typeConstraint == NULL) && (genericParam->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Interface))) + typeConstraint = mContext->mBfObjectType; + if (typeConstraint != NULL) + varType = typeConstraint; + else + break; + if (++pass >= 100) // Sanity - but we should have caught circular error before + break; + } + initValue = GetDefaultTypedValue(varType, false, BfDefaultValueKind_Undef); } BfTypeInstance* srcTypeInstance = initValue.mType->ToTypeInstance(); @@ -1218,10 +1227,10 @@ void BfModule::TryInitVar(BfAstNode* checkNode, BfLocalVariable* localVar, BfTyp if (!IsInSpecializedSection()) { if (initValue.mType != varType) - Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' because static cast cannot fail and a value of type '%s' can never be null", - TypeToString(varType).c_str()), checkNode); + Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' because static cast cannot fail and a value of type '%s' can never be null", + TypeToString(varType).c_str()), checkNode); else - Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' because a value of type '%s' can never be null", + Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' because a value of type '%s' can never be null", TypeToString(varType).c_str()), checkNode); } } @@ -1247,7 +1256,7 @@ void BfModule::TryInitVar(BfAstNode* checkNode, BfLocalVariable* localVar, BfTyp // } if (!isDynamicCast) - { + { //initValue = Cast(checkNode, initValue, varType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail)); initValue = Cast(checkNode, initValue, varType); @@ -1255,7 +1264,7 @@ void BfModule::TryInitVar(BfAstNode* checkNode, BfLocalVariable* localVar, BfTyp { checkResult = BfTypedValue(GetConstValue(0, boolType), boolType); } - else + else { if (localVar->mAddr) { @@ -1324,14 +1333,14 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } BfAutoComplete* bfAutocomplete = NULL; - + // Just a check mBfIRBuilder->GetInsertBlock(); if (mCompiler->mResolvePassData != NULL) - bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete; - if (bfAutocomplete != NULL) - bfAutocomplete->CheckTypeRef(varDecl->mTypeRef, true, true); + bfAutocomplete = mCompiler->mResolvePassData->mAutoComplete; + if (bfAutocomplete != NULL) + bfAutocomplete->CheckTypeRef(varDecl->mTypeRef, true, true); bool isConst = (varDecl->mModSpecifier != NULL) && (varDecl->mModSpecifier->GetToken() == BfToken_Const); bool isReadOnly = (varDecl->mModSpecifier != NULL) && (varDecl->mModSpecifier->GetToken() == BfToken_ReadOnly); @@ -1403,7 +1412,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD auto phiVal = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(boolType), 2); mBfIRBuilder->AddPhiIncoming(phiVal, mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), insertBlock); mBfIRBuilder->AddPhiIncoming(phiVal, mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), doAssignBlock); - exprEvaluator->mResult = BfTypedValue(phiVal, boolType); + exprEvaluator->mResult = BfTypedValue(phiVal, boolType); }; bool handled = false; @@ -1421,7 +1430,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD BfIRValue dscVal = ExtractValue(initValue, dscDataIdx); auto eqVal = mBfIRBuilder->CreateCmpEQ(dscVal, GetConstValue(tagId, dscType)); exprEvaluator->mResult = BfTypedValue(eqVal, boolType); - + PopulateType(outType); if (!outType->IsValuelessType()) { @@ -1438,7 +1447,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } handled = true; - } + } } if (handled) @@ -1479,7 +1488,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD handledVarInit = true; handledVarStore = true; } - }; + }; if ((varDecl->mTypeRef->IsA()) || (isLet)) { @@ -1492,7 +1501,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if (mCurMethodState->mLocalVarSet.TryGet(BfLocalVarEntry(localDef), &shadowEntry)) { auto prevLocal = shadowEntry->mLocalVar; - if (prevLocal->mLocalVarIdx >= mCurMethodState->GetLocalStartIdx()) + if (prevLocal->mLocalVarIdx >= mCurMethodState->GetLocalStartIdx()) { BfExprEvaluator exprEvaluator(this); initValue = exprEvaluator.LoadLocal(prevLocal); @@ -1545,27 +1554,27 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { auto typeInst = initValue.mType->ToTypeInstance(); if (typeInst != NULL) - { + { PopulateType(typeInst); BfType* outType = NULL; - int tagId = -1; + int tagId = -1; if (typeInst->GetResultInfo(outType, tagId)) { handledExprBoolResult = true; unresolvedType = outType; resolvedType = outType; isReadOnly = isLet; - localDef->mIsReadOnly = isLet; - _DoConditionalInit(outType); + localDef->mIsReadOnly = isLet; + _DoConditionalInit(outType); } } } - } + } } } - if (!initValue) + if (!initValue) { - initValue = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_Var)); + initValue = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_Var)); } if (initValue.mType->IsNull()) { @@ -1579,12 +1588,12 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if ((initValue.IsTempAddr()) && (!localDef->mAddr) && (initValue.mType == resolvedType)) { // Take over value - localDef->mAddr = initValue.mValue; - handledVarInit = true; + localDef->mAddr = initValue.mValue; + handledVarInit = true; if (isLet) { - localDef->mValue = mBfIRBuilder->CreateLoad(localDef->mAddr); + localDef->mValue = mBfIRBuilder->CreateLoad(localDef->mAddr); } } @@ -1603,9 +1612,9 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, flags); if (unresolvedType == NULL) - unresolvedType = GetPrimitiveType(BfTypeCode_Var); - resolvedType = unresolvedType; - } + unresolvedType = GetPrimitiveType(BfTypeCode_Var); + resolvedType = unresolvedType; + } auto _CheckConst = [&] { @@ -1627,10 +1636,10 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } } }; - + localDef->mResolvedType = resolvedType; - localDef->mIsReadOnly = isReadOnly; - + localDef->mIsReadOnly = isReadOnly; + if (!initHandled) { if (isLet) @@ -1647,11 +1656,11 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD } _CheckConst(); - + bool localNeedsAddr = false; bool allowValueAccess = true; if (mHasFullDebugInfo) - { + { //if (!IsTargetingBeefBackend()) if (!isConst) @@ -1660,7 +1669,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD /*if (mCurMethodInstance->mMethodDef->mName != "Boop2") dbgNeedsAddr = true;*/ } - + // This is required because of lifetime and LLVM domination rules for certain instances of variable declarations in binary conditionals. // IE: if ((something) && (let a = somethingElse)) if ((exprEvaluator != NULL) && (!isConst)) @@ -1668,14 +1677,14 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD localNeedsAddr = true; allowValueAccess = false; } - + if ((varDecl->mEqualsNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!initHandled)) { mCompiler->mResolvePassData->mAutoComplete->CheckEmptyStart(varDecl->mEqualsNode, resolvedType); } BfIRInitType initType = BfIRInitType_NotSet; - + if (varDecl->mInitializer != NULL) { initType = BfIRInitType_NotNeeded_AliveOnDecl; @@ -1686,11 +1695,11 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { BfConstResolver constResolver(this); initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_ActualizeValues); - if (!initValue) + if (!initValue) initValue = GetDefaultTypedValue(resolvedType); } - else if (varDecl->mInitializer->IsA()) - { + else if (varDecl->mInitializer->IsA()) + { // Fake 'is assigned' } else @@ -1711,7 +1720,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if ((!handledVarInit) && (initValue)) initValue = Cast(varDecl->mInitializer, initValue, resolvedType, BfCastFlags_PreferAddr); } - + if ((initValue) && (resolvedType->IsUndefSizedArray())) { resolvedType = initValue.mType; @@ -1724,8 +1733,8 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { // Handled later } - else if (varDecl->mInitializer->IsA()) - { + else if (varDecl->mInitializer->IsA()) + { // Fake 'is assigned' initType = BfIRInitType_Uninitialized; } @@ -1778,8 +1787,8 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { localDef->mAddr = initValue.mValue; if (localDef->mIsReadOnly) - localDef->mValue = mBfIRBuilder->CreateLoad(localDef->mAddr); - } + localDef->mValue = mBfIRBuilder->CreateLoad(localDef->mAddr); + } if (WantsLifetimes()) mCurMethodState->mCurScope->mDeferredLifetimeEnds.push_back(localDef->mAddr); } @@ -1814,13 +1823,16 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD initValue = BfTypedValue(); } + if (!initValue) + initValue = GetDefaultTypedValue(localDef->mResolvedType); + localDef->mAddr = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(localDef->mResolvedType), false, BfIRLinkageType_Internal, initValue.mValue, name);; initHandled = true; } bool wantsStore = false; if ((initValue) && (!handledVarStore) && (!isConst) && (!initHandled)) - { + { initValue = LoadValue(initValue); if (initValue.IsSplat()) { @@ -1872,16 +1884,16 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD else if ((resolvedType->IsPointer()) || (resolvedType->IsObjectOrInterface())) { exprEvaluator->mResult = BfTypedValue(mBfIRBuilder->CreateIsNotNull(initValue.mValue), boolType); - } + } else if (resolvedType->IsVar()) { exprEvaluator->mResult = GetDefaultTypedValue(GetPrimitiveType(BfTypeCode_Boolean), false, BfDefaultValueKind_Undef); } else - { + { // Always true if ((!IsInSpecializedSection()) && (!resolvedType->IsGenericParam())) - Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' since a value of type '%s' can never be null", + Warn(BfWarning_CS0472_ValueTypeNullCompare, StrFormat("Variable declaration is always 'true' since a value of type '%s' can never be null", TypeToString(initValue.mType).c_str()), varDecl); exprEvaluator->mResult = BfTypedValue(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 1), boolType); } @@ -1911,18 +1923,59 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD ValidateAllocation(localDef->mResolvedType, varDecl->mTypeRef); if ((exprEvaluator == NULL) && (varDecl->GetSourceData() != NULL)) - UpdateSrcPos(varDecl); + UpdateSrcPos(varDecl); localDef->Init(); if (localDef->mConstValue) - initType = BfIRInitType_NotNeeded; + initType = BfIRInitType_NotNeeded; BfLocalVariable* localVar = AddLocalVariableDef(localDef, true, false, BfIRValue(), initType); if (wantsStore) mBfIRBuilder->CreateAlignedStore(initValue.mValue, localVar->mAddr, localVar->mResolvedType->mAlign); + + if ((mCurMethodState->mConstResolveState != NULL) && (mCurMethodState->mConstResolveState->mInCalcAppend)) + { + if (localDef->mValue.IsConst()) + localDef->mConstValue = localDef->mValue; + } + return localVar; } +BfLocalVariable* BfModule::HandleVariableDeclaration(BfType* type, BfAstNode* nameNode, BfTypedValue val, bool updateSrcLoc, bool forceAddr) +{ + BfLocalVariable* localDef = new BfLocalVariable(); + nameNode->ToString(localDef->mName); + localDef->mNameNode = BfNodeDynCast(nameNode); + localDef->mResolvedType = type; + localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; + localDef->mValue = val.mValue; + + if ((!localDef->mIsReadOnly) || (mHasFullDebugInfo)) + { + localDef->mAddr = AllocLocalVariable(localDef->mResolvedType, localDef->mName); + if ((val.mValue) && (!localDef->mResolvedType->IsValuelessType()) && (!localDef->mResolvedType->IsVar())) + { + if (localDef->mResolvedType->IsRef()) + val = MakeAddressable(val, true, true); + + if (val.IsSplat()) + { + AggregateSplatIntoAddr(val, localDef->mAddr); + } + else + mBfIRBuilder->CreateAlignedStore(val.mValue, localDef->mAddr, localDef->mResolvedType->mAlign); + } + } + + CheckVariableDef(localDef); + + if (nameNode->GetSourceData() != NULL) + UpdateSrcPos(nameNode); + localDef->Init(); + return AddLocalVariableDef(localDef, true); +} + BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc, bool forceAddr) { if (varDecl->mEqualsNode != NULL) @@ -1930,15 +1983,13 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if (varDecl->mInitializer != NULL) CreateValueFromExpression(varDecl->mInitializer); - auto isLet = varDecl->mTypeRef->IsA(); + auto isLet = varDecl->mTypeRef->IsA(); auto isVar = varDecl->mTypeRef->IsA(); bool isRef = false; if (auto varRefTypeReference = BfNodeDynCast(varDecl->mTypeRef)) { - BF_ASSERT(val.IsAddr()); isRef = true; - isLet = varRefTypeReference->mVarToken->GetToken() == BfToken_Let; isVar = varRefTypeReference->mVarToken->GetToken() == BfToken_Var; } @@ -1957,11 +2008,11 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD // type = ResolveTypeRef(varDecl->mTypeRef); // if (type == NULL) // type = mContext->mBfObjectType; -// } +// } BfType* type = NULL; if ((isLet) || (isVar)) - { + { type = val.mType; } else @@ -1969,14 +2020,13 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD type = ResolveTypeRef(varDecl->mTypeRef); } if (type == NULL) - { + { type = GetPrimitiveType(BfTypeCode_Var); val = GetDefaultTypedValue(type); } if ((type->IsVar()) || (type->IsLet())) { - } if (isRef) @@ -1989,20 +2039,25 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD varDecl->mNameNode->ToString(localDef->mName); localDef->mNameNode = BfNodeDynCast(varDecl->mNameNode); localDef->mResolvedType = type; - localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; + localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; localDef->mValue = val.mValue; if (isLet) { - localDef->mIsReadOnly = true; + localDef->mIsReadOnly = true; } if ((!localDef->mIsReadOnly) || (mHasFullDebugInfo) || (forceAddr)) { - localDef->mAddr = AllocLocalVariable(localDef->mResolvedType, localDef->mName); + localDef->mAddr = AllocLocalVariable(localDef->mResolvedType, localDef->mName); if ((val.mValue) && (!localDef->mResolvedType->IsValuelessType()) && (!localDef->mResolvedType->IsVar())) { + if (localDef->mResolvedType->IsRef()) + val = MakeAddressable(val, true, true); + if (val.IsSplat()) + { AggregateSplatIntoAddr(val, localDef->mAddr); + } else mBfIRBuilder->CreateAlignedStore(val.mValue, localDef->mAddr, localDef->mResolvedType->mAlign); } @@ -2015,7 +2070,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD if ((updateSrcLoc) && (varDecl->GetSourceData() != NULL)) UpdateSrcPos(varDecl); localDef->Init(); - return AddLocalVariableDef(localDef, true); + return AddLocalVariableDef(localDef, true); } void BfModule::CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType) @@ -2058,9 +2113,9 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf initTupleType = (BfTypeInstance*)initTupleValue.mType; CheckTupleVariableDeclaration(tupleExpr, initTupleValue.mType); - + for (int varIdx = 0; varIdx < (int)tupleExpr->mValues.size(); varIdx++) - { + { BfType* resolvedType = NULL; BfTypedValue initValue; if ((initTupleType != NULL) && (varIdx < (int)initTupleType->mFieldInstances.size())) @@ -2108,7 +2163,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf if (!varNameNode->IsExact()) { if (BfTupleExpression* innerTupleExpr = BfNodeDynCast(varNameNode)) - { + { HandleTupleVariableDeclaration(varDecl, innerTupleExpr, initValue, isReadOnly, isConst, false, declBlock); } else if (!varNameNode->IsExact()) @@ -2120,22 +2175,22 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf BfLocalVariable* localDef = new BfLocalVariable(); varNameNode->ToString(localDef->mName); - localDef->mNameNode = BfNodeDynCast(varNameNode); + localDef->mNameNode = BfNodeDynCast(varNameNode); localDef->mResolvedType = resolvedType; localDef->mReadFromId = 0; // Don't give usage errors for binds if (isReadOnly) { localDef->mIsReadOnly = true; if ((initValue) && (initValue.mValue.IsConst())) - { + { isConst = true; } } CheckVariableDef(localDef); if ((!isConst) && ((forceAddr) || (!localDef->mIsReadOnly) || (mHasFullDebugInfo))) - { - localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName); + { + localDef->mAddr = AllocLocalVariable(resolvedType, localDef->mName); } if ((varDecl != NULL) && (varDecl->mEqualsNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!initHandled)) @@ -2148,13 +2203,13 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf if ((!isConst) && (!initHandled)) { if (initValue) - { + { if (!forceAddr) localDef->mValue = initValue.mValue; if (localDef->mAddr) { mBfIRBuilder->CreateStore(initValue.mValue, localDef->mAddr); - } + } } else if ((varDecl == NULL) || (varDecl->mInitializer->IsA())) { @@ -2166,7 +2221,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf } } - localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; + localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; } else if ((varDecl != NULL) && (varDecl->mInitializer == NULL)) { @@ -2212,15 +2267,15 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl) BfTypedValue initTupleValue; bool hadVarType = false; bool isLet = varDecl->mTypeRef->IsA(); - bool isVar = varDecl->mTypeRef->IsA(); + bool isVar = varDecl->mTypeRef->IsA(); bool wasVarOrLet = isVar || isLet; - + if ((!isLet) && (!isVar)) { ResolveTypeRef(varDecl->mTypeRef); Fail("'var' or 'let' expected", varDecl->mTypeRef); isVar = true; - } + } if ((isVar) || (isLet)) { @@ -2244,10 +2299,10 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl) } initTupleValue = LoadValue(initTupleValue); - + if ((bfAutocomplete != NULL) && (wasVarOrLet)) bfAutocomplete->CheckVarResolution(varDecl->mTypeRef, initTupleValue.mType); - } + } bool isCompatible = false; if (initTupleValue) @@ -2278,7 +2333,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr auto tupleFieldInstance = &tupleType->mFieldInstances[tupleFieldIdx]; if (tupleFieldIdx >= arguments.size()) - { + { BfError* error = Fail(StrFormat("Not enough parameters specified, expected %d more.", tupleType->mFieldInstances.size() - (int)arguments.size()), tooFewRef); break; } @@ -2308,7 +2363,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr if (wantType == NULL) wantType = mContext->mBfObjectType; if (wantType != NULL) - tupleElement = Cast(varDecl->mTypeRef, tupleElement, wantType); + tupleElement = Cast(varDecl->mTypeRef, tupleElement, wantType); if (!tupleElement) tupleElement = GetDefaultTypedValue(wantType); } @@ -2325,13 +2380,38 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr continue; } + if (auto binOpExpr = BfNodeDynCast(expr)) + { + if (binOpExpr->mOp == BfBinaryOp_Multiply) + { + SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); + auto resolvedType = ResolveTypeRef(binOpExpr->mLeft, NULL); + prevIgnoreError.Restore(); + if (resolvedType != NULL) + { + resolvedType = CreatePointerType(resolvedType); + + PopulateType(tupleElement.mType); + tupleElement = LoadValue(tupleElement); + tupleElement = Cast(binOpExpr->mLeft, tupleElement, resolvedType); + + if (prevHadFallthrough) + Fail("Destructuring cannot be used when the previous case contains a fallthrough", expr); + + auto localVar = HandleVariableDeclaration(resolvedType, binOpExpr->mRight, tupleElement, false, true); + localVar->mReadFromId = 0; // Don't give usage errors for binds + continue; + } + } + } + if (auto uninitExpr = BfNodeDynCast(expr)) { continue; } if (tupleFieldInstance->mDataIdx >= 0) - { + { if (auto tupleExpr = BfNodeDynCast(expr)) { if (tupleElement.mType->IsTuple()) @@ -2340,7 +2420,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr if (tupleExpr->mValues.size() > 0) tooFewRef = tupleExpr->mValues[tupleExpr->mValues.size() - 1]; if (tooFewRef == NULL) - tooFewRef = tupleExpr->mOpenParen; + tooFewRef = tupleExpr->mOpenParen; HandleCaseEnumMatch_Tuple(tupleElement, tupleExpr->mValues, tooFewRef, phiVal, matchedBlockStart, matchedBlockEnd, falseBlockStart, falseBlockEnd, hadConditional, clearOutOnMismatch, prevHadFallthrough); continue; } @@ -2376,7 +2456,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr } else enumTagVal = BfTypedValue(mBfIRBuilder->CreateExtractValue(tupleElement.mValue, 2), intType, false); - + int uncondTagId = -1; bool hadConditional = false; exprResult = TryCaseEnumMatch(tupleElementAddr, enumTagVal, expr, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, prevHadFallthrough); @@ -2414,7 +2494,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr continue; if (argValue.mType->IsRef()) - { + { auto refType = (BfRefType*)argValue.mType; if (refType->mRefKind != BfRefType::RefKind_Out) { @@ -2443,23 +2523,23 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr argValue = LoadValue(argValue); argValue = Cast(expr, argValue, tupleFieldInstance->GetResolvedType()); if (!argValue) - continue; - + continue; + exprEvaluator.PerformBinaryOperation(expr, expr, BfBinaryOp_Equality, expr, BfBinOpFlag_NoClassify, tupleElement, argValue); exprResult = exprEvaluator.mResult; } - + if (exprResult) { hadConditional = true; if (phiVal) { - auto insertBlock = mBfIRBuilder->GetInsertBlock(); + auto insertBlock = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->AddPhiIncoming(phiVal, mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), insertBlock); } - + matchedBlockStart = matchedBlockEnd = mBfIRBuilder->CreateBlock("match", false); - + mBfIRBuilder->CreateCondBr(exprResult.mValue, matchedBlockStart, falseBlockStart); mBfIRBuilder->AddBlock(matchedBlockStart); mBfIRBuilder->SetInsertPoint(matchedBlockStart); @@ -2487,7 +2567,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr auto curInsertPoint = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPoint(falseBlockEnd); for (auto& deferredAssign : deferredAssigns) - { + { auto tupleFieldInstance = &tupleType->mFieldInstances[deferredAssign.mFieldIdx]; // We have to re-process the expr because we haven't done it in this branch, and then clear the result out SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, mHadBuildError); // Don't fail twice @@ -2514,7 +2594,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr CreateValueFromExpression(expr); } - BfAstNode* errorRef = arguments[(int)tupleType->mFieldInstances.size()]; + BfAstNode* errorRef = arguments[(int)tupleType->mFieldInstances.size()]; BfError* error = Fail(StrFormat("Too many arguments, expected %d fewer.", arguments.size() - tupleType->mFieldInstances.size()), errorRef); } } @@ -2549,7 +2629,7 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio auto methodMatchInfo = autoComplete->mMethodMatchInfo; // auto methodDef = tupleType->mTypeDef->mMethods[0]; -// +// // BfAutoComplete::MethodMatchEntry methodMatchEntry; // methodMatchEntry.mMethodDef = methodDef; // methodMatchEntry.mTypeInstance = tupleType; @@ -2642,12 +2722,12 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio BfIRValue phiVal; if (eqBlock == NULL) phiVal = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(boolType), 2); - + mBfIRBuilder->SetInsertPoint(matchedBlockStart); BfIRBlock matchedBlockEnd = matchedBlockStart; - HandleCaseEnumMatch_Tuple(tupleVal, tupleExpr->mValues, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd, + HandleCaseEnumMatch_Tuple(tupleVal, tupleExpr->mValues, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd, falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd, hadConditional, clearOutOnMismatch, prevHadFallthrough); - + if (phiVal) { auto falseVal = mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0); @@ -2696,7 +2776,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa { targetType = enumVal.mType; } - else if (auto typeRef = BfNodeDynCast(memberRefExpr->mTarget)) + else if (auto typeRef = BfNodeDynCast(memberRefExpr->mTarget)) { SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); targetType = ResolveTypeRef(typeRef); @@ -2748,7 +2828,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa TypeToString(enumVal.mType).c_str(), TypeToString(enumType).c_str())); enumVal = GetDefaultTypedValue(enumType); tagVal = GetDefaultTypedValue(tagType); - } + } for (int fieldIdx = 0; fieldIdx < (int)enumType->mFieldInstances.size(); fieldIdx++) { @@ -2768,7 +2848,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa if (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) resolvePassData->HandleFieldReference(nameNode, enumType->mTypeDef, fieldDef); String filter; - auto autoComplete = resolvePassData->mAutoComplete; + auto autoComplete = resolvePassData->mAutoComplete; if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(dotNode, nameNode, filter))) autoComplete->AddEnumTypeMembers(enumType, enumCaseName, false, enumType == mCurTypeInstance); } @@ -2789,10 +2869,10 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa BfIRBlock falseBlockEnd; BfIRBlock doneBlockStart; BfIRBlock doneBlockEnd; - if (notEqBlock != NULL) + if (notEqBlock != NULL) doneBlockStart = doneBlockEnd = *notEqBlock; - else - doneBlockStart = doneBlockEnd = mBfIRBuilder->CreateBlock("caseDone", false); + else + doneBlockStart = doneBlockEnd = mBfIRBuilder->CreateBlock("caseDone", false); if (clearOutOnMismatch) { @@ -2805,32 +2885,32 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa if (matchBlock != NULL) *matchBlock = matchedBlockStart; mBfIRBuilder->CreateCondBr(eqResult, matchedBlockStart, falseBlockStart ? falseBlockStart : doneBlockStart); - + mBfIRBuilder->AddBlock(matchedBlockStart); - + mBfIRBuilder->SetInsertPoint(doneBlockEnd); BfIRValue phiVal; if (eqBlock == NULL) phiVal = mBfIRBuilder->CreatePhi(mBfIRBuilder->MapType(boolType), 1 + (int)tupleType->mFieldInstances.size()); - + mBfIRBuilder->SetInsertPoint(matchedBlockEnd); - + BfTypedValue tupleVal; if (!enumVal.IsAddr()) { auto unionInnerType = enumType->GetUnionInnerType(); if (unionInnerType == tupleType) - { - tupleVal = ExtractValue(enumVal, NULL, 1); + { + tupleVal = ExtractValue(enumVal, NULL, 1); } } if (!tupleVal) - { + { if (!tupleType->IsValuelessType()) { tupleVal = ExtractValue(enumVal, NULL, 1); - tupleVal = Cast(NULL, tupleVal, tupleType, BfCastFlags_Force); + tupleVal = Cast(NULL, tupleVal, tupleType, BfCastFlags_Force); } else tupleVal = GetDefaultTypedValue(tupleType); @@ -2842,7 +2922,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa if ((tooFewRef == NULL) && (!invocationExpr->mCommas.IsEmpty())) tooFewRef = invocationExpr->mCommas[invocationExpr->mCommas.size() - 1]; else if (tooFewRef == NULL) - tooFewRef = invocationExpr->mOpenParen; + tooFewRef = invocationExpr->mOpenParen; /// @@ -2855,7 +2935,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa autoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas); if (autoComplete->mIsCapturingMethodMatchInfo) - { + { autoComplete->mMethodMatchInfo->mInstanceList.Clear(); auto methodMatchInfo = autoComplete->mMethodMatchInfo; @@ -2898,7 +2978,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa if (fieldDef->IsUnnamedTupleField()) insertStr = "p"; insertStr += fieldDef->mName; - + insertStr.Insert(0, "let "); autoComplete->mEntriesSet.Clear(); autoComplete->AddEntry(AutoCompleteEntry("paramName", insertStr)); @@ -2918,7 +2998,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa /// - HandleCaseEnumMatch_Tuple(tupleVal, invocationExpr->mArguments, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd, + HandleCaseEnumMatch_Tuple(tupleVal, invocationExpr->mArguments, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd, falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd, hadConditional, clearOutOnMismatch, prevHadFallthrough); @@ -2941,7 +3021,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa mBfIRBuilder->CreateBr(doneBlockStart); if (falseBlockEnd) - { + { mBfIRBuilder->SetInsertPoint(falseBlockEnd); mBfIRBuilder->CreateBr(doneBlockStart); //mBfIRBuilder->AddPhiIncoming(phiVal, mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0), falseBlock); @@ -2962,7 +3042,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int* outEnumIdx) { - BfTypeInstance* tupleType = NULL; + BfTypeInstance* tupleType = NULL; auto activeTypeDef = GetActiveTypeDef(); @@ -2992,9 +3072,8 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& } else if (auto typeRef = BfNodeDynCast(memberExpr->mTarget)) { - type = ResolveTypeRef(typeRef); + type = ResolveTypeRef(typeRef); } - } targetNode = memberExpr->mTarget; @@ -3015,7 +3094,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& } if (!findName.empty()) - { + { if (type != NULL) { if (type != enumVal.mType) @@ -3031,7 +3110,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& { auto fieldDef = fieldInstance.GetFieldDef(); if ((fieldDef != NULL) && (fieldDef->IsEnumCaseEntry()) && (fieldDef->mName == findName)) - { + { if ((!enumType->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, this)) || (!enumType->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef))) continue; @@ -3042,7 +3121,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& if (resolvePassData->mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) resolvePassData->HandleFieldReference(nameNode, enumType->mTypeDef, fieldDef); String filter; - auto autoComplete = resolvePassData->mAutoComplete; + auto autoComplete = resolvePassData->mAutoComplete; if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(dotNode, nameNode, filter))) autoComplete->AddEnumTypeMembers(enumType, findName, false, enumType == mCurTypeInstance); } @@ -3064,8 +3143,8 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& { Fail(StrFormat("Type '%s' is not an enum type", TypeToString(type).c_str()), targetNode); } - } - } + } + } BF_ASSERT(tagVal.mType->IsPrimitiveType()); eqResult = mBfIRBuilder->CreateCmpEQ(tagVal.mValue, mBfIRBuilder->CreateConst(((BfPrimitiveType*)tagVal.mType)->mTypeDef->mTypeCode, enumIdx)); @@ -3087,7 +3166,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& auto mainBlock = mBfIRBuilder->GetInsertBlock(); - BfIRBlock trueBlock = mBfIRBuilder->CreateBlock("eqBlock", false); + BfIRBlock trueBlock = mBfIRBuilder->CreateBlock("eqBlock", false); if (matchBlock != NULL) *matchBlock = trueBlock; mBfIRBuilder->AddBlock(trueBlock); @@ -3116,7 +3195,7 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& { tupleVal = MakeAddressable(tupleVal); tupleVal = BfTypedValue(mBfIRBuilder->CreateBitCast(tupleVal.mValue, mBfIRBuilder->MapTypeInstPtr(tupleType)), tupleType, true); - } + } } HandleTupleVariableDeclaration(NULL, bindExpr->mBindNames, tupleVal, isLet, false, true /*, &mainBlock*/); @@ -3133,12 +3212,12 @@ BfTypedValue BfModule::HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& mBfIRBuilder->CreateBr(falseBlock); // Don't create the condBr until now, so HandleTupleVariableDeclaration can create the variable declarations in mainBlock-- - // we need them there since the code that uses the new variables is created outside the eqBlock + // we need them there since the code that uses the new variables is created outside the eqBlock mBfIRBuilder->SetInsertPoint(mainBlock); mBfIRBuilder->CreateCondBr(eqResult, trueBlock, falseBlock); mBfIRBuilder->AddBlock(falseBlock); - mBfIRBuilder->SetInsertPoint(falseBlock); + mBfIRBuilder->SetInsertPoint(falseBlock); return BfTypedValue(eqResult, boolType); } @@ -3196,11 +3275,11 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval } else if (mCurMethodState != NULL) { - bool isIgnore = mBfIRBuilder->mIgnoreWrites; - + bool isIgnore = mBfIRBuilder->mIgnoreWrites; + mCurMethodState->mInHeadScope = false; - BfScopeData scopeData; + BfScopeData scopeData; if (IsTargetingBeefBackend()) scopeData.mValueScopeStart = mBfIRBuilder->CreateValueScopeStart(); @@ -3209,14 +3288,14 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval { mCurMethodState->mCurScope->mAstBlock = block; mCurMethodState->mCurScope->mCloseNode = closeBrace; - } + } if (labelNode != NULL) scopeData.mLabelNode = labelNode->mLabel; NewScopeState(block != NULL); mCurMethodState->mCurScope->mOuterIsConditional = (flags & BfEmbeddedStatementFlags_IsConditional) != 0; mCurMethodState->mCurScope->mIsDeferredBlock = (flags & BfEmbeddedStatementFlags_IsDeferredBlock) != 0; - mCurMethodState->mCurScope->mExprEvaluator = exprEvaluator; - + mCurMethodState->mCurScope->mExprEvaluator = exprEvaluator; + // { SetAndRestoreValue inDeferredBlock(mCurMethodState->mInDeferredBlock, mCurMethodState->mInDeferredBlock || mCurMethodState->mCurScope->mIsDeferredBlock); @@ -3264,7 +3343,7 @@ void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEval } } -void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn, BfLabelNode* labelNode, bool closeScope) +void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakBlock, BfIRBlock fallthroughBlock, bool defaultBreak, bool* hadReturn, BfLabelNode* labelNode, bool closeScope, BfEmbeddedStatementFlags flags) { BfBreakData breakData; breakData.mIRContinueBlock = continueBlock; @@ -3274,9 +3353,9 @@ void BfModule::VisitCodeBlock(BfBlock* block, BfIRBlock continueBlock, BfIRBlock breakData.mPrevBreakData = mCurMethodState->mBreakData; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); - Visit(block); + VisitEmbeddedStatement(block, NULL, flags); - if (closeScope) + if (closeScope) RestoreScopeState(); if ((!mCurMethodState->mLeftBlockUncond) && (defaultBreak)) @@ -3299,15 +3378,15 @@ void BfModule::VisitCodeBlock(BfBlock* block) BfIRBlock prevInsertBlock; bool hadReturn = false; - + int startLocalMethod = 0; // was -1 auto rootMethodState = mCurMethodState->GetRootMethodState(); - BfIRBlock startInsertBlock = mBfIRBuilder->GetInsertBlock(); + BfIRBlock startInsertBlock = mBfIRBuilder->GetInsertBlock(); bool allowLocalMethods = mCurMethodInstance != NULL; //int startDeferredLocalIdx = (int)rootMethodState->mDeferredLocalMethods.size(); - + int curLocalMethodIdx = -1; // Scan for any local method declarations @@ -3323,7 +3402,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) { BfLocalMethod* localMethod; auto rootMethodState = mCurMethodState->GetRootMethodState(); - + String methodName; if (localMethodDecl->mMethodDeclaration->mNameNode != NULL) { @@ -3352,7 +3431,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) auto autoComplete = mCompiler->mResolvePassData->mAutoComplete; if (!autoComplete->IsAutocompleteNode(localMethod->mMethodDeclaration)) localMethod->mDeclOnly = true; - } + } if (localMethod->mMethodDeclaration->mNameNode != NULL) localMethod->mMethodName = localMethod->mMethodDeclaration->mNameNode->ToString(); @@ -3368,11 +3447,11 @@ void BfModule::VisitCodeBlock(BfBlock* block) localMethod->mDeclMixinState->mHasDeferredUsage = true; mCurMethodState->mLocalMethods.push_back(localMethod); - String* namePtr; - if (!mCurMethodState->mLocalMethodMap.TryAdd(localMethod->mMethodName, &namePtr, &localMethodPtr)) - { + String* namePtr; + if (!mCurMethodState->mLocalMethodMap.TryAdd(localMethod->mMethodName, &namePtr, &localMethodPtr)) + { BF_ASSERT(localMethod != *localMethodPtr); - localMethod->mNextWithSameName = *localMethodPtr; + localMethod->mNextWithSameName = *localMethodPtr; } *localMethodPtr = localMethod; } @@ -3382,7 +3461,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) } bool wantsAllLocalMethods = true; - auto autoComplete = mCompiler->GetAutoComplete(); + auto autoComplete = mCompiler->GetAutoComplete(); if (autoComplete != NULL) { // If we only need reasoning "at the cursor" then we don't need all local methods @@ -3415,7 +3494,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) BfAstNode* child = *itr; if (auto localMethodDecl = BfNodeDynCastExact(child)) - { + { /*if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)) Fail("Mixins cannot contain local methods", child);*/ @@ -3428,7 +3507,12 @@ void BfModule::VisitCodeBlock(BfBlock* block) BfLocalMethod* localMethod = mCurMethodState->mLocalMethods[curLocalMethodIdx]; BF_ASSERT(localMethod->mMethodDeclaration == localMethodDecl->mMethodDeclaration); - if ((wantsAllLocalMethods) || (autoComplete->IsAutocompleteNode(localMethod->mMethodDeclaration))) + bool wantsLocalMethod = (wantsAllLocalMethods) || (autoComplete->IsAutocompleteNode(localMethod->mMethodDeclaration)); + + if ((!wantsLocalMethod) && (mCurMethodInstance->mMethodDef->mIsLocalMethod)) + wantsLocalMethod = true; + + if (wantsLocalMethod) { if (!mCurMethodInstance->IsSpecializedGenericMethodOrType()) GetLocalMethodInstance(localMethod, BfTypeVector(), NULL, true); // Only necessary on unspecialized pass @@ -3444,12 +3528,11 @@ void BfModule::VisitCodeBlock(BfBlock* block) continue; } - if ((mCurMethodState != NULL) && (mCurMethodState->mLeftBlockUncond)) // mLeftBlock is cleared after conditional block is completed { if (mCurMethodState->mHadReturn) hadReturn = true; - + if ((!hadUnreachableCode) && (!mCurMethodState->mInPostReturn)) { if ((mCurMethodState->mCurScope == NULL) || (!mCurMethodState->mCurScope->mSupressNextUnreachable)) @@ -3458,9 +3541,9 @@ void BfModule::VisitCodeBlock(BfBlock* block) hadUnreachableCode = true; prevInsertBlock = mBfIRBuilder->GetInsertBlock(); - mCurMethodState->mInPostReturn = true; + mCurMethodState->mInPostReturn = true; mBfIRBuilder->mIgnoreWrites = true; - } + } } if ((mCurMethodState != NULL) && (mCurMethodState->mCurScope != NULL)) mCurMethodState->mCurScope->mSupressNextUnreachable = false; @@ -3468,7 +3551,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) if (itr.IsLast()) { if (auto expr = BfNodeDynCast(child)) - { + { if (expr->IsExpression()) { if (mCurMethodState != NULL) @@ -3491,20 +3574,20 @@ void BfModule::VisitCodeBlock(BfBlock* block) if ((exprEvaluator->mResult) && (!exprEvaluator->mResult.mType->IsValuelessType()) && (!exprEvaluator->mResult.mValue.IsConst()) && (!exprEvaluator->mResult.IsAddr()) && (!exprEvaluator->mResult.mValue.IsFake())) - { - if ((mCurMethodState->mCurScope != NULL) && (mCurMethodState->mCurScope->mPrevScope != NULL)) + { + if ((mCurMethodState->mCurScope != NULL) && (mCurMethodState->mCurScope->mPrevScope != NULL)) { // We need to make sure we don't retain any values through the scope's ValueScopeHardEnd - and extend alloca through previous scope bool wasReadOnly = exprEvaluator->mResult.IsReadOnly(); - FixIntUnknown(exprEvaluator->mResult, exprEvaluator->mExpectingType); - auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); + FixIntUnknown(exprEvaluator->mResult, exprEvaluator->mExpectingType); + auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); auto tempVar = CreateAlloca(exprEvaluator->mResult.mType, false, "blockExpr"); mBfIRBuilder->SetInsertPointAtStart(startInsertBlock); auto lifetimeStart = mBfIRBuilder->CreateLifetimeStart(tempVar); mBfIRBuilder->ClearDebugLocation(lifetimeStart); - - if (!mBfIRBuilder->mIgnoreWrites) + + if ((!mBfIRBuilder->mIgnoreWrites) && (IsTargetingBeefBackend())) mCurMethodState->mCurScope->mPrevScope->mDeferredLifetimeEnds.push_back(tempVar); mBfIRBuilder->SetInsertPoint(prevInsertBlock); if (exprEvaluator->mResult.IsSplat()) @@ -3514,9 +3597,15 @@ void BfModule::VisitCodeBlock(BfBlock* block) exprEvaluator->mResult = BfTypedValue(tempVar, exprEvaluator->mResult.mType, exprEvaluator->mResult.IsThis() ? (wasReadOnly ? BfTypedValueKind_ReadOnlyThisAddr : BfTypedValueKind_ThisAddr) : - (wasReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr)); + (wasReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr)); } } + + if (exprEvaluator->mResult.IsAddr()) + { + if (mCurMethodState->mCurScope->ExtendLifetime(exprEvaluator->mResult.mValue)) + mBfIRBuilder->CreateLifetimeSoftEnd(exprEvaluator->mResult.mValue); + } } break; @@ -3529,7 +3618,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin()) && (mCurMethodState->mCurScope == &mCurMethodState->mHeadScope)) { // Only in mixin definition - result ignored - CreateValueFromExpression(expr); + CreateValueFromExpression(expr, NULL, BfEvalExprFlags_AllowRefExpr); break; } else @@ -3538,10 +3627,10 @@ void BfModule::VisitCodeBlock(BfBlock* block) } } } - } + } } - - UpdateSrcPos(child); + + UpdateSrcPos(child); BfAutoParentNodeEntry autoParentNode(this, child); if ((mAttributeState != NULL) && @@ -3551,14 +3640,14 @@ void BfModule::VisitCodeBlock(BfBlock* block) } else child->Accept(this); - + mContext->CheckLockYield(); ++itr; } if (mCurMethodState != NULL) - { + { // Any local method that hasn't been called needs to be processed now for (int localMethodIdx = startLocalMethod; localMethodIdx < (int)mCurMethodState->mLocalMethods.size(); localMethodIdx++) { @@ -3572,9 +3661,9 @@ void BfModule::VisitCodeBlock(BfBlock* block) } while ((int)mCurMethodState->mLocalMethods.size() > startLocalMethod) - { + { auto localMethod = mCurMethodState->mLocalMethods.back(); - + #if _DEBUG BfLocalMethod** localMethodPtr = NULL; mCurMethodState->mLocalMethodMap.TryGetValue(localMethod->mMethodName, &localMethodPtr); @@ -3587,8 +3676,8 @@ void BfModule::VisitCodeBlock(BfBlock* block) mCurMethodState->mLocalMethodMap[localMethod->mMethodName] = localMethod->mNextWithSameName; localMethod->mNextWithSameName = NULL; } - - mCurMethodState->mLocalMethods.pop_back(); + + mCurMethodState->mLocalMethods.pop_back(); } if (hadUnreachableCode) @@ -3597,11 +3686,11 @@ void BfModule::VisitCodeBlock(BfBlock* block) mCurMethodState->SetHadReturn(true); mCurMethodState->mLeftBlockUncond = true; mCurMethodState->mInPostReturn = false; - + if (prevInsertBlock) mBfIRBuilder->SetInsertPoint(prevInsertBlock); } - } + } } void BfModule::Visit(BfAstNode* astNode) @@ -3611,7 +3700,7 @@ void BfModule::Visit(BfAstNode* astNode) void BfModule::Visit(BfIdentifierNode* identifierNode) { - Visit((BfExpression*)identifierNode); + Visit((BfExpression*)identifierNode); } void BfModule::Visit(BfTypeReference* typeRef) @@ -3623,7 +3712,6 @@ void BfModule::Visit(BfTypeReference* typeRef) void BfModule::Visit(BfEmptyStatement* astNode) { - } void BfModule::Visit(BfTryStatement* tryStmt) @@ -3650,7 +3738,7 @@ void BfModule::Visit(BfCheckedStatement* checkedStmt) } void BfModule::Visit(BfUncheckedStatement* uncheckedStmt) -{ +{ VisitChild(uncheckedStmt->mStatement); } @@ -3664,7 +3752,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i { AssertErrorState(); return; - } + } //TODO: Only conditionally create the scopeData here if we create a variable inside the condition statement @@ -3675,30 +3763,30 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i newScope.mScopeKind = BfScopeKind_StatementTarget; if (ifStmt->mLabelNode != NULL) newScope.mLabelNode = ifStmt->mLabelNode->mLabel; - mCurMethodState->AddScope(&newScope); + mCurMethodState->AddScope(&newScope); NewScopeState(); - BfBreakData breakData; + BfBreakData breakData; breakData.mScope = &newScope; - breakData.mPrevBreakData = mCurMethodState->mBreakData; - SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); + breakData.mPrevBreakData = mCurMethodState->mBreakData; + SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); - auto boolType = GetPrimitiveType(BfTypeCode_Boolean); + auto boolType = GetPrimitiveType(BfTypeCode_Boolean); - BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); + BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); deferredLocalAssignData.mIsIfCondition = true; deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, true); deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); BfAutoParentNodeEntry autoParentNodeEntry(this, ifStmt); - BfTypedValue condValue = CreateValueFromExpression(ifStmt->mCondition, boolType); + BfTypedValue condValue = CreateValueFromExpression(ifStmt->mCondition, boolType); newScope.mScopeKind = BfScopeKind_Normal; deferredLocalAssignData.mIsIfCondition = false; - // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and + // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and // conditionally executed code (in the case of "(GetVal(out a) && GetVal(out b))" for example mCurMethodState->mDeferredLocalAssignData->BreakExtendChain(); @@ -3707,7 +3795,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i AssertErrorState(); condValue = BfTypedValue(GetDefaultValue(boolType), boolType); } - + BfIRBlock trueBB; BfIRBlock falseBB; bool isConstBranch = false; @@ -3723,7 +3811,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i } if (!isConstBranch) - { + { trueBB = mBfIRBuilder->CreateBlock("if.then", true); falseBB = (ifStmt->mFalseStatement == NULL) ? BfIRBlock() : mBfIRBuilder->CreateBlock("if.else"); } @@ -3737,7 +3825,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i mBfIRBuilder->CreateCondBr(condValue.mValue, trueBB, (falseBB) ? falseBB : contBB); } - // TRUE statement + // TRUE statement bool ignoredLastBlock = true; if (includeTrueStmt) @@ -3757,10 +3845,11 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i VisitEmbeddedStatement(ifStmt->mTrueStatement); } prevDLA.Restore(); + if (mCurMethodState->mDeferredLocalAssignData != NULL) mCurMethodState->mDeferredLocalAssignData->mHadBreak |= deferredLocalAssignData.mHadBreak; - bool trueHadReturn = mCurMethodState->mHadReturn; + bool trueHadReturn = mCurMethodState->mHadReturn; // We restore the scopeData before the False block because we don't want variables created in the if condition to // be visible in the false section @@ -3771,11 +3860,14 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i mBfIRBuilder->CreateBr_NoCollapse(contBB); if (mCurMethodState->mLeftBlockUncond) + { + deferredLocalAssignData.mLeftBlockUncond = true; mCurMethodState->mLeftBlockCond = true; + } mCurMethodState->mLeftBlockUncond = false; mCurMethodState->SetHadReturn(false); - + bool falseHadReturn = false; if (ifStmt->mFalseStatement != NULL) { @@ -3786,9 +3878,9 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i mBfIRBuilder->AddBlock(falseBB); mBfIRBuilder->SetInsertPoint(falseBB); } - + ignoredLastBlock = true; - // + // { SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites); SetAndRestoreValue prevInConstIgnore(mCurMethodState->mCurScope->mInConstIgnore); @@ -3801,15 +3893,14 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i else ignoredLastBlock = false; falseDeferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData); - SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &falseDeferredLocalAssignData); + SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &falseDeferredLocalAssignData); if (includeFalseStmt) VisitEmbeddedStatement(ifStmt->mFalseStatement, NULL, BfEmbeddedStatementFlags_IsConditional); } if ((!mCurMethodState->mLeftBlockUncond) && (!ignoredLastBlock)) - { - + { if (IsTargetingBeefBackend()) - { + { // If we don't do this, then with: // if (a) { } else if (b) { } // Then we hit the closing second brace even if 'b' is false @@ -3821,7 +3912,10 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i } falseHadReturn = mCurMethodState->mHadReturn; if (mCurMethodState->mLeftBlockUncond) + { + falseDeferredLocalAssignData.mLeftBlockUncond = true; mCurMethodState->mLeftBlockCond = true; + } mCurMethodState->mLeftBlockUncond = false; mCurMethodState->SetHadReturn(false); @@ -3840,15 +3934,15 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i mBfIRBuilder->AddBlock(contBB); mBfIRBuilder->SetInsertPoint(contBB); - + if (isConstBranch) mCurMethodState->SetHadReturn(constResult ? trueHadReturn : falseHadReturn); else - mCurMethodState->SetHadReturn(trueHadReturn && falseHadReturn); + mCurMethodState->SetHadReturn(trueHadReturn && falseHadReturn); mCurMethodState->mLeftBlockUncond = mCurMethodState->mHadReturn; if (mCurMethodState->mHadReturn) - { + { mBfIRBuilder->EraseFromParent(contBB); } else @@ -3873,15 +3967,15 @@ void BfModule::Visit(BfVariableDeclaration* varDecl) BfTupleExpression* tupleVariableDeclaration = BfNodeDynCast(varDecl->mNameNode); if (tupleVariableDeclaration != NULL) { - HandleTupleVariableDeclaration(varDecl); + HandleTupleVariableDeclaration(varDecl); } else - HandleVariableDeclaration(varDecl); + HandleVariableDeclaration(varDecl); } void BfModule::Visit(BfLocalMethodDeclaration* methodDecl) { - Fail("Local method declarations must be wrapped in a block statement", methodDecl->mMethodDeclaration->mNameNode); + Fail("Local method declarations must be wrapped in a block statement", methodDecl->mMethodDeclaration->mNameNode); } void BfModule::Visit(BfAttributedStatement* attribStmt) @@ -3925,13 +4019,13 @@ void BfModule::Visit(BfAttributedStatement* attribStmt) VisitChild(attribStmt->mStatement); } - FinishAttributeState(&attributeState); + FinishAttributeState(&attributeState); } void BfModule::Visit(BfExpression* expression) -{ - UpdateSrcPos(expression); - BfExprEvaluator exprEvaluator(this); +{ + UpdateSrcPos(expression); + BfExprEvaluator exprEvaluator(this); exprEvaluator.mUsedAsStatement = true; exprEvaluator.Evaluate(expression); } @@ -3942,7 +4036,7 @@ void BfModule::Visit(BfExpressionStatement* expressionStmt) } void BfModule::Visit(BfThrowStatement* throwStmt) -{ +{ if (throwStmt->mExpression == NULL) { AssertErrorState(); @@ -3956,11 +4050,11 @@ void BfModule::Visit(BfThrowStatement* throwStmt) if (mCurMethodInstance->mReturnType->IsVoid()) EmitReturn(BfTypedValue()); else - EmitReturn(GetDefaultTypedValue(mCurMethodInstance->mReturnType)); + EmitReturn(GetDefaultTypedValue(mCurMethodInstance->mReturnType)); } void BfModule::Visit(BfDeleteStatement* deleteStmt) -{ +{ UpdateSrcPos(deleteStmt); auto autoComplete = mCompiler->GetAutoComplete(); @@ -3997,41 +4091,45 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) if (val.mType->IsAllocType()) val.mType = val.mType->GetUnderlyingType(); - + BfGenericParamType* genericType = NULL; if (val.mType->IsGenericParam()) genericType = (BfGenericParamType*)val.mType; if ((val.mType->IsPointer()) && (val.mType->GetUnderlyingType()->IsGenericParam())) - genericType = (BfGenericParamType*)val.mType->GetUnderlyingType(); + genericType = (BfGenericParamType*)val.mType->GetUnderlyingType(); auto checkType = val.mType; if (genericType != NULL) { - auto genericParamInst = GetGenericParamInstance(genericType); - if (genericParamInst->mTypeConstraint != NULL) - checkType = genericParamInst->mTypeConstraint; + BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None; + BfType* typeConstraint = NULL; + auto genericParam = GetMergedGenericParamData(genericType, genericParamFlags, typeConstraint); + + if (typeConstraint != NULL) + checkType = typeConstraint; bool canAlwaysDelete = checkType->IsDelegate() || checkType->IsFunction() || checkType->IsArray(); if (auto checkTypeInst = checkType->ToTypeInstance()) { - if ((checkTypeInst->IsInstanceOf(mCompiler->mDelegateTypeDef)) || + if ((checkTypeInst->IsInstanceOf(mCompiler->mDelegateTypeDef)) || (checkTypeInst->IsInstanceOf(mCompiler->mFunctionTypeDef))) canAlwaysDelete = true; } if (!canAlwaysDelete) { - if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var)) + if (genericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var)) return; - if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) + if (genericParamFlags & BfGenericParamFlag_StructPtr) return; - if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Struct) && (checkType->IsPointer())) + if ((genericParamFlags & BfGenericParamFlag_Struct) && (checkType->IsPointer())) return; + auto genericParamInst = GetGenericParamInstance(genericType); Fail(StrFormat("Must add 'where %s : delete' constraint to generic parameter to delete generic type '%s'", genericParamInst->GetGenericParamDef()->mName.c_str(), TypeToString(val.mType).c_str()), deleteStmt->mExpression); return; } } - + if (checkType->IsVar()) { // Mixin or unconstrained generic @@ -4052,7 +4150,6 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) bool mayBeSentinel = false; - if (checkType->IsPointer()) { auto innerType = checkType->GetUnderlyingType(); @@ -4069,8 +4166,8 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) } else { - isNotNull = mBfIRBuilder->CreateIsNotNull(val.mValue); - } + isNotNull = mBfIRBuilder->CreateIsNotNull(val.mValue); + } mBfIRBuilder->CreateCondBr(isNotNull, bodyBB, endBB); mBfIRBuilder->AddBlock(bodyBB); @@ -4078,16 +4175,16 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) if (val.mType->IsObjectOrInterface()) { - EmitObjectAccessCheck(val); - } - + EmitObjectAccessCheck(val); + } + SizedArray llvmArgs; auto bitAddr = mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr)); llvmArgs.push_back(bitAddr); if (val.mType->IsObjectOrInterface()) { auto objectType = mContext->mBfObjectType; - BfTypeInstance* checkTypeInst = val.mType->ToTypeInstance(); + BfTypeInstance* checkTypeInst = val.mType->ToTypeInstance(); bool allowPrivate = checkTypeInst == mCurTypeInstance; bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst); @@ -4098,15 +4195,15 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) { if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate)) { - auto error = Fail(StrFormat("'%s.~this()' is inaccessible due to its protection level", TypeToString(checkTypeInst).c_str()), deleteStmt->mExpression); // CS0122 + auto error = Fail(StrFormat("'%s.~this()' is inaccessible due to its protection level", TypeToString(checkTypeInst).c_str()), deleteStmt->mExpression); // CS0122 } } checkTypeInst = checkTypeInst->mBaseType; allowPrivate = false; - } + } if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsComptimeModule)) - { + { auto preDelete = GetInternalMethod((deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete"); SizedArray llvmArgs; llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType))); @@ -4115,7 +4212,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) // call dtor BfExprEvaluator expressionEvaluator(this); - PopulateType(val.mType); + PopulateType(val.mType); PopulateType(objectType, BfPopulateType_DataAndMethods); if (objectType->mVirtualMethodTable.size() == 0) @@ -4135,7 +4232,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) if ((deleteStmt->mTargetTypeToken != NULL) && (!isAppendDelete)) { if (deleteStmt->mAllocExpr != NULL) - { + { if (customAllocator) { auto customAllocTypeInst = customAllocator.mType->ToTypeInstance(); @@ -4163,7 +4260,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) else { if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsComptimeModule)) - { + { SizedArray llvmArgs; llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType))); auto moduleMethodInstance = GetInternalMethod("Dbg_MarkObjectDeleted"); @@ -4183,7 +4280,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) } else { - auto func = GetBuiltInFunc(BfBuiltInFuncType_Free); + auto func = GetBuiltInFunc(BfBuiltInFuncType_Free); if (!func) { BF_ASSERT(mCompiler->mIsResolveOnly); @@ -4203,7 +4300,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); auto ptrValue = BfTypedValue(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(voidPtrType)), voidPtrType); BfTypedValueExpression typedValueExpr; - typedValueExpr.Init(ptrValue); + typedValueExpr.Init(ptrValue); BfExprEvaluator exprEvaluator(this); SizedArray argExprs; argExprs.push_back(&typedValueExpr); @@ -4213,7 +4310,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) exprEvaluator.mNoBind = true; exprEvaluator.MatchMethod(deleteStmt->mAllocExpr, NULL, customAllocator, false, false, "Free", argValues, BfMethodGenericArguments()); } - + mBfIRBuilder->CreateBr(endBB); mBfIRBuilder->AddBlock(endBB); @@ -4222,11 +4319,16 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) void BfModule::Visit(BfSwitchStatement* switchStmt) { + if (mModuleName == "BeefTest_TestProgram") + { + NOP; + } + BfScopeData outerScope; outerScope.mInnerIsConditional = false; outerScope.mCloseNode = switchStmt; if (switchStmt->mCloseBrace != NULL) - outerScope.mCloseNode = switchStmt->mCloseBrace; + outerScope.mCloseNode = switchStmt->mCloseBrace; mCurMethodState->AddScope(&outerScope); NewScopeState(); @@ -4236,11 +4338,11 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (switchStmt->mSwitchValue == NULL) { AssertErrorState(); - UpdateSrcPos(switchStmt->mSwitchToken); + UpdateSrcPos(switchStmt->mSwitchToken); } else { - UpdateExprSrcPos(switchStmt->mSwitchValue); + UpdateExprSrcPos(switchStmt->mSwitchValue); BfEvalExprFlags flags = BfEvalExprFlags_None; flags = BfEvalExprFlags_AllowSplat; @@ -4273,12 +4375,12 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (switchStmt->mLabelNode != NULL) newScope.mLabelNode = switchStmt->mLabelNode->mLabel; mCurMethodState->AddScope(&newScope); - NewScopeState(); - + NewScopeState(); + BfTypedValue switchValueAddr = switchValue; - + BfLocalVariable* localDef = new BfLocalVariable(); - localDef->mName = "_"; + localDef->mName = "_"; localDef->mResolvedType = switchValueAddr.mType; localDef->mIsReadOnly = true; localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; @@ -4347,7 +4449,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) else if ((switchValue.mType->IsComposite()) && (switchValue.IsAddr())) { auto refType = CreateRefType(switchValue.mType); - auto allocaVal = CreateAlloca(refType); + auto allocaVal = CreateAlloca(refType); mBfIRBuilder->CreateStore(switchValue.mValue, allocaVal); auto diType = mBfIRBuilder->DbgGetType(refType); @@ -4361,7 +4463,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (switchValueAddr.IsSplat()) { auto addr = CreateAlloca(switchValue.mType); - if (switchValue.IsSplat()) + if (switchValue.IsSplat()) AggregateSplatIntoAddr(switchValue, addr); else mBfIRBuilder->CreateStore(switchValue.mValue, addr); @@ -4369,8 +4471,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) localDef->mValue = BfIRValue(); localDef->mIsSplat = false; } - } - } + } + } if (!localDef->mResolvedType->IsVar()) AddLocalVariableDef(localDef, addDebugInfo, true); @@ -4382,7 +4484,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) SizedArray blocks; SizedArray whenExprs; SizedArray whenFailBlocks; - BfIRBlock defaultBlock; + BfIRBlock defaultBlock; auto endBlock = mBfIRBuilder->CreateBlock("switch.end"); for (BfSwitchCase* switchCase : switchStmt->mSwitchCases) @@ -4394,9 +4496,9 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) defaultBlock = mBfIRBuilder->CreateBlock("default"); bool hasDefaultCase = switchStmt->mDefaultCase != NULL; - if (hasDefaultCase) - blocks.push_back(defaultBlock); - + if (hasDefaultCase) + blocks.push_back(defaultBlock); + SizedArray deferredLocalAssignDataVec; deferredLocalAssignDataVec.resize(blocks.size()); @@ -4412,8 +4514,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) auto switchBlock = mBfIRBuilder->GetInsertBlock(); BfIRBlock noSwitchBlock = mBfIRBuilder->CreateBlock("noSwitch", true); - BfPrimitiveType* intCoercibleType = GetIntCoercibleType(switchValue.mType); - + BfPrimitiveType* intCoercibleType = GetIntCoercibleType(switchValue.mType); + bool isConstSwitch = false; if ((switchValue.mValue.IsConst()) || (switchValue.mType->IsValuelessType())) { @@ -4436,7 +4538,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) switchStatement = mBfIRBuilder->CreateSwitch(enumTagVal.mValue, noSwitchBlock, numExpressions); } else if ((!isConstSwitch) && (!switchValue.mType->IsVar())) - switchStatement = mBfIRBuilder->CreateSwitch(switchValue.mValue, noSwitchBlock, numExpressions); + switchStatement = mBfIRBuilder->CreateSwitch(switchValue.mValue, noSwitchBlock, numExpressions); } auto valueScopeStartInner = ValueScopeStart(); @@ -4456,7 +4558,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) { auto fieldDef = fieldInstance.GetFieldDef(); if (fieldDef->IsEnumCaseEntry()) - { + { int enumIdx = -fieldInstance.mDataIdx - 1; if (enumIdx == id) { @@ -4482,7 +4584,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) }; bool hadConstMatch = false; - + auto startingLocalVarId = mCurMethodState->GetRootMethodState()->mCurLocalVarId; bool prevHadFallthrough = false; @@ -4503,7 +4605,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) { - // This does the enum autocomplete popup + // This does the enum autocomplete popup BfAstNode* checkNode = NULL; int caseExprIdx = (int)switchCase->mCaseExpressions.size(); if (caseExprIdx == 0) @@ -4517,7 +4619,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) bool mayHaveMatch = false; BfWhenExpression* whenExpr = NULL; - + for (BfExpression* caseExpr : switchCase->mCaseExpressions) { if (auto checkWhenExpr = BfNodeDynCast(caseExpr)) @@ -4538,13 +4640,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) continue; if ((!openedScope) && (wantsOpenedScope)) - { + { openedScope = true; caseScopeData.mOuterIsConditional = true; + caseScopeData.mIsSharedTempBlock = true; mCurMethodState->AddScope(&caseScopeData); NewScopeState(); - UpdateSrcPos(caseExpr); + UpdateSrcPos(caseExpr); SetIllegalSrcPos(); } @@ -4558,7 +4661,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) { auto dscrType = switchValue.mType->ToTypeInstance()->GetDiscriminatorType(); if (!enumTagVal) - { + { enumTagVal = ExtractValue(switchValue, NULL, 2); enumTagVal = LoadValue(enumTagVal); } @@ -4566,17 +4669,17 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq.%d", blockIdx), false); int tagId = -1; BfIRBlock matchBlock; - BfTypedValue eqTypedResult; + BfTypedValue eqTypedResult; if (auto bindExpr = BfNodeDynCast(caseExpr)) { - eqTypedResult = HandleCaseBind(switchValueAddr, enumTagVal, bindExpr, &caseBlock, ¬EqBB, &matchBlock, &tagId); + eqTypedResult = HandleCaseBind(switchValueAddr, enumTagVal, bindExpr, &caseBlock, ¬EqBB, &matchBlock, &tagId); } else { eqTypedResult = TryCaseEnumMatch(switchValueAddr, enumTagVal, caseExpr, &caseBlock, ¬EqBB, &matchBlock, tagId, hadConditional, false, prevHadFallthrough); if (hadConditional) hadCondCase = true; - } + } if (tagId != -1) { @@ -4584,12 +4687,12 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) caseValue = BfTypedValue(GetConstValue(tagId, GetPrimitiveType(dscrType->mTypeDef->mTypeCode)), dscrType); } else - hadCondCase = true; + hadCondCase = true; if (eqTypedResult) { handled = true; - eqResult = eqTypedResult.mValue; + eqResult = eqTypedResult.mValue; } } else if (auto tupleExpr = BfNodeDynCast(caseExpr)) @@ -4618,14 +4721,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) BfTypedValue caseIntVal = caseValue; if ((isIntegralSwitch) || (isPayloadEnum)) { - if ((intCoercibleType != NULL) && - (caseValue.mType == switchValue.mType) && + if ((intCoercibleType != NULL) && + (caseValue.mType == switchValue.mType) && (caseValue.mValue.IsConst())) { caseIntVal = GetIntCoercible(caseValue); constantInt = mBfIRBuilder->GetConstant(caseIntVal.mValue); } - else + else { // For a non-const case, allow for conversion operators, otherwise cast now if ((isIntegralSwitch) && (caseValue.mValue.IsConst())) @@ -4659,7 +4762,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) { _CaseState* caseState = NULL; handledCases.TryAdd(constantInt->mInt64, NULL, &caseState); - + if (caseState->mUncondBlock) { _ShowCaseError(constantInt->mInt64, caseExpr); @@ -4676,7 +4779,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) else if (!handled) { hadCondCase = true; - + if (!eqResult) { BfExprEvaluator exprEvaluator(this); @@ -4685,14 +4788,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if ((caseValue.mType->IsPayloadEnum()) && (caseValue.mValue.IsConst()) && (switchValue.mType == caseValue.mType)) { if (!enumTagVal) - { + { enumTagVal = ExtractValue(switchValue, NULL, 2); enumTagVal = LoadValue(enumTagVal); } eqResult = mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseValue.mValue); } else - { + { exprEvaluator.PerformBinaryOperation(switchStmt->mSwitchValue, caseExpr, BfBinaryOp_Equality, refNode, (BfBinOpFlags)(BfBinOpFlag_ForceLeftType), switchValue, caseValue); if (switchStmt->mSwitchValue != NULL) @@ -4715,17 +4818,17 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (constant->mTypeCode == BfTypeCode_Boolean) { isConstResult = true; - constResult = constant->mBool; + constResult = constant->mBool; } } if (isConstResult) - { + { if (constResult) { mBfIRBuilder->CreateBr(caseBlock); mayHaveMatch = true; - + if (whenExpr == NULL) { hadConstMatch = true; @@ -4733,7 +4836,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) else { notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq.%d", blockIdx)); - + mBfIRBuilder->AddBlock(notEqBB); mBfIRBuilder->SetInsertPoint(notEqBB); } @@ -4749,7 +4852,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mBfIRBuilder->AddBlock(notEqBB); mBfIRBuilder->SetInsertPoint(notEqBB); } - } + } if (notEqBB) lastNotEqBlock = notEqBB; @@ -4765,7 +4868,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) auto notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq_when.%d", blockIdx)); - mBfIRBuilder->CreateBr(caseBlock); + mBfIRBuilder->CreateBr(caseBlock); mBfIRBuilder->AddBlock(notEqBB); mBfIRBuilder->SetInsertPoint(notEqBB); @@ -4776,14 +4879,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mBfIRBuilder->SetSwitchDefaultDest(switchStatement, lastDefaultBlock); auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); - + bool isConstIgnore = !mayHaveMatch && !prevHadFallthrough; SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true, isConstIgnore); SetAndRestoreValue prevInConstIgnore(mCurMethodState->mCurScope->mInConstIgnore, true, isConstIgnore); - + mBfIRBuilder->AddBlock(caseBlock); mBfIRBuilder->SetInsertPoint(caseBlock); - + if (whenExpr != NULL) { UpdateSrcPos(whenExpr); @@ -4795,7 +4898,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) { AssertErrorState(); whenValue = GetDefaultTypedValue(boolType); - } + } bool constResult = false; if (mBfIRBuilder->TryGetBool(whenValue.mValue, constResult)) @@ -4822,13 +4925,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) bool hadReturn = false; if ((switchCase->mCodeBlock != NULL) && (!switchCase->mCodeBlock->mChildArr.IsEmpty())) { - UpdateSrcPos(switchCase->mCodeBlock); + UpdateSrcPos(switchCase->mCodeBlock); + + VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, fallthroughBlock, true, &hadReturn, switchStmt->mLabelNode, openedScope /*, BfEmbeddedStatementFlags_RescopeDLA*/); - VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, fallthroughBlock, true, &hadReturn, switchStmt->mLabelNode, openedScope); openedScope = false; deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn; caseCount++; - if ((!hadReturn) && + if ((!hadReturn) && ((!mCurMethodState->mDeferredLocalAssignData->mHadFallthrough) || (mCurMethodState->mDeferredLocalAssignData->mHadBreak))) allHadReturns = false; @@ -4839,8 +4943,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) else { if (switchStmt->mCloseBrace != NULL) - { - UpdateSrcPos(switchStmt->mCloseBrace); + { + UpdateSrcPos(switchStmt->mCloseBrace); } EmitEnsureInstructionAt(); } @@ -4861,7 +4965,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) prevIgnoreWrites.Restore(); mBfIRBuilder->SetInsertPoint(prevInsertBlock); - + prevHadFallthrough = mCurMethodState->mDeferredLocalAssignData->mHadFallthrough; blockIdx++; @@ -4870,7 +4974,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) // Check for comprehensiveness bool isComprehensive = true; if ((switchValue) && (switchStmt->mDefaultCase == NULL)) - { + { if (switchValue.mType->IsEnum()) { if (hadConstMatch) @@ -4936,9 +5040,9 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mBfIRBuilder->SetInsertPoint(switchBlock); if (!hadConstIntVals) - { + { if (switchStatement) - mBfIRBuilder->EraseInstFromParent(switchStatement); + mBfIRBuilder->EraseInstFromParent(switchStatement); mBfIRBuilder->CreateBr(noSwitchBlock); } @@ -4954,20 +5058,28 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (switchCase->mCodeBlock != NULL) { isComprehensive = true; - UpdateSrcPos(switchCase->mCodeBlock); - + UpdateSrcPos(switchCase->mCodeBlock); + deferredLocalAssignDataVec[blockIdx].mScopeData = mCurMethodState->mCurScope; deferredLocalAssignDataVec[blockIdx].ExtendFrom(mCurMethodState->mDeferredLocalAssignData); SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignDataVec[blockIdx]); mCurMethodState->mDeferredLocalAssignData->mVarIdBarrier = startingLocalVarId; + BfScopeData caseScopeData; + caseScopeData.mOuterIsConditional = true; + caseScopeData.mIsSharedTempBlock = true; + mCurMethodState->AddScope(&caseScopeData); + NewScopeState(); + bool hadReturn = false; - VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, BfIRBlock(), true, &hadReturn, switchStmt->mLabelNode); + VisitCodeBlock(switchCase->mCodeBlock, BfIRBlock(), endBlock, BfIRBlock(), true, &hadReturn, switchStmt->mLabelNode); deferredLocalAssignDataVec[blockIdx].mHadReturn = hadReturn; caseCount++; if (!hadReturn) allHadReturns = false; - } + + RestoreScopeState(); + } } else { @@ -4980,14 +5092,14 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) if (IsTargetingBeefBackend()) mBfIRBuilder->CreateBr(endBlock); } - else + else mBfIRBuilder->CreateBr(endBlock); } if (isComprehensive) { // Merge and apply deferred local assign data - // We only do this if there's a default case, otherwise we assume we may have missed a case + // We only do this if there's a default case, otherwise we assume we may have missed a case // that by definition had no local assigns BfDeferredLocalAssignData* mergedDeferredLocalAssignData = NULL; for (blockIdx = 0; blockIdx < (int)blocks.size(); blockIdx++) @@ -5013,7 +5125,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mCurMethodState->mLeftBlockUncond = true; if ((!hasDefaultCase) && (!isComprehensive)) - mBfIRBuilder->DeleteBlock(endBlock); + mBfIRBuilder->DeleteBlock(endBlock); else { if (switchStmt->mCloseBrace != NULL) @@ -5022,7 +5134,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mBfIRBuilder->SetInsertPoint(endBlock); mBfIRBuilder->CreateUnreachable(); } - } + } else { if (switchStmt->mCloseBrace != NULL) @@ -5031,29 +5143,29 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) mBfIRBuilder->AddBlock(endBlock); mBfIRBuilder->SetInsertPoint(endBlock); } - + BfIRValue lifetimeExtendVal; if (tryExtendValue) { if (localDef->mAddr) lifetimeExtendVal = localDef->mAddr; else - lifetimeExtendVal = localDef->mValue; + lifetimeExtendVal = localDef->mValue; } - + RestoreScopeState(); // newScope RestoreScopeState(); // outerScope if (lifetimeExtendVal) mBfIRBuilder->CreateLifetimeExtend(lifetimeExtendVal); - + ValueScopeEnd(valueScopeStartOuter); } static int gRetIdx = 0; void BfModule::Visit(BfReturnStatement* returnStmt) -{ +{ if ((mCurMethodInstance == NULL) || (mCurMethodState->mDisableReturns)) { Fail("Unexpected return", returnStmt); @@ -5064,7 +5176,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt) } return; } - + UpdateSrcPos(returnStmt); EmitEnsureInstructionAt(); @@ -5096,7 +5208,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt) { Fail("Initialization blocks cannot contain 'return' statements", returnStmt); } - checkScope = checkScope->mPrevScope; + checkScope = checkScope->mPrevScope; } auto checkLocalAssignData = mCurMethodState->mDeferredLocalAssignData; @@ -5111,17 +5223,17 @@ void BfModule::Visit(BfReturnStatement* returnStmt) { if (returnStmt->mExpression != NULL) { - BfExprEvaluator exprEvaluator(this); + BfExprEvaluator exprEvaluator(this); CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, GetPrimitiveType(BfTypeCode_Var), BfEvalExprFlags_None); } MarkScopeLeft(&mCurMethodState->mHeadScope); return; - } + } if (returnStmt->mExpression == NULL) { MarkScopeLeft(&mCurMethodState->mHeadScope); - + if ((retType != NULL) && (retType->IsVoid())) { EmitReturn(BfTypedValue()); @@ -5129,11 +5241,11 @@ void BfModule::Visit(BfReturnStatement* returnStmt) } Fail("Expected return value", returnStmt); - if (retType != NULL) + if (retType != NULL) EmitReturn(GetDefaultTypedValue(retType)); else EmitReturn(BfTypedValue()); - return; + return; } BfType* expectingReturnType = retType; @@ -5141,15 +5253,15 @@ void BfModule::Visit(BfReturnStatement* returnStmt) BfExprEvaluator exprEvaluator(this); bool alreadyWritten = false; if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) - exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal; + exprEvaluator.mReceivingValue = &mCurMethodState->mRetVal; if (mCurMethodInstance->mMethodDef->mIsReadOnly) exprEvaluator.mAllowReadOnlyReference = true; if (inferReturnType) expectingReturnType = NULL; - auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType); - + auto retValue = CreateValueFromExpression(exprEvaluator, returnStmt->mExpression, expectingReturnType, BfEvalExprFlags_AllowRefExpr, &origType); + if ((retValue) && (inferReturnType)) { if (mCurMethodState->mClosureState->mReturnType == NULL) @@ -5179,7 +5291,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt) if ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1)) alreadyWritten = exprEvaluator.mReceivingValue == NULL; MarkScopeLeft(&mCurMethodState->mHeadScope); - + if (!retValue) { AssertErrorState(); @@ -5191,7 +5303,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt) { EmitReturn(BfTypedValue()); return; - } + } } if (retValue.mType->IsVar()) @@ -5199,7 +5311,7 @@ void BfModule::Visit(BfReturnStatement* returnStmt) EmitReturn(BfTypedValue()); } else if (retValue.mType->IsVoid()) - { + { if (retType->IsVoid()) { Warn(0, "Returning void value", returnStmt->mReturnToken); @@ -5229,20 +5341,20 @@ void BfModule::Visit(BfReturnStatement* returnStmt) } void BfModule::Visit(BfYieldStatement* yieldStmt) -{ +{ Fail("Yield not supported", yieldStmt); } void BfModule::Visit(BfBreakStatement* breakStmt) { bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin()); - + UpdateSrcPos(breakStmt); mBfIRBuilder->CreateEnsureInstructionAt(); BfBreakData* breakData = mCurMethodState->mBreakData; if (breakStmt->mLabel != NULL) - { + { breakData = FindBreakData(breakStmt->mLabel); } else @@ -5252,7 +5364,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt) if (breakData->mIRBreakBlock) break; breakData = breakData->mPrevBreakData; - } + } } if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) @@ -5265,7 +5377,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt) } if ((breakData == NULL) || (!breakData->mIRBreakBlock)) - { + { if (inMixinDecl) { // Our mixin may just require that we're injected into a breakable scope @@ -5273,7 +5385,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt) else Fail("'break' not applicable in this block", breakStmt); return; - } + } if (mCurMethodState->mInDeferredBlock) { @@ -5283,7 +5395,7 @@ void BfModule::Visit(BfBreakStatement* breakStmt) if (checkScope == breakData->mScope) break; if (checkScope->mIsDeferredBlock) - { + { Fail("The break target crosses a deferred block boundary", breakStmt); return; } @@ -5291,39 +5403,53 @@ void BfModule::Visit(BfBreakStatement* breakStmt) } } + if (HasDeferredScopeCalls(breakData->mScope)) + { + EmitDeferredScopeCalls(true, breakData->mScope, breakData->mIRBreakBlock); + } + else + { + mBfIRBuilder->CreateBr(breakData->mIRBreakBlock); + } + mCurMethodState->mLeftBlockUncond = true; + + bool isCond = false; + int uncondScopeDepth = 0; + if (mCurMethodState->mCurScope != NULL) + uncondScopeDepth = mCurMethodState->mCurScope->mScopeDepth + 1; + + BfIRValue earliestValueScopeStart; + auto checkScope = mCurMethodState->mCurScope; + while (checkScope != NULL) + { + if (!isCond) + uncondScopeDepth = checkScope->mScopeDepth; + if ((checkScope->mOuterIsConditional) && (!checkScope->mIsSharedTempBlock)) + isCond = true; + + if (checkScope->mValueScopeStart) + earliestValueScopeStart = checkScope->mValueScopeStart; + if (checkScope == breakData->mScope) + break; + + checkScope = checkScope->mPrevScope; + } + auto checkLocalAssignData = mCurMethodState->mDeferredLocalAssignData; while (checkLocalAssignData != NULL) { if ((checkLocalAssignData->mScopeData != NULL) && (checkLocalAssignData->mScopeData->mScopeDepth >= breakData->mScope->mScopeDepth)) { + if (checkLocalAssignData->mScopeData->mScopeDepth >= uncondScopeDepth) + checkLocalAssignData->mLeftBlockUncond = true; checkLocalAssignData->mLeftBlock = true; checkLocalAssignData->mHadBreak = true; } checkLocalAssignData = checkLocalAssignData->mChainedAssignData; } - if (HasDeferredScopeCalls(breakData->mScope)) - { - EmitDeferredScopeCalls(true, breakData->mScope, breakData->mIRBreakBlock); - } - else - { - mBfIRBuilder->CreateBr(breakData->mIRBreakBlock); - } - mCurMethodState->mLeftBlockUncond = true; - - BfIRValue earliestValueScopeStart; - auto checkScope = mCurMethodState->mCurScope; - while (checkScope != NULL) - { - if (checkScope->mValueScopeStart) - earliestValueScopeStart = checkScope->mValueScopeStart; - if (checkScope == breakData->mScope) - break; - checkScope = checkScope->mPrevScope; - } MarkScopeLeft(breakData->mScope); - ValueScopeEnd(earliestValueScopeStart); + ValueScopeEnd(earliestValueScopeStart); auto checkBreakData = mCurMethodState->mBreakData; while (true) @@ -5332,13 +5458,13 @@ void BfModule::Visit(BfBreakStatement* breakStmt) if (checkBreakData == breakData) break; checkBreakData = checkBreakData->mPrevBreakData; - } + } } void BfModule::Visit(BfContinueStatement* continueStmt) { bool inMixinDecl = (mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin()); - + UpdateSrcPos(continueStmt); mBfIRBuilder->CreateEnsureInstructionAt(); @@ -5361,7 +5487,7 @@ void BfModule::Visit(BfContinueStatement* continueStmt) break; breakData = breakData->mPrevBreakData; } - } + } if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) { @@ -5416,7 +5542,7 @@ void BfModule::Visit(BfContinueStatement* continueStmt) } if ((nextScope != NULL) && (HasDeferredScopeCalls(nextScope))) - { + { EmitDeferredScopeCalls(true, nextScope, breakData->mIRContinueBlock); } else @@ -5470,12 +5596,12 @@ void BfModule::Visit(BfFallthroughStatement* fallthroughStmt) } void BfModule::Visit(BfUsingStatement* usingStmt) -{ +{ UpdateSrcPos(usingStmt); mCurMethodState->mInHeadScope = false; BfScopeData newScope; - mCurMethodState->AddScope(&newScope); + mCurMethodState->AddScope(&newScope); NewScopeState(); if (usingStmt->mVariableDeclaration != NULL) UpdateSrcPos(usingStmt->mVariableDeclaration); @@ -5502,21 +5628,21 @@ void BfModule::Visit(BfUsingStatement* usingStmt) AssertErrorState(); failed = true; } - else + else { - embeddedValue = exprEvaluator.LoadLocal(localVar); + embeddedValue = exprEvaluator.LoadLocal(localVar); } //exprEvaluator.CheckModifyResult(embeddedValue, usingStmt->mVariableDeclaration->mNameNode,); } - else - { + else + { embeddedValue = CreateValueFromExpression(usingStmt->mVariableDeclaration->mInitializer); if (!embeddedValue) failed = true; } if (!failed) - { + { auto iDisposableType = ResolveTypeDef(mCompiler->mIDisposableTypeDef)->ToTypeInstance(); auto dispMethod = GetMethodByName(iDisposableType, "Dispose"); @@ -5537,7 +5663,7 @@ void BfModule::Visit(BfUsingStatement* usingStmt) mayBeNull = false; } - exprEvaluator.mFunctionBindResult = &functionBindResult; + exprEvaluator.mFunctionBindResult = &functionBindResult; SizedArray resolvedArgs; BfMethodMatcher methodMatcher(usingStmt->mVariableDeclaration, this, dispMethod.mMethodInstance, resolvedArgs, BfMethodGenericArguments()); methodMatcher.CheckType(iDisposableType, embeddedValue, false); @@ -5564,40 +5690,40 @@ void BfModule::Visit(BfUsingStatement* usingStmt) } void BfModule::Visit(BfDoStatement* doStmt) -{ +{ UpdateSrcPos(doStmt); - auto bodyBB = mBfIRBuilder->CreateBlock("do.body", true); + auto bodyBB = mBfIRBuilder->CreateBlock("do.body", true); auto endBB = mBfIRBuilder->CreateBlock("do.end"); - BfScopeData scopeData; + BfScopeData scopeData; if (doStmt->mLabelNode != NULL) scopeData.mLabelNode = doStmt->mLabelNode->mLabel; mCurMethodState->AddScope(&scopeData); NewScopeState(); - BfBreakData breakData; + BfBreakData breakData; breakData.mIRBreakBlock = endBB; breakData.mScope = &scopeData; - breakData.mPrevBreakData = mCurMethodState->mBreakData; + breakData.mPrevBreakData = mCurMethodState->mBreakData; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, false); deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; - SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); + SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); // We may have a call in the loop body mCurMethodState->mMayNeedThisAccessCheck = true; mBfIRBuilder->CreateBr(bodyBB); - mBfIRBuilder->SetInsertPoint(bodyBB); - VisitEmbeddedStatement(doStmt->mEmbeddedStatement); - + mBfIRBuilder->SetInsertPoint(bodyBB); + VisitEmbeddedStatement(doStmt->mEmbeddedStatement); + prevDLA.Restore(); mCurMethodState->ApplyDeferredLocalAssignData(deferredLocalAssignData); - RestoreScopeState(); + RestoreScopeState(); if (!mCurMethodState->mLeftBlockUncond) mBfIRBuilder->CreateBr(endBB); @@ -5605,7 +5731,7 @@ void BfModule::Visit(BfDoStatement* doStmt) mCurMethodState->mLeftBlockUncond = false; mBfIRBuilder->AddBlock(endBB); - mBfIRBuilder->SetInsertPoint(endBB); + mBfIRBuilder->SetInsertPoint(endBB); } void BfModule::Visit(BfRepeatStatement* repeatStmt) @@ -5625,7 +5751,7 @@ void BfModule::Visit(BfRepeatStatement* repeatStmt) auto endBB = mBfIRBuilder->CreateBlock("repeat.end"); BfScopeData scopeData; - // We set mIsLoop later + // We set mIsLoop later if (repeatStmt->mLabelNode != NULL) scopeData.mLabelNode = repeatStmt->mLabelNode->mLabel; mCurMethodState->AddScope(&scopeData); @@ -5635,32 +5761,39 @@ void BfModule::Visit(BfRepeatStatement* repeatStmt) breakData.mIRContinueBlock = condBB; breakData.mIRBreakBlock = endBB; breakData.mScope = &scopeData; - breakData.mPrevBreakData = mCurMethodState->mBreakData; + breakData.mPrevBreakData = mCurMethodState->mBreakData; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); // We may have a call in the loop body mCurMethodState->mMayNeedThisAccessCheck = true; mBfIRBuilder->CreateBr(bodyBB); - mBfIRBuilder->SetInsertPoint(bodyBB); + mBfIRBuilder->SetInsertPoint(bodyBB); scopeData.mIsLoop = true; - VisitEmbeddedStatement(repeatStmt->mEmbeddedStatement); + + BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); + deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, false); + deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; + SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); + + VisitEmbeddedStatement(repeatStmt->mEmbeddedStatement); + if (!mCurMethodState->mLeftBlockUncond) mBfIRBuilder->CreateBr(condBB); mCurMethodState->SetHadReturn(false); mCurMethodState->mLeftBlockUncond = false; mCurMethodState->mLeftBlockCond = false; - mBfIRBuilder->AddBlock(condBB); + mBfIRBuilder->AddBlock(condBB); mBfIRBuilder->SetInsertPoint(condBB); bool isInfiniteLoop = false; - if (repeatStmt->mCondition != NULL) - { + if (repeatStmt->mCondition != NULL) + { UpdateSrcPos(repeatStmt->mCondition); auto checkVal = CreateValueFromExpression(repeatStmt->mCondition, GetPrimitiveType(BfTypeCode_Boolean)); - if (checkVal) + if (checkVal) { if ((!breakData.mHadBreak) && (checkVal.mValue.IsConst())) { @@ -5673,11 +5806,13 @@ void BfModule::Visit(BfRepeatStatement* repeatStmt) mBfIRBuilder->AddBlock(endBB); mBfIRBuilder->SetInsertPoint(endBB); } - } RestoreScopeState(); + prevDLA.Restore(); + mCurMethodState->ApplyDeferredLocalAssignData(deferredLocalAssignData); + if (isInfiniteLoop) EmitDefaultReturn(); } @@ -5689,8 +5824,8 @@ void BfModule::Visit(BfWhileStatement* whileStmt) bool prevHadReturn = mCurMethodState->mHadReturn; auto condBB = mBfIRBuilder->CreateBlock("while.cond"); - auto bodyBB = mBfIRBuilder->CreateBlock("while.body"); - auto endBB = mBfIRBuilder->CreateBlock("while.end"); + auto bodyBB = mBfIRBuilder->CreateBlock("while.body"); + auto endBB = mBfIRBuilder->CreateBlock("while.end"); mCurMethodState->mInHeadScope = false; BfScopeData scopeData; @@ -5699,14 +5834,14 @@ void BfModule::Visit(BfWhileStatement* whileStmt) if (whileStmt->mLabelNode != NULL) scopeData.mLabelNode = whileStmt->mLabelNode->mLabel; scopeData.mValueScopeStart = ValueScopeStart(); - mCurMethodState->AddScope(&scopeData); + mCurMethodState->AddScope(&scopeData); NewScopeState(); BfBreakData breakData; breakData.mIRContinueBlock = condBB; breakData.mIRBreakBlock = endBB; breakData.mScope = &scopeData; - breakData.mPrevBreakData = mCurMethodState->mBreakData; + breakData.mPrevBreakData = mCurMethodState->mBreakData; breakData.mInnerValueScopeStart = scopeData.mValueScopeStart; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); @@ -5750,7 +5885,7 @@ void BfModule::Visit(BfWhileStatement* whileStmt) mBfIRBuilder->CreateBr(bodyBB); else if (isFalseLoop) mBfIRBuilder->CreateBr(endBB); - else + else mBfIRBuilder->CreateCondBr(checkVal.mValue, bodyBB, endBB); // Apply deferred local assign to mEmbeddedStatement and itrStmt @@ -5761,7 +5896,7 @@ void BfModule::Visit(BfWhileStatement* whileStmt) deferredLocalAssignData.mIsUnconditional = isInfiniteLoop; mBfIRBuilder->AddBlock(bodyBB); - mBfIRBuilder->SetInsertPoint(bodyBB); + mBfIRBuilder->SetInsertPoint(bodyBB); if (whileStmt->mEmbeddedStatement != NULL) { if (isFalseLoop) @@ -5771,7 +5906,7 @@ void BfModule::Visit(BfWhileStatement* whileStmt) VisitEmbeddedStatement(whileStmt->mEmbeddedStatement); } else - VisitEmbeddedStatement(whileStmt->mEmbeddedStatement); + VisitEmbeddedStatement(whileStmt->mEmbeddedStatement); } else { @@ -5781,24 +5916,24 @@ void BfModule::Visit(BfWhileStatement* whileStmt) { isInfiniteLoop = false; } - + if ((!mCurMethodState->mLeftBlockUncond) && (!isFalseLoop)) { mBfIRBuilder->CreateBr(condBB); - } + } if (!isInfiniteLoop) mCurMethodState->mHadReturn = prevHadReturn; - mCurMethodState->mLeftBlockUncond = false; - mCurMethodState->mLeftBlockCond = false; + mCurMethodState->mLeftBlockUncond = false; + mCurMethodState->mLeftBlockCond = false; mBfIRBuilder->AddBlock(endBB); mBfIRBuilder->SetInsertPoint(endBB); if (isFalseLoop) { - mBfIRBuilder->EraseFromParent(bodyBB); + mBfIRBuilder->EraseFromParent(bodyBB); } RestoreScopeState(); @@ -5843,22 +5978,22 @@ void BfModule::Visit(BfForStatement* forStmt) auto incBB = mBfIRBuilder->CreateBlock("for.inc"); auto endBB = mBfIRBuilder->CreateBlock("for.end"); - BfBreakData breakData; + BfBreakData breakData; breakData.mIRContinueBlock = incBB; breakData.mIRBreakBlock = endBB; breakData.mScope = &scopeData; - breakData.mPrevBreakData = mCurMethodState->mBreakData; - SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); + breakData.mPrevBreakData = mCurMethodState->mBreakData; + SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); mBfIRBuilder->CreateBr(condBB); - bool isInfiniteLoop = false; + bool isInfiniteLoop = false; mBfIRBuilder->SetInsertPoint(condBB); if (forStmt->mCondition != NULL) { auto conditionValue = CreateValueFromExpression(forStmt->mCondition, boolType); if (!conditionValue) - conditionValue = GetDefaultTypedValue(boolType); + conditionValue = GetDefaultTypedValue(boolType); auto constant = mBfIRBuilder->GetConstant(conditionValue.mValue); if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_Boolean)) isInfiniteLoop = constant->mBool; @@ -5880,8 +6015,8 @@ void BfModule::Visit(BfForStatement* forStmt) mBfIRBuilder->AddBlock(bodyBB); mBfIRBuilder->SetInsertPoint(bodyBB); if (forStmt->mEmbeddedStatement != NULL) - { - VisitEmbeddedStatement(forStmt->mEmbeddedStatement); + { + VisitEmbeddedStatement(forStmt->mEmbeddedStatement); } if (!mCurMethodState->mLeftBlockUncond) mBfIRBuilder->CreateBr(incBB); @@ -5898,7 +6033,7 @@ void BfModule::Visit(BfForStatement* forStmt) mBfIRBuilder->CreateBr(condBB); mBfIRBuilder->AddBlock(endBB); - mBfIRBuilder->SetInsertPoint(endBB); + mBfIRBuilder->SetInsertPoint(endBB); // The 'return' may have been inside the block, which may not have been entered if preconditions were not met mCurMethodState->SetHadReturn(false); @@ -5923,19 +6058,19 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) mBfIRBuilder->SetInsertPoint(condBB); BfScopeData scopeData; - // We set mIsLoop later + // We set mIsLoop later if (forEachStmt->mLabelNode != NULL) scopeData.mLabelNode = forEachStmt->mLabelNode->mLabel; - mCurMethodState->AddScope(&scopeData); + mCurMethodState->AddScope(&scopeData); NewScopeState(); - + auto autoComplete = mCompiler->GetAutoComplete(); auto isLet = BfNodeDynCast(forEachStmt->mVariableTypeRef) != 0; auto isVar = BfNodeDynCast(forEachStmt->mVariableTypeRef) != 0; - - BfTypedValue target; - BfType* varType = NULL; + + BfTypedValue target; + BfType* varType = NULL; bool didInference = false; if (isLet || isVar) { @@ -5948,19 +6083,18 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) } if (autoComplete != NULL) - autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType); + autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType); didInference = true; } else { - varType = ResolveTypeRef(forEachStmt->mVariableTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); + varType = ResolveTypeRef(forEachStmt->mVariableTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); if (forEachStmt->mCollectionExpression != NULL) target = CreateValueFromExpression(forEachStmt->mCollectionExpression, varType); } if (varType == NULL) varType = GetPrimitiveType(BfTypeCode_IntPtr); - BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); deferredLocalAssignData.mIsIfCondition = true; deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, true); @@ -5969,7 +6103,7 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) deferredLocalAssignData.mIsIfCondition = false; - // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and + // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and // conditionally executed code (in the case of "(GetVal(out a) && GetVal(out b))" for example mCurMethodState->mDeferredLocalAssignData->BreakExtendChain(); @@ -5983,19 +6117,19 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) if (didInference) target = GetDefaultTypedValue(varType); } - PopulateType(varType, BfPopulateType_Data); + PopulateType(varType, BfPopulateType_Data); auto condEndBB = mBfIRBuilder->GetInsertBlock(); mBfIRBuilder->SetInsertPoint(startBB); - - BfLocalVariable* localDef = new BfLocalVariable(); + + BfLocalVariable* localDef = new BfLocalVariable(); localDef->mNameNode = BfNodeDynCast(forEachStmt->mVariableName); localDef->mName = localDef->mNameNode->ToString(); localDef->mResolvedType = varType; BfIRValue varInst; if (!varType->IsValuelessType()) { - varInst = CreateAlloca(varType); + varInst = CreateAlloca(varType); } localDef->mAddr = varInst; localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; @@ -6009,7 +6143,7 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) localDef->Init(); UpdateExprSrcPos(forEachStmt->mVariableName); AddLocalVariableDef(localDef, true); - + auto bodyBB = mBfIRBuilder->CreateBlock("forless.body"); auto incBB = mBfIRBuilder->CreateBlock("forless.inc"); auto endBB = mBfIRBuilder->CreateBlock("forless.end"); @@ -6018,7 +6152,7 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) breakData.mIRContinueBlock = incBB; breakData.mIRBreakBlock = endBB; breakData.mScope = &scopeData; - breakData.mPrevBreakData = mCurMethodState->mBreakData; + breakData.mPrevBreakData = mCurMethodState->mBreakData; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); @@ -6031,7 +6165,6 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) // We may have a call in the loop body mCurMethodState->mMayNeedThisAccessCheck = true; - // Cond auto valueScopeStart = ValueScopeStart(); auto localVal = mBfIRBuilder->CreateAlignedLoad(localDef->mAddr, localDef->mResolvedType->mAlign); @@ -6044,7 +6177,7 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) conditionValue = mBfIRBuilder->CreateCmpLTE(localVal, target.mValue, varType->IsSigned()); else conditionValue = mBfIRBuilder->CreateCmpLT(localVal, target.mValue, varType->IsSigned()); - mBfIRBuilder->CreateCondBr(conditionValue, bodyBB, endBB); + mBfIRBuilder->CreateCondBr(conditionValue, bodyBB, endBB); ValueScopeEnd(valueScopeStart); mBfIRBuilder->AddBlock(bodyBB); @@ -6053,8 +6186,8 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) // Body scopeData.mIsLoop = true; if (forEachStmt->mEmbeddedStatement != NULL) - { - VisitEmbeddedStatement(forEachStmt->mEmbeddedStatement); + { + VisitEmbeddedStatement(forEachStmt->mEmbeddedStatement); } // Inc @@ -6076,16 +6209,16 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) mBfIRBuilder->CreateAlignedStore(result, localDef->mAddr, localDef->mResolvedType->mAlign); ValueScopeEnd(valueScopeStart); - mBfIRBuilder->CreateBr(condBB); + mBfIRBuilder->CreateBr(condBB); mBfIRBuilder->AddBlock(endBB); - mBfIRBuilder->SetInsertPoint(endBB); + mBfIRBuilder->SetInsertPoint(endBB); // The 'return' may have been inside the block, which may not have been entered if preconditions were not met mCurMethodState->SetHadReturn(false); mCurMethodState->mLeftBlockUncond = false; mCurMethodState->mLeftBlockCond = false; - + bool definitelyExecuted = false; if (target.mValue.IsConst()) { @@ -6102,8 +6235,8 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) } void BfModule::Visit(BfForEachStatement* forEachStmt) -{ - if ((forEachStmt->mInToken != NULL) && +{ + if ((forEachStmt->mInToken != NULL) && ((forEachStmt->mInToken->GetToken() == BfToken_LChevron) || (forEachStmt->mInToken->GetToken() == BfToken_LessEquals))) { DoForLess(forEachStmt); @@ -6111,10 +6244,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } auto autoComplete = mCompiler->GetAutoComplete(); - UpdateSrcPos(forEachStmt); + UpdateSrcPos(forEachStmt); BfScopeData scopeData; - // We set mIsLoop after the non-looped initializations + // We set mIsLoop after the non-looped initializations scopeData.mValueScopeStart = ValueScopeStart(); mCurMethodState->AddScope(&scopeData); NewScopeState(); @@ -6142,7 +6275,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) bool isLet = (forEachStmt->mVariableTypeRef != NULL) && (forEachStmt->mVariableTypeRef->IsA()); BfType* varType = NULL; - bool inferVarType = false; + bool inferVarType = false; if ((forEachStmt->mVariableTypeRef == NULL) || (forEachStmt->mVariableTypeRef->IsA()) || (isLet)) { if (target.mType->IsSizedArray()) @@ -6166,7 +6299,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) autoComplete->CheckTypeRef(forEachStmt->mVariableTypeRef, false); varType = ResolveTypeRef(forEachStmt->mVariableTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); } - + if (varType == NULL) varType = GetPrimitiveType(BfTypeCode_Var); bool isArray = target.mType->IsArray(); @@ -6177,7 +6310,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) BfType* itrType; BfTypedValue itr; BfTypeInstance* itrInterface = NULL; - BfTypeInstance* refItrInterface = NULL; + BfTypeInstance* refItrInterface = NULL; if (isVarEnumerator) varType = GetPrimitiveType(BfTypeCode_Var); @@ -6203,14 +6336,14 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if (genericParamInst->mTypeConstraint->IsGenericTypeInstance()) { - auto genericConstraintType = (BfTypeInstance*)genericParamInst->mTypeConstraint; + auto genericConstraintType = (BfTypeInstance*)genericParamInst->mTypeConstraint; if (genericConstraintType->IsInstanceOf(mCompiler->mSizedArrayTypeDef)) { varType = genericConstraintType->mGenericTypeInfo->mTypeGenericArguments[0]; isVarEnumerator = true; - } - } - } + } + } + } } if (target.mType->IsConcreteInterfaceType()) @@ -6219,26 +6352,26 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if (isArray || isSizedArray) { itrType = GetPrimitiveType(BfTypeCode_IntPtr); - BfIRValue itrInst = CreateAlloca(itrType); + BfIRValue itrInst = CreateAlloca(itrType); itr = BfTypedValue(itrInst, itrType, true); } else if (isVarEnumerator) { - // Generic method or mixin decl - } + // Generic method or mixin decl + } else if ((!target.mType->IsTypeInstance()) && (genericParamInst == NULL)) - { + { Fail(StrFormat("Type '%s' cannot be used in enumeration", TypeToString(target.mType).c_str()), forEachStmt->mCollectionExpression); } else if (forEachStmt->mCollectionExpression != NULL) { - auto targetTypeInstance = target.mType->ToTypeInstance(); - + auto targetTypeInstance = target.mType->ToTypeInstance(); + itr = target; bool hadGetEnumeratorType = false; if (genericParamInst != NULL) - { + { for (auto ifaceConstraint : genericParamInst->mInterfaceConstraints) { if (ifaceConstraint->IsInstanceOf(mCompiler->mGenericIEnumerableTypeDef)) @@ -6248,7 +6381,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) targetTypeInstance = NULL; break; } - targetTypeInstance = ifaceConstraint->ToTypeInstance(); + targetTypeInstance = ifaceConstraint->ToTypeInstance(); } } } @@ -6256,6 +6389,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if (targetTypeInstance != NULL) { PopulateType(targetTypeInstance, BfPopulateType_DataAndMethods); + auto getEnumeratorMethod = GetMethodByName(targetTypeInstance, "GetEnumerator", 0, true); if (!getEnumeratorMethod) { @@ -6265,7 +6399,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) { hadGetEnumeratorType = true; Fail(StrFormat("Type '%s' does not contain a non-static 'GetEnumerator' method", TypeToString(targetTypeInstance).c_str()), forEachStmt->mCollectionExpression); - } + } else { if (getEnumeratorMethod.mMethodInstance->mMethodDef->mIsConcrete) @@ -6317,19 +6451,19 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if (varType->IsPointer()) varType = CreateRefType(varType->GetUnderlyingType()); } - } } }; auto enumeratorTypeInst = itr.mType->ToTypeInstance(); - - if (enumeratorTypeInst != NULL) + while (enumeratorTypeInst != NULL) { + PopulateType(enumeratorTypeInst, Beefy::BfPopulateType_Interfaces_All); + for (auto& interfaceRef : enumeratorTypeInst->mInterfaces) { BfTypeInstance* interface = interfaceRef.mInterfaceType; - _CheckInterface(interface); + _CheckInterface(interface); } if (enumeratorTypeInst->IsInstanceOf(isRefExpression ? mCompiler->mGenericIRefEnumeratorTypeDef : mCompiler->mGenericIEnumeratorTypeDef)) @@ -6345,7 +6479,13 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) varType = CreateRefType(varType); } } + break; } + + if (itrInterface != NULL) + break; + + enumeratorTypeInst = enumeratorTypeInst->mBaseType; } if ((genericItrInterface == NULL) && (genericParamInst != NULL)) @@ -6380,11 +6520,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) itr = MakeAddressable(itr); itr = RemoveReadOnly(itr); } - } + } } else - { - AssertErrorState(); + { + AssertErrorState(); } PopulateType(varType, BfPopulateType_Data); @@ -6409,28 +6549,27 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) struct _TupleBind { BfIdentifierNode* mNameNode; - String mName; + String mName; BfType* mType; BfLocalVariable* mVariable; }; Array<_TupleBind> tupleBinds; - if (forEachStmt->mVariableName != NULL) { if (auto tupleExpr = BfNodeDynCast(forEachStmt->mVariableName)) { CheckTupleVariableDeclaration(tupleExpr, varType); - + if (varType->IsTuple()) { auto tupleType = (BfTypeInstance*)varType; for (int idx = 0; idx < BF_MIN((int)tupleExpr->mValues.size(), (int)tupleType->mFieldInstances.size()); idx++) - { - auto nameNode = tupleExpr->mValues[idx]; - + { + auto nameNode = tupleExpr->mValues[idx]; + _TupleBind tupleBind; tupleBind.mNameNode = BfNodeDynCast(nameNode); if ((tupleBind.mNameNode == NULL) && (nameNode != NULL)) @@ -6440,7 +6579,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) tupleBind.mName = nameNode->ToString(); tupleBind.mType = tupleType->mFieldInstances[idx].mResolvedType; tupleBind.mVariable = NULL; - + tupleBinds.Add(tupleBind); if (idx == 0) variableName = tupleBind.mName; @@ -6454,10 +6593,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) variableName = nameNode->ToString(); } } - + if (variableName.IsEmpty()) variableName = "_"; - + BfModuleMethodInstance getNextMethodInst; BfType* nextEmbeddedType = NULL; @@ -6489,43 +6628,43 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) // Iterator local def if (itr) - { + { BfLocalVariable* localDef = new BfLocalVariable(); itrLocalDef = localDef; - localDef->mNameNode = nameNode; - localDef->mName = variableName; + localDef->mNameNode = nameNode; + localDef->mName = variableName; localDef->mResolvedType = itr.mType; localDef->mAddr = itr.mValue; localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional; - localDef->mReadFromId = 0; + localDef->mReadFromId = 0; localDef->Init(); UpdateSrcPos(forEachStmt); CheckVariableDef(localDef); - AddLocalVariableDef(localDef, true); + AddLocalVariableDef(localDef, true); } BfIRValue varInst; BfTypedValue varTypedVal; bool needsValCopy = true; - + // Local variable { if (!tupleBinds.IsEmpty()) - { + { BF_ASSERT(varType->IsTuple()); auto tupleType = (BfTypeInstance*)varType; - // Tuple binds + // Tuple binds needsValCopy = false; if (!nextResult) { varInst = CreateAlloca(varType); varTypedVal = BfTypedValue(varInst, varType, true); - } + } // Local - for (int idx = 0; idx < (int)tupleBinds.size(); idx++) - { + for (int idx = 0; idx < (int)tupleBinds.size(); idx++) + { auto& tupleBind = tupleBinds[idx]; BfLocalVariable* localDef = new BfLocalVariable(); localDef->mNameNode = tupleBind.mNameNode; @@ -6539,7 +6678,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if ((isLet) || (forEachStmt->mReadOnlyToken != NULL)) localDef->mIsReadOnly = true; localDef->Init(); - + auto fieldInstance = &tupleType->mFieldInstances[idx]; if (fieldInstance->mDataIdx >= 0) { @@ -6551,8 +6690,8 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) tuplePtr = mBfIRBuilder->CreateBitCast(varInst, mBfIRBuilder->MapType(tuplePtrType)); auto valAddr = mBfIRBuilder->CreateInBoundsGEP(tuplePtr, 0, fieldInstance->mDataIdx); mBfIRBuilder->CreateAlignedStore(valAddr, localDef->mAddr, localDef->mResolvedType->mAlign); - } - + } + UpdateSrcPos(forEachStmt); if ((itrLocalDef != NULL) && (idx == 0)) { @@ -6565,12 +6704,12 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } AddLocalVariableDef(localDef, true, false, BfIRValue(), BfIRInitType_NotNeeded_AliveOnDecl); - } + } } else { - // Normal case - if ((nextResult) && (varType->IsComposite())) + // Normal case + if ((nextResult) && (varType->IsComposite()) && (!isRefExpression)) { needsValCopy = false; varType = CreateRefType(varType); @@ -6610,11 +6749,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) varTypedVal = BfTypedValue(varInst, varType, true); } - } - + } + // Iterator if (itr) - { + { if ((!isArray) && (!isSizedArray)) { BfFunctionBindResult functionBindResult; @@ -6622,7 +6761,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) exprEvaluator.mFunctionBindResult = &functionBindResult; // Allow for "Dispose" not to exist - SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); BfResolvedArgs resolvedArgs; exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_NoAutoComplete); exprEvaluator.MatchMethod(forEachStmt->mCollectionExpression, NULL, itr, false, false, "Dispose", resolvedArgs, BfMethodGenericArguments()); @@ -6633,7 +6772,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) AddDeferredCall(moduleMethodInstance, functionBindResult.mIRArgs, mCurMethodState->mCurScope); } } - } + } BfScopeData innerScopeData; if (forEachStmt->mLabelNode != NULL) @@ -6646,8 +6785,8 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL)) autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType); - if (isArray || isSizedArray) - mBfIRBuilder->CreateAlignedStore(GetConstValue(0), itr.mValue, itr.mType->mAlign); + if (isArray || isSizedArray) + mBfIRBuilder->CreateAlignedStore(GetConstValue(0), itr.mValue, itr.mType->mAlign); auto valueScopeStartInner = ValueScopeStart(); @@ -6664,7 +6803,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) breakData.mIRBreakBlock = endBB; breakData.mScope = &innerScopeData; breakData.mInnerValueScopeStart = valueScopeStartInner; - breakData.mPrevBreakData = mCurMethodState->mBreakData; + breakData.mPrevBreakData = mCurMethodState->mBreakData; SetAndRestoreValue prevBreakData(mCurMethodState->mBreakData, &breakData); mBfIRBuilder->CreateBr(condBB); @@ -6676,16 +6815,16 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) { auto itrVal = mBfIRBuilder->CreateLoad(itr.mValue); auto arrayType = (BfSizedArrayType*)target.mType; - PopulateType(arrayType, BfPopulateType_DataAndMethods); + PopulateType(arrayType, BfPopulateType_DataAndMethods); BfIRValue lengthVal = GetConstValue(arrayType->mElementCount); - conditionValue = mBfIRBuilder->CreateCmpLT(itrVal, lengthVal, true); + conditionValue = mBfIRBuilder->CreateCmpLT(itrVal, lengthVal, true); mBfIRBuilder->CreateCondBr(conditionValue, bodyBB, endBB); ValueScopeEnd(valueScopeStartInner); } else if (isArray) // if (i < array.mLength) - { + { auto itrVal = mBfIRBuilder->CreateAlignedLoad(itr.mValue, itr.mType->mAlign); - auto arrayType = (BfArrayType*)target.mType; + auto arrayType = (BfArrayType*)target.mType; PopulateType(arrayType); auto arrayBaseValue = mBfIRBuilder->CreateBitCast(target.mValue, mBfIRBuilder->MapType(arrayType->mBaseType, BfIRPopulateType_Full)); int getLengthBitCount = arrayType->GetLengthBitCount(); @@ -6709,7 +6848,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } } lengthVal = mBfIRBuilder->CreateNumericCast(lengthVal, true, BfTypeCode_IntPtr); - conditionValue = mBfIRBuilder->CreateCmpLT(itrVal, lengthVal, true); + conditionValue = mBfIRBuilder->CreateCmpLT(itrVal, lengthVal, true); mBfIRBuilder->CreateCondBr(conditionValue, bodyBB, endBB); ValueScopeEnd(valueScopeStartInner); } @@ -6723,18 +6862,18 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) mBfIRBuilder->CreateBr(endBB); } else - { - BfExprEvaluator exprEvaluator(this); + { + BfExprEvaluator exprEvaluator(this); auto itrTypeInstance = itr.mType->ToTypeInstance(); - SizedArray resolvedArgs; + SizedArray resolvedArgs; BfMethodMatcher methodMatcher(forEachStmt->mCollectionExpression, this, getNextMethodInst.mMethodInstance, resolvedArgs, BfMethodGenericArguments()); if (isRefExpression) methodMatcher.CheckType(refItrInterface, itr, false); else methodMatcher.CheckType(itrInterface, itr, false); methodMatcher.TryDevirtualizeCall(itr); - exprEvaluator.mReceivingValue = &nextResult; - auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr); + exprEvaluator.mReceivingValue = &nextResult; + auto retVal = exprEvaluator.CreateCall(&methodMatcher, itr); if (exprEvaluator.mReceivingValue != NULL) { if (mIsComptimeModule) @@ -6753,11 +6892,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) conditionValue = mBfIRBuilder->CreateCmpEQ(i8Result.mValue, GetConstValue8(0)); } else - conditionValue = GetDefaultValue(GetPrimitiveType(BfTypeCode_Boolean)); + conditionValue = GetDefaultValue(GetPrimitiveType(BfTypeCode_Boolean)); mBfIRBuilder->CreateCondBr(conditionValue, bodyBB, endBB); ValueScopeEnd(valueScopeStartInner); } - } + } mBfIRBuilder->AddBlock(bodyBB); mBfIRBuilder->SetInsertPoint(bodyBB); @@ -6766,12 +6905,12 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) // Nothing to do... } else if (isSizedArray) // val = array[i] - { + { auto itrVal = mBfIRBuilder->CreateLoad(itr.mValue); auto arrayType = (BfSizedArrayType*)target.mType; BfType* ptrType = CreatePointerType(arrayType->mElementType); BfTypedValue arrayItem; - + if (arrayType->mElementType->IsValuelessType()) { arrayItem = GetDefaultTypedValue(arrayType->mElementType); @@ -6800,13 +6939,13 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) SizedArray indices; indices.push_back(&typedValueExpr); BfSizedArray sizedArgExprs(indices); - BfResolvedArgs argValues(&sizedArgExprs); + BfResolvedArgs argValues(&sizedArgExprs); exprEvaluator.ResolveArgValues(argValues); bool boundsCheck = mCompiler->mOptions.mRuntimeChecks; auto typeOptions = GetTypeOptions(); if (typeOptions != NULL) boundsCheck = typeOptions->Apply(boundsCheck, BfOptionFlags_RuntimeChecks); - + BfMethodMatcher methodMatcher(forEachStmt->mVariableName, this, "get__", argValues.mResolvedArgs, BfMethodGenericArguments()); methodMatcher.mMethodType = BfMethodType_PropertyGetter; methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false); @@ -6841,12 +6980,12 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } else if (mCompiler->IsAutocomplete()) { - // If we don't do this shortcut, we can end up creating temporary "boxed" objects + // If we don't do this shortcut, we can end up creating temporary "boxed" objects } else { if (needsValCopy) - { + { auto nextVal = BfTypedValue(mBfIRBuilder->CreateBitCast(nextResult.mValue, mBfIRBuilder->MapType(CreatePointerType(nextEmbeddedType))), nextEmbeddedType, true); if (isRefExpression) { @@ -6862,8 +7001,8 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } if (forEachStmt->mEmbeddedStatement != NULL) - { - VisitEmbeddedStatement(forEachStmt->mEmbeddedStatement); + { + VisitEmbeddedStatement(forEachStmt->mEmbeddedStatement); } if (!mCurMethodState->mLeftBlockUncond) @@ -6874,7 +7013,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) mBfIRBuilder->AddBlock(incBB); mBfIRBuilder->SetInsertPoint(incBB); - + if (isArray || isSizedArray) { auto val = mBfIRBuilder->CreateLoad(itr.mValue); @@ -6883,10 +7022,10 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) } else { - // Nothing to do + // Nothing to do } - - mBfIRBuilder->CreateBr(condBB); + + mBfIRBuilder->CreateBr(condBB); mBfIRBuilder->AddBlock(endBB); mBfIRBuilder->SetInsertPoint(endBB); @@ -6917,9 +7056,9 @@ void BfModule::Visit(BfDeferStatement* deferStmt) // We only want the breakpoint to hit on execution of the defer, not on insertion of it //SetAndRestoreValue prevSetIllegalSrcPos(mSetIllegalSrcPosition, true); - UpdateSrcPos(deferStmt); + UpdateSrcPos(deferStmt); EmitEnsureInstructionAt(); - + BfScopeData* scope = NULL; if (deferStmt->mScopeToken != NULL) @@ -6935,7 +7074,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt) scope = mCurMethodState->mCurScope; if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) - { + { auto targetIdentifier = BfNodeDynCast(deferStmt->mScopeName); if ((deferStmt->mScopeName == NULL) || (targetIdentifier != NULL)) mCompiler->mResolvePassData->mAutoComplete->CheckLabel(targetIdentifier, deferStmt->mColonToken, scope); @@ -6944,14 +7083,14 @@ void BfModule::Visit(BfDeferStatement* deferStmt) if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL)) { auto parser = deferStmt->GetParser(); - if ((parser == NULL) || (!parser->mIsEmitted)) + if ((parser == NULL) || (!parser->mIsEmitted)) Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken); } if (auto block = BfNodeDynCast(deferStmt->mTargetNode)) - { + { if (deferStmt->mBind != NULL) - { + { Array captures; for (auto identifier : deferStmt->mBind->mParams) { @@ -6962,18 +7101,18 @@ void BfModule::Visit(BfDeferStatement* deferStmt) { captures.push_back(deferredCapture); } - } + } AddDeferredBlock(block, scope, &captures); } else AddDeferredBlock(block, scope); } else if (auto exprStmt = BfNodeDynCast(deferStmt->mTargetNode)) - { + { BfExprEvaluator expressionEvaluator(this); expressionEvaluator.mDeferCallRef = exprStmt->mExpression; expressionEvaluator.mDeferScopeAlloc = scope; - expressionEvaluator.VisitChild(exprStmt->mExpression); + expressionEvaluator.VisitChild(exprStmt->mExpression); if (mCurMethodState->mPendingNullConditional != NULL) FlushNullConditional(expressionEvaluator.mResult, true); } @@ -6998,9 +7137,9 @@ void BfModule::Visit(BfDeferStatement* deferStmt) { isGenericParam = true; auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)val.mType); - if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Delete) - return; - if (genericParamInst->mTypeConstraint != NULL) + if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Delete) + return; + if (genericParamInst->mTypeConstraint != NULL) checkType = genericParamInst->mTypeConstraint; } @@ -7040,7 +7179,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt) } else if (customAllocator) { - BfFunctionBindResult functionBindResult; + BfFunctionBindResult functionBindResult; functionBindResult.mWantsArgs = true; auto customAllocTypeInst = customAllocator.mType->ToTypeInstance(); if ((checkType->IsObjectOrInterface()) && (customAllocTypeInst != NULL) && (customAllocTypeInst->mTypeDef->GetMethodByName("FreeObject") != NULL)) @@ -7063,7 +7202,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt) auto voidPtrType = GetPrimitiveType(BfTypeCode_NullPtr); auto ptrValue = BfTypedValue(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(voidPtrType)), voidPtrType); BfTypedValueExpression typedValueExpr; - typedValueExpr.Init(ptrValue); + typedValueExpr.Init(ptrValue); BfExprEvaluator exprEvaluator(this); SizedArray argExprs; argExprs.push_back(&typedValueExpr); @@ -7076,13 +7215,13 @@ void BfModule::Visit(BfDeferStatement* deferStmt) } if (functionBindResult.mMethodInstance != NULL) - { + { AddDeferredCall(BfModuleMethodInstance(functionBindResult.mMethodInstance, functionBindResult.mFunc), functionBindResult.mIRArgs, scope, deleteStmt, true); } - } + } if (checkType->IsObjectOrInterface()) - { + { auto objectType = mContext->mBfObjectType; PopulateType(objectType); BfMethodInstance* methodInstance = objectType->mVirtualMethodTable[mCompiler->GetVTableMethodOffset() + 0].mImplementingMethod; @@ -7104,7 +7243,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt) llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr))); AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true); } - } + } auto moduleMethodInstance = GetMethodInstance(objectType, methodInstance->mMethodDef, BfTypeVector()); AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true); @@ -7113,10 +7252,10 @@ void BfModule::Visit(BfDeferStatement* deferStmt) { auto moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), (deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete"); AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true); - } - } + } + } else - { + { if ((!customAllocator) && (!isAppendDelete)) { val = LoadValue(val); @@ -7128,8 +7267,8 @@ void BfModule::Visit(BfDeferStatement* deferStmt) SizedArray llvmArgs; llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr))); AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true); - } - } + } + } } else { @@ -7154,7 +7293,7 @@ void BfModule::Visit(BfLabeledBlock* labeledBlock) } void BfModule::Visit(BfRootNode* rootNode) -{ +{ VisitMembers(rootNode); } @@ -7293,7 +7432,7 @@ void BfModule::Visit(BfInlineAsmStatement* asmStmt) { if (hasOpCode) // check against label-only lines (which still get written out, but don't do any other processing) { - int argCount = (int)asmInst.mArgs.size(); + int argCount = (int)asmInst.mArgs.size(); for (int iArg=0; iArgmInstructions.empty()) debugLocOffset = asmStmt->mInstructions.front()->GetSrcStart() - asmStmt->GetSrcStart(); UpdateSrcPos(asmStmt, true, debugLocOffset); @@ -7686,7 +7825,7 @@ void BfModule::Visit(BfInlineAsmStatement* asmStmt) //BasicBlock* block = mBfIRBuilder->GetInsertBlock(); //auto declareVar = mDIBuilder->insertDeclare(varValue, diVariable, mBfIRBuilder->GetInsertBlock()); - auto declareVar = mDIBuilder->insertDeclare(allocaInst, diVariable, mDIBuilder->createExpression(), + auto declareVar = mDIBuilder->insertDeclare(allocaInst, diVariable, mDIBuilder->createExpression(), mIRBuilder->getCurrentDebugLocation(), mBfIRBuilder->GetInsertBlock()); //auto declareVar = mDIBuilder->insertDbgValueIntrinsic(varValue, 0, diVariable, mBfIRBuilder->GetInsertBlock()); declareVar->setDebugLoc(mIRBuilder->getCurrentDebugLocation()); @@ -7751,4 +7890,4 @@ void BfModule::Visit(BfInlineAsmStatement* asmStmt) RestoreScopeState(&prevScope); #endif -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index b45d74e4..28be7946 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -23,7 +23,7 @@ using namespace llvm; #pragma warning(disable:4996) void Beefy::DoBfLog(int fileIdx, const char* fmt ...) -{ +{ static int entryNum = 0; static bool onNewLine[10]; entryNum++; @@ -47,7 +47,7 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...) char exeName[512]; int len = 512; BfpSystem_GetExecutablePath(exeName, &len, NULL); - + String dbgName = exeName; int dotPos = (int)dbgName.IndexOf('.'); if (dotPos != -1) @@ -58,21 +58,21 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...) dbgName += 'B'; dbgName += ".txt"; - + fp[fileIdx] = BfpFile_Create(dbgName.c_str(), BfpFileCreateKind_CreateAlways, (BfpFileCreateFlags)(BfpFileCreateFlag_Write | BfpFileCreateFlag_NoBuffering | BfpFileCreateFlag_ShareRead), BfpFileAttribute_Normal, NULL); onNewLine[fileIdx] = true; logCount[fileIdx]++; } if (fp[fileIdx] == NULL) - return; - - char lineStr[4096]; + return; + + char lineStr[4096]; int strOfs; int maxChars; - + if (onNewLine[fileIdx]) { - strOfs = sprintf(lineStr, "%d", entryNum) + 1; + strOfs = sprintf(lineStr, "%d", entryNum) + 1; lineStr[strOfs - 1] = ' '; maxChars = 4095 - strOfs; } @@ -87,7 +87,7 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...) int numChars = BF_stbsp_vsnprintf(lineStr + strOfs, maxChars, fmt, argList); if (numChars <= maxChars) - { + { if (strOfs + numChars > 0) { logSize[fileIdx] += strOfs + numChars; @@ -97,27 +97,27 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...) onNewLine[fileIdx] = true; else onNewLine[fileIdx] = false; - } + } else onNewLine[fileIdx] = false; return; } - + String aResult = vformat(fmt, argList); va_end(argList); - + if (onNewLine[fileIdx]) { - aResult = StrFormat("%d ", entryNum) + aResult; + aResult = StrFormat("%d ", entryNum) + aResult; } if (aResult.EndsWith('\n')) onNewLine[fileIdx] = true; else onNewLine[fileIdx] = false; - + logSize[fileIdx] += aResult.length(); - BfpFile_Write(fp[fileIdx], aResult.c_str(), aResult.length(), -1, NULL); + BfpFile_Write(fp[fileIdx], aResult.c_str(), aResult.length(), -1, NULL); } BfAtom::~BfAtom() @@ -139,13 +139,13 @@ void BfAtom::Ref() // if (mTypeData->mTypesHash.IsZero()) // { // for (auto typeDef : mTypeData->mTypeDefs) -// { +// { // if (typeDef->mNextRevision != NULL) // { // HASH128_MIXIN(mTypeData->mTypesHash, typeDef->mNextRevision->mHash); // continue; // } -// +// // // Use the typeDef's 'mHash' here - we don't want our hash to change when // // the internals of a typeDef changes, we just want it to change when // // we add or remove typeDefs of this given name @@ -165,7 +165,7 @@ BfAtomComposite::BfAtomComposite() BfAtomComposite::BfAtomComposite(BfAtom* atom) { - Set(&atom, 1, NULL, 0); + Set(&atom, 1, NULL, 0); } BfAtomComposite::BfAtomComposite(const BfAtomComposite& rhs) @@ -193,7 +193,7 @@ BfAtomComposite::BfAtomComposite(BfAtomComposite&& rhs) rhs.mOwns = false; return; } - + mParts = NULL; mSize = 0; mAllocSize = 0; @@ -218,7 +218,7 @@ BfAtomComposite::BfAtomComposite(const BfAtomComposite& left, BfAtom* right) mAllocSize = 0; mOwns = false; Set(left.mParts, left.mSize, &right, 1); -} +} void BfAtomComposite::Set(const BfAtomComposite& left, const BfAtomComposite& right) { @@ -226,13 +226,13 @@ void BfAtomComposite::Set(const BfAtomComposite& left, const BfAtomComposite& ri } void BfAtomComposite::Set(BfAtom** atomsA, int countA, BfAtom** atomsB, int countB) -{ +{ BfAtom** freeParts = NULL; if (countA + countB > mAllocSize) { if (mOwns) // Defer freeing incase we are referring to ourselves - freeParts = mParts; + freeParts = mParts; mAllocSize = countA + countB; mParts = (BfAtom**)malloc(sizeof(BfAtom*) * mAllocSize); mOwns = true; @@ -255,7 +255,7 @@ BfAtomComposite::~BfAtomComposite() } BfAtomComposite& BfAtomComposite::operator=(const BfAtomComposite& rhs) -{ +{ Set(rhs.mParts, rhs.mSize, NULL, 0); return *this; } @@ -279,7 +279,7 @@ bool BfAtomComposite::IsValid() const { for (int i = 0; i < mSize; i++) if (mParts[i] == NULL) - return false; + return false; return true; } @@ -310,13 +310,13 @@ String BfAtomComposite::ToString() const } void BfAtomComposite::ToString(StringImpl& str) const -{ +{ for (int i = 0; i < mSize; i++) { if (i > 0) str += "."; str += mParts[i]->mString; - } + } } bool BfAtomComposite::StartsWith(const BfAtomComposite& other) const @@ -334,7 +334,7 @@ bool BfAtomComposite::EndsWith(const BfAtomComposite& other) const int ofs = mSize - other.mSize; if (ofs < 0) return false; - + for (int i = 0; i < other.mSize; i++) if (mParts[i + ofs] != other.mParts[i]) return false; @@ -362,7 +362,7 @@ void BfAtomComposite::Reference(const BfAtomComposite & other) // Val128 BfAtomComposite::GetTypesHash() // { // Val128 hash; -// for (int i = 0; i < mSize; i++) +// for (int i = 0; i < mSize; i++) // { // auto atom = mParts[i]; // if (atom->mRefCount == 0) @@ -435,7 +435,7 @@ bool BfPropertyDef::IsVirtual() } bool BfPropertyDef::HasExplicitInterface() -{ +{ for (auto methodDef : mMethods) { if (methodDef->mExplicitInterface != NULL) @@ -470,21 +470,21 @@ BfAstNode* BfMethodDef::GetRefNode() if (operatorDef->mOperatorDeclaration->mOpTypeToken != NULL) return operatorDef->mOperatorDeclaration->mOpTypeToken; return operatorDef->mOperatorDeclaration->mOperatorToken; - } + } if (auto methodDeclaration = GetMethodDeclaration()) { if (auto ctorDecl = BfNodeDynCast(methodDeclaration)) - return ctorDecl->mThisToken; + return ctorDecl->mThisToken; if (methodDeclaration->mNameNode != NULL) - return methodDeclaration->mNameNode; + return methodDeclaration->mNameNode; return methodDeclaration; } if (auto methodDeclaration = GetPropertyMethodDeclaration()) - { + { return methodDeclaration->mNameNode; } - if (mDeclaringType != NULL) - return mDeclaringType->GetRefNode(); + if (mDeclaringType != NULL) + return mDeclaringType->GetRefNode(); return NULL; } @@ -505,7 +505,7 @@ bool BfMethodDef::HasBody() { auto body = methodDeclaration->mBody; return (body != NULL) && (!BfNodeIsA(body)); - } + } return false; } @@ -542,6 +542,7 @@ void BfMethodDef::FreeMembers() for (auto genericParam : mGenericParams) delete genericParam; mGenericParams.Clear(); + delete mParamNameMap; } BfMethodDeclaration* BfMethodDef::GetMethodDeclaration() @@ -585,8 +586,8 @@ bool BfMethodDef::IsCtorOrInit() } String BfMethodDef::ToString() -{ - String methodText; +{ + String methodText; if (mName.empty()) { if (auto operatorDecl = BfNodeDynCast(mMethodDeclaration)) @@ -606,7 +607,7 @@ String BfMethodDef::ToString() else if (mMethodType == BfMethodType_Dtor) methodText += "~this"; else - methodText += mName; + methodText += mName; if (mMethodType == BfMethodType_Mixin) methodText += "!"; @@ -660,18 +661,28 @@ int BfMethodDef::GetExplicitParamCount() return (int)mParams.size(); } +void BfMethodDef::BuildParamNameMap() +{ + if (mParamNameMap != NULL) + return; + + mParamNameMap = new Dictionary(); + for (int i = 0; i < mParams.mSize; i++) + (*mParamNameMap)[mParams[i]->mName] = i; +} + /// void BfTypeDef::Reset() { FreeMembers(); - Init(); + Init(); } void BfTypeDef::FreeMembers() -{ +{ if ((!mIsCombinedPartial) && (mEmitParent == NULL)) - mSystem->RemoveNamespaceUsage(mNamespace, mProject); + mSystem->RemoveNamespaceUsage(mNamespace, mProject); if (mName != NULL) { @@ -696,17 +707,17 @@ void BfTypeDef::FreeMembers() { BF_ASSERT(mNameEx->mPendingDerefCount > 0); if (mNameEx->mPendingDerefCount > 0) - mNameEx->mPendingDerefCount--; + mNameEx->mPendingDerefCount--; } mSystem->ReleaseAtom(mNameEx); mNameEx = NULL; } - + for (auto genericParam : mGenericParamDefs) { // auto genericParamCopy = *genericParam; // BF_ASSERT(genericParam->mOwner != NULL); -// +// // if (genericParam->mOwner == this) delete genericParam; } @@ -717,18 +728,18 @@ void BfTypeDef::FreeMembers() mFields.Clear(); for (auto prop : mProperties) delete prop; - mProperties.Clear(); + mProperties.Clear(); for (auto method : mMethods) delete method; - mMethods.Clear(); + mMethods.Clear(); mNestedTypes.Clear(); // mOperators are also in mMethods so we don't need to delete those specifically mOperators.Clear(); for (auto& searchName : mNamespaceSearch) - mSystem->ReleaseAtomComposite(searchName); + mSystem->ReleaseAtomComposite(searchName); mNamespaceSearch.Clear(); - + mStaticSearch.Clear(); mInternalAccessSet.Clear(); @@ -764,13 +775,6 @@ void BfTypeDef::PopulateMemberSets() fieldDef->mNextWithSameName = (BfFieldDef*)entry->mMemberDef; entry->mMemberDef = fieldDef; } - - if (fieldDef->mUsingProtection != BfProtection_Hidden) - { - if (mUsingFieldData == NULL) - mUsingFieldData = new BfUsingFieldData(); - mUsingFieldData->mUsingFields.Add(fieldDef); - } } while (mPropertySet.mSourceSize < mProperties.mSize) @@ -784,13 +788,6 @@ void BfTypeDef::PopulateMemberSets() propDef->mNextWithSameName = (BfPropertyDef*)entry->mMemberDef; entry->mMemberDef = propDef; } - - if (propDef->mUsingProtection != BfProtection_Hidden) - { - if (mUsingFieldData == NULL) - mUsingFieldData = new BfUsingFieldData(); - mUsingFieldData->mUsingFields.Add(propDef); - } } } @@ -803,8 +800,6 @@ void BfTypeDef::ClearMemberSets() for (auto entry : mFieldSet) ((BfFieldDef*)entry.mMemberDef)->mNextWithSameName = NULL; mFieldSet.Clear(); - delete mUsingFieldData; - mUsingFieldData = NULL; for (auto entry : mPropertySet) ((BfPropertyDef*)entry.mMemberDef)->mNextWithSameName = NULL; @@ -823,7 +818,6 @@ BfTypeDef::~BfTypeDef() mSource->mRefCount--; BF_ASSERT(mSource->mRefCount >= 0); } - delete mUsingFieldData; } BfSource* BfTypeDef::GetLastSource() @@ -866,14 +860,14 @@ int BfTypeDef::GetSelfGenericParamCount() BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount) { PopulateMemberSets(); - BfMemberSetEntry* entry = NULL; + BfMemberSetEntry* entry = NULL; if (!mMethodSet.TryGetWith(name, &entry)) return NULL; BfMethodDef* bestMethodDef = NULL; auto methodDef = (BfMethodDef*)entry->mMemberDef; while (methodDef != NULL) - { + { if (((paramCount == -1) || (paramCount == (int)methodDef->mParams.size()))) { if ((bestMethodDef == NULL) || @@ -898,7 +892,7 @@ BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name) } String BfTypeDef::ToString() -{ +{ String typeName(mName->ToString()); auto checkOuterTypeDef = mOuterType; while (checkOuterTypeDef != NULL) @@ -932,7 +926,7 @@ bool BfTypeDef::HasAutoProperty(BfPropertyDeclaration* propertyDeclaration) return false; if (propertyDeclaration->mExternSpecifier != NULL) return false; - + for (auto methodDeclaration : propertyDeclaration->mMethods) { if (methodDeclaration->mBody == NULL) @@ -942,7 +936,7 @@ bool BfTypeDef::HasAutoProperty(BfPropertyDeclaration* propertyDeclaration) } String BfTypeDef::GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration) -{ +{ String name = "prop__"; if (propertyDeclaration->IsA()) name += "indexer__"; @@ -1007,9 +1001,9 @@ bool BfTypeDef::NameEquals(BfTypeDef* otherTypeDef) } bool BfTypeDef::HasSource(BfSource* source) -{ +{ if (mNextRevision != NULL) - return mNextRevision->HasSource(source); + return mNextRevision->HasSource(source); if (mSource == source) return true; if ((mSource != NULL) && (mSource->mNextRevision != NULL) && (mSource->mNextRevision == source)) @@ -1034,8 +1028,8 @@ bool BfTypeDef::HasParsingFailed() { auto parser = mTypeDeclaration->GetParser(); if ((parser != NULL) && (parser->mParsingFailed)) - return true; - + return true; + for (auto partial : mPartials) { parser = partial->mTypeDeclaration->GetParser(); @@ -1049,11 +1043,11 @@ bool BfTypeDef::HasParsingFailed() ////////////////////////////////////////////////////////////////////////// BfProject::BfProject() -{ +{ mDisabled = false; mSingleModule = false; mTargetType = BfTargetType_BeefConsoleApplication; - mBuildConfigChanged = false; + mBuildConfigChanged = false; mSingleModule = false; mAlwaysIncludeAll = false; mDeleteStage = BfProject::DeleteStage_None; @@ -1117,8 +1111,8 @@ size_t BfErrorEntry::GetHashCode() const HashContext hashCtx; hashCtx.Mixin(mError->mSrcStart); hashCtx.Mixin(mError->mSrcEnd); - hashCtx.Mixin(mError->mSource); - hashCtx.Mixin(mError->mIsWarning); + hashCtx.Mixin(mError->mSource); + hashCtx.Mixin(mError->mIsWarning); hashCtx.Mixin(mError->mIsDeferred); return (size_t)hashCtx.Finish64(); } @@ -1231,8 +1225,8 @@ bool BfPassInstance::WantsRangeDisplayed(BfSourceData* bfSource, int srcIdx, int auto bfParser = (bfSource == NULL) ? NULL : bfSource->ToParser(); if (bfParser == NULL) return true; - if (bfParser->mCursorIdx == -1) - return !mTrimMessagesToCursor; + if (bfParser->mCursorIdx == -1) + return !mTrimMessagesToCursor; if ((bfParser->mCursorIdx >= srcIdx) && (bfParser->mCursorIdx < srcIdx + srcLen)) return true; return false; @@ -1281,7 +1275,7 @@ static void VisibleAdvance(const char* str, int strLength, int& idx) idx++; break; } - + int cLen = 0; uint32 c32 = u8_toucs(str + idx, strLength - idx, &cLen); idx += cLen; @@ -1337,14 +1331,14 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er lineNum++; } } - + int lineChar = origSrcIdx - lineStart; bool endsWithPunctuation = false; int lastChar = error[(int)error.length() - 1]; String formatStr; if ((lastChar == '.') || (lastChar == '?') || (lastChar == '!')) - formatStr = "%s %s Line %d:%d in %s"; + formatStr = "%s %s Line %d:%d in %s"; else formatStr = "%s %s at line %d:%d in %s"; @@ -1364,19 +1358,19 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er else if (spaceCount == 1) lineStr.Append(""); spaceCount = 0; - + if (tabCount > 1) lineStr += StrFormat("<%d TABS>", tabCount); else if (tabCount == 1) lineStr.Append(""); - tabCount = 0; + tabCount = 0; }; for (int i = 0; i < 255; i++) { char c = bfParser->mSrc[lineStart + i]; if ((c == '\0') || (c == '\n') || (c == '\r')) - { + { break; } else if (c == '\t') @@ -1386,7 +1380,7 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er if (spaceCount > 0) _FlushSpacing(); tabCount++; - //lineStr.Append("\xe2\x86\x92"); // Arrow \u2192 + //lineStr.Append("\xe2\x86\x92"); // Arrow \u2192 } else lineStr.Append(' '); @@ -1409,7 +1403,7 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er showSpaces = false; lineStr.Append(c); } - } + } _FlushSpacing(); OutputLine(lineStr); @@ -1428,7 +1422,7 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er lineStr[i] = c; } OutputLine(lineStr);*/ - + // Don't show '^^^^^^^^^' under the entire line bool isFullUnderline = true; for (int i = lineStart; i < srcIdx; i++) @@ -1437,7 +1431,7 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er if (!::isspace((uint8)c)) isFullUnderline = false; } - + if (isFullUnderline) { isFullUnderline = false; @@ -1467,7 +1461,7 @@ void BfPassInstance::MessageAt(const StringImpl& msgPrefix, const StringImpl& er break; } OutputLine(pointerStr); - } + } } BfError* BfPassInstance::FailAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags) @@ -1478,10 +1472,10 @@ BfError* BfPassInstance::FailAt(const StringImpl& error, BfSourceData* bfSource, mFailedIdx++; if ((int) mErrors.size() >= sMaxErrors) return NULL; - + if (!WantsRangeRecorded(bfSource, srcIdx, srcLen, false)) return NULL; - + TrimSourceRange(bfSource, srcIdx, srcLen); BfError* errorVal = new BfError(); @@ -1491,7 +1485,7 @@ BfError* BfPassInstance::FailAt(const StringImpl& error, BfSourceData* bfSource, errorVal->mError = error; errorVal->mSrcStart = srcIdx; errorVal->mSrcEnd = srcIdx + srcLen; - //int checkEnd = srcIdx + srcLen; + //int checkEnd = srcIdx + srcLen; for (int i = srcIdx; i < srcIdx + srcLen; i++) { char c = bfSource->mSrc[i]; @@ -1516,7 +1510,6 @@ BfError* BfPassInstance::FailAt(const StringImpl& error, BfSourceData* bfSource, return errorVal; } - void BfPassInstance::FixSrcStartAndEnd(BfSourceData* bfSource, int& startIdx, int& endIdx) { auto bfParser = bfSource->ToParserData(); @@ -1554,9 +1547,9 @@ BfError* BfPassInstance::FailAfterAt(const StringImpl& error, BfSourceData* bfSo FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd); mErrorSet.Add(BfErrorEntry(errorVal)); mErrors.push_back(errorVal); - + mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx - 1, 2, false); - if (mLastWasDisplayed) + if (mLastWasDisplayed) { String errorStart = "ERROR"; /*if ((int)mErrors.size() > 1) @@ -1574,7 +1567,7 @@ BfError* BfPassInstance::Fail(const StringImpl& error) BfError* errorVal = new BfError(); errorVal->mIsWarning = false; - errorVal->mSource = NULL; + errorVal->mSource = NULL; errorVal->mIsAfter = false; errorVal->mError = error; errorVal->mSrcStart = 0; @@ -1604,7 +1597,7 @@ BfError* BfPassInstance::Fail(const StringImpl& errorStr, BfAstNode* refNode) else if (refNode->IsA()) error = FailAt(errorStr, refNode->GetSourceData(), refNode->GetSrcStart(), 1); else - error = FailAt(errorStr, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength()); + error = FailAt(errorStr, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength()); return error; } @@ -1642,12 +1635,12 @@ BfError* BfPassInstance::DeferFail(const StringImpl& error, BfAstNode* refNode) if (refNode == NULL) { - return Fail(error); + return Fail(error); } if (!WantsRangeRecorded(refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength(), false, true)) return NULL; - + ++mDeferredErrorCount; BfError* errorVal = new BfError(); errorVal->mIsWarning = false; @@ -1678,7 +1671,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf mLastWasAdded = false; if ((int) mErrors.size() >= sMaxErrors) return NULL; - + auto bfParser = bfSource->ToParserData(); if ((bfParser != NULL) && (warningNumber > 0) && (!bfParser->IsWarningEnabledAtSrcIndex(warningNumber, srcIdx))) return NULL; @@ -1741,7 +1734,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs mLastWasAdded = false; mLastWasDisplayed = (int)mErrors.size() <= sMaxErrors; if (!mLastWasDisplayed) - return NULL; + return NULL; auto parser = refNode->GetSourceData()->ToParserData(); if (parser != NULL) @@ -1751,7 +1744,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs mLastWasDisplayed = false; return NULL; } - } + } if (refNode != NULL) return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength(), isDeferred); @@ -1817,7 +1810,7 @@ BfError* BfPassInstance::WarnAfterAt(int warningNumber, const StringImpl& error, } BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags) -{ +{ if (!mLastWasDisplayed) { if (mLastWasAdded) @@ -1842,7 +1835,7 @@ BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfS } BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, bool forceQueue) -{ +{ if ((!mLastWasDisplayed) || (forceQueue)) { if (mLastWasAdded) @@ -1860,7 +1853,7 @@ BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, bool forceQueue) return NULL; } - + String outText; outText += " > "; outText += info; @@ -1869,7 +1862,7 @@ BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, bool forceQueue) } BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, BfAstNode* refNode) -{ +{ if (refNode == NULL) return MoreInfo(info); else @@ -1882,11 +1875,11 @@ BfMoreInfo* BfPassInstance::MoreInfoAfter(const StringImpl& info, BfAstNode* ref } void BfPassInstance::TryFlushDeferredError() -{ +{ // This can happen in the case of an internal compiler error, where we believe we've satisfied // generic constraints but we generate an error on the specialization but not the unspecialized version bool hasDisplayedError = false; - bool hasDisplayedWarning = false; + bool hasDisplayedWarning = false; for (int pass = 0; pass < 2; pass++) { for (auto& error : mErrors) @@ -1897,7 +1890,7 @@ void BfPassInstance::TryFlushDeferredError() hasDisplayedWarning = true; else if ((pass == 1) && (!hasDisplayedWarning)) { - String errorText = "WARNING "; + String errorText = "WARNING "; if (error->mWarningNumber > 0) errorText += StrFormat(": BF%04d", error->mWarningNumber); errorText += ": "; @@ -1917,21 +1910,21 @@ void BfPassInstance::TryFlushDeferredError() else { if (!error->mIsDeferred) - hasDisplayedError = true; + hasDisplayedError = true; else if ((pass == 1) && (!hasDisplayedError)) { - MessageAt(":error", "ERROR: " + error->mError, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart); + MessageAt(":error", "ERROR: " + error->mError, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart); for (auto moreInfo : error->mMoreInfo) { - if (moreInfo->mSource != NULL) + if (moreInfo->mSource != NULL) MessageAt(":error", " > " + moreInfo->mInfo, moreInfo->mSource, moreInfo->mSrcStart, moreInfo->mSrcEnd - moreInfo->mSrcStart); else OutputLine(":error " + moreInfo->mInfo); } } } - } + } } } @@ -1960,25 +1953,25 @@ BfSystem::BfSystem() if (gPerfManager == NULL) gPerfManager = new PerfManager(); //gPerfManager->StartRecording(); - + mAtomUpdateIdx = 0; mAtomCreateIdx = 0; mTypeMapVersion = 1; CreateBasicTypes(); - mPtrSize = 4; + mPtrSize = 4; mCurSystemLockPri = -1; mYieldDisallowCount = 0; mPendingSystemLockPri = -1; mCurSystemLockThreadId = 0; mYieldTickCount = 0; mHighestYieldTime = 0; - mNeedsTypesHandledByCompiler = false; + mNeedsTypesHandledByCompiler = false; mWorkspaceConfigChanged = false; mIsResolveOnly = false; mEmptyAtom = GetAtom(""); mBfAtom = GetAtom("bf"); mGlobalsAtom = GetAtom("@"); - mTypeDot = NULL; + mTypeDot = NULL; if (gBfParserCache == NULL) gBfParserCache = new BfParserCache(); @@ -2006,24 +1999,24 @@ BfSystem::BfSystem() mDirectRefIntTypeRef->mElementType = mDirectIntTypeRef; mDirectRefIntTypeRef->mRefToken = NULL; mDirectInt32TypeRef = mDirectTypeRefs.Alloc(); - mDirectInt32TypeRef->Init("int32"); + mDirectInt32TypeRef->Init("int32"); } BfSystem::~BfSystem() -{ +{ BP_ZONE("BfSystem::~BfSystem"); BfLogSys(this, "Deleting BfSystem...\n"); BfReportMemory(); //gPerfManager->StopRecording(); - //gPerfManager->DbgPrint(); + //gPerfManager->DbgPrint(); for (auto& typeItr : mSystemTypeDefs) delete typeItr.mValue; - for (auto typeDef : mTypeDefs) - delete typeDef; + for (auto typeDef : mTypeDefs) + delete typeDef; mTypeDefs.Clear(); for (auto typeDef : mTypeDefDeleteQueue) @@ -2032,7 +2025,7 @@ BfSystem::~BfSystem() { BP_ZONE("Deleting parsers"); for (auto parser : mParsers) - { + { delete parser; } } @@ -2041,11 +2034,11 @@ BfSystem::~BfSystem() delete project; for (auto project : mProjectDeleteQueue) - delete project; - + delete project; + ReleaseAtom(mGlobalsAtom); ReleaseAtom(mBfAtom); - ReleaseAtom(mEmptyAtom); + ReleaseAtom(mEmptyAtom); ProcessAtomGraveyard(); BF_ASSERT(mAtomMap.size() == 0); @@ -2072,7 +2065,7 @@ BfSystem::~BfSystem() mSystemTypeDefs[name] = typeDef; BfAtom* BfSystem::GetAtom(const StringImpl& string) -{ +{ StringView* stringPtr = NULL; BfAtom* atom = NULL; BfAtom** atomPtr = NULL; @@ -2093,7 +2086,7 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string) atom->mString = *stringPtr; atom->mRefCount = 1; atom->mPendingDerefCount = 0; - + atom->mHash = 0; for (char c : string) atom->mHash = ((atom->mHash ^ c) << 5) - atom->mHash; @@ -2104,17 +2097,17 @@ BfAtom* BfSystem::GetAtom(const StringImpl& string) } else atom = *atomPtr; - + atom->Ref(); return atom; } BfAtom* BfSystem::FindAtom(const StringImpl& string) -{ +{ BfAtom** atomPtr = NULL; if (mAtomMap.TryGetValueWith(string, &atomPtr)) - return *atomPtr; - return NULL; + return *atomPtr; + return NULL; } BfAtom* BfSystem::FindAtom(const StringView& string) @@ -2126,13 +2119,13 @@ BfAtom* BfSystem::FindAtom(const StringView& string) } void BfSystem::ReleaseAtom(BfAtom* atom) -{ +{ if (--atom->mRefCount == 0) - { - mAtomGraveyard.push_back(atom); + { + mAtomGraveyard.push_back(atom); return; } - + BF_ASSERT(atom->mRefCount > 0); // Sanity check BF_ASSERT(atom->mRefCount < 1000000); @@ -2173,7 +2166,7 @@ bool BfSystem::ParseAtomComposite(const StringView& name, BfAtomComposite& compo BF_ASSERT(composite.mSize == 0); int lastDot = -1; for (int i = 0; i <= (int)name.mLength; i++) - { + { if ((i == (int)name.mLength) || (name[i] == '.')) { BfAtom* atom; @@ -2184,7 +2177,7 @@ bool BfSystem::ParseAtomComposite(const StringView& name, BfAtomComposite& compo if (atom == NULL) isValid = false; parts.push_back(atom); - lastDot = i; + lastDot = i; } } if (!parts.IsEmpty()) @@ -2216,7 +2209,7 @@ void BfSystem::SanityCheckAtomComposite(const BfAtomComposite& atomComposite) { for (int i = 0; i < atomComposite.mSize; i++) { - auto part = atomComposite.mParts[i]; + auto part = atomComposite.mParts[i]; BF_ASSERT(part != NULL); BF_ASSERT(part->mRefCount > 0); BF_ASSERT(part->mRefCount < 1000000); @@ -2224,7 +2217,7 @@ void BfSystem::SanityCheckAtomComposite(const BfAtomComposite& atomComposite) } void BfSystem::TrackName(BfTypeDef* typeDef) -{ +{ if (!typeDef->IsEmitted()) { for (int i = 0; i < (int)typeDef->mFullName.mSize - 1; i++) @@ -2248,7 +2241,7 @@ void BfSystem::UntrackName(BfTypeDef* typeDef) { BfAtom* nameAtom = typeDef->mName; if (nameAtom != mEmptyAtom) - { + { nameAtom->mAtomUpdateIdx = ++mAtomUpdateIdx; } @@ -2280,9 +2273,9 @@ void BfSystem::CreateBasicTypes() { BfTypeDef* typeDef; - SYSTEM_TYPE(mTypeVoid, "void", BfTypeCode_None); + SYSTEM_TYPE(mTypeVoid, "void", BfTypeCode_None); SYSTEM_TYPE(mTypeNullPtr, "null", BfTypeCode_NullPtr); - SYSTEM_TYPE(mTypeSelf, "Self", BfTypeCode_Self); + SYSTEM_TYPE(mTypeSelf, "Self", BfTypeCode_Self); SYSTEM_TYPE(mTypeVar, "var", BfTypeCode_Var); SYSTEM_TYPE(mTypeLet, "let", BfTypeCode_Let); SYSTEM_TYPE(mTypeBool, "bool", BfTypeCode_Boolean); @@ -2302,15 +2295,15 @@ void BfSystem::CreateBasicTypes() SYSTEM_TYPE(mTypeChar16, "char16", BfTypeCode_Char16); SYSTEM_TYPE(mTypeChar32, "char32", BfTypeCode_Char32); SYSTEM_TYPE(mTypeSingle, "float", BfTypeCode_Float); - SYSTEM_TYPE(mTypeDouble, "double", BfTypeCode_Double); + SYSTEM_TYPE(mTypeDouble, "double", BfTypeCode_Double); } bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, int64 value) { - if (typeCode == BfTypeCode_IntPtr) + if (typeCode == BfTypeCode_IntPtr) typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64; - if (typeCode == BfTypeCode_UIntPtr) - typeCode = (mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64; + if (typeCode == BfTypeCode_UIntPtr) + typeCode = (mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64; switch (typeCode) { @@ -2327,7 +2320,7 @@ bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, int64 value) case BfTypeCode_UInt8: case BfTypeCode_Char8: - return (value >= 0) && (value < 0x100); + return (value >= 0) && (value < 0x100); case BfTypeCode_UInt16: case BfTypeCode_Char16: return (value >= 0) && (value < 0x10000); @@ -2343,7 +2336,7 @@ bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, int64 value) } bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, uint64 value) -{ +{ if (typeCode == BfTypeCode_IntPtr) typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64; if (typeCode == BfTypeCode_UIntPtr) @@ -2399,7 +2392,7 @@ bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, const BfVariant& variant) BfParser* BfSystem::CreateParser(BfProject* bfProject) { AutoCrit crit(mDataLock); - auto parser = new BfParser(this, bfProject); + auto parser = new BfParser(this, bfProject); mParsers.push_back(parser); BfLogSys(this, "CreateParser: %p\n", parser); @@ -2409,7 +2402,7 @@ BfParser* BfSystem::CreateParser(BfProject* bfProject) BfCompiler* BfSystem::CreateCompiler(bool isResolveOnly) { - auto compiler = new BfCompiler(this, isResolveOnly); + auto compiler = new BfCompiler(this, isResolveOnly); mCompilers.push_back(compiler); if (mIsResolveOnly) BF_ASSERT(isResolveOnly); @@ -2430,28 +2423,27 @@ BfProject* BfSystem::GetProject(const StringImpl& projName) BfTypeReference* BfSystem::GetTypeRefElement(BfTypeReference* typeRef) { if (auto elementedType = BfNodeDynCast(typeRef)) - return GetTypeRefElement(elementedType->mElementType); + return GetTypeRefElement(elementedType->mElementType); return (BfTypeReference*)typeRef; } - void BfSystem::AddNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject) { if (namespaceStr.IsEmpty()) return; - + if (namespaceStr.GetPartsCount() > 1) { - BfAtomComposite subComposite; + BfAtomComposite subComposite; subComposite.Set(namespaceStr.mParts, namespaceStr.mSize - 1, NULL, 0); AddNamespaceUsage(subComposite, bfProject); } int* valuePtr = NULL; if (bfProject->mNamespaces.TryAdd(namespaceStr, NULL, &valuePtr)) - { + { BfLogSys(this, "BfSystem::AddNamespaceUsage created %s in project: %p\n", namespaceStr.ToString().c_str(), bfProject); - *valuePtr = 1; + *valuePtr = 1; mTypeMapVersion++; } else @@ -2462,7 +2454,7 @@ void BfSystem::RemoveNamespaceUsage(const BfAtomComposite& namespaceStr, BfProje { if (namespaceStr.IsEmpty()) return; - + if (namespaceStr.GetPartsCount() > 1) { BfAtomComposite subComposite; @@ -2471,7 +2463,7 @@ void BfSystem::RemoveNamespaceUsage(const BfAtomComposite& namespaceStr, BfProje } int* valuePtr = NULL; - bfProject->mNamespaces.TryGetValue(namespaceStr, &valuePtr); + bfProject->mNamespaces.TryGetValue(namespaceStr, &valuePtr); BF_ASSERT(valuePtr != NULL); (*valuePtr)--; if (*valuePtr == 0) @@ -2503,7 +2495,7 @@ bool BfSystem::ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* } BfTypeDef* BfSystem::FilterDeletedTypeDef(BfTypeDef* typeDef) -{ +{ if ((typeDef != NULL) && (typeDef->mDefState == BfTypeDef::DefState_Deleted)) return NULL; return typeDef; @@ -2519,44 +2511,46 @@ bool BfSystem::CheckTypeDefReference(BfTypeDef* typeDef, BfProject* project) } BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const Array& namespaceSearch, BfTypeDef** ambiguousTypeDef, BfFindTypeDefFlags flags) -{ +{ if (findName.GetPartsCount() == 1) - { + { BfTypeDef** typeDefPtr = NULL; if (mSystemTypeDefs.TryGetValueWith(findName.mParts[0]->mString, &typeDefPtr)) return FilterDeletedTypeDef(*typeDefPtr); } // This searched globals, but we were already doing that down below at the LAST step. Right? - BfTypeDef* foundTypeDef = NULL; + BfTypeDef* foundTypeDef = NULL; BfAtomCompositeT<16> qualifiedFindName; + bool allowGlobal = (flags & BfFindTypeDefFlag_AllowGlobal) != 0; + int foundPri = (int)0x80000000; for (int namespaceIdx = 0; namespaceIdx <= (int) namespaceSearch.size(); namespaceIdx++) - { + { int curNamespacePri = 0; if (namespaceIdx < (int)namespaceSearch.size()) - { + { auto& namespaceDeclaration = namespaceSearch[namespaceIdx]; qualifiedFindName.Set(namespaceDeclaration, findName); } else - { + { qualifiedFindName = findName; } - + int partialStartEntryIdx = -1; - auto itr = mTypeDefs.TryGet(qualifiedFindName); + auto itr = mTypeDefs.TryGet(qualifiedFindName); while (itr) { BfTypeDef* typeDef = *itr; - if ((typeDef->mIsPartial) || + if ((typeDef->mIsPartial) || ((typeDef->IsGlobalsContainer()) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0))) { bool handled = false; - if (itr.mCurEntry < mTypeDefs.mPartialSkipCache.mSize) + if ((itr.mCurEntry < mTypeDefs.mPartialSkipCache.mSize) && (!allowGlobal)) { auto& entry = mTypeDefs.mPartialSkipCache[itr.mCurEntry]; if (entry.mRevision == mTypeDefs.mRevision) @@ -2581,8 +2575,8 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric continue; } } - - if ((partialStartEntryIdx != -1) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0)) + + if ((partialStartEntryIdx != -1) && (!allowGlobal)) { mTypeDefs.SetPartialSkipCache(partialStartEntryIdx, itr.mCurEntry); partialStartEntryIdx = -1; @@ -2590,7 +2584,7 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project))) { - int curPri = curNamespacePri; + int curPri = curNamespacePri; if (typeDef->mGenericParamDefs.size() != numGenericArgs) { // Still allow SOME match even if we put in the wrong number of generic args @@ -2607,26 +2601,26 @@ BfTypeDef* BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGeneric else if (curPri == foundPri) { if ((ambiguousTypeDef != NULL) && (!typeDef->mIsPartial)) - *ambiguousTypeDef = typeDef; + *ambiguousTypeDef = typeDef; } } itr.MoveToNextHashMatch(); } - if ((partialStartEntryIdx != -1) && ((flags & BfFindTypeDefFlag_AllowGlobal) == 0)) + if ((partialStartEntryIdx != -1) && (!allowGlobal)) mTypeDefs.SetPartialSkipCache(partialStartEntryIdx, -1); - } + } // Didn't match the correct number of generic params, but let the compiler complain return FilterDeletedTypeDef(foundTypeDef); } bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const BfAtomComposite& checkNamespace, bool allowPrivate, BfTypeDefLookupContext* ctx) -{ +{ BfAtomComposite const* qualifiedFindNamePtr; BfAtomComposite qualifiedFindName; - BfAtom* tempData[16]; - + BfAtom* tempData[16]; + if (checkNamespace.IsEmpty()) { if ((findName.mSize == 1) && (findName.mParts[0]->mIsSystemType)) @@ -2640,31 +2634,31 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, return true; } qualifiedFindNamePtr = &findName; - } + } else { qualifiedFindName.mAllocSize = 16; qualifiedFindName.mParts = tempData; qualifiedFindName.Set(checkNamespace, findName); qualifiedFindNamePtr = &qualifiedFindName; - } + } BfProtection minProtection = allowPrivate ? BfProtection_Private : BfProtection_Protected; bool hadMatch = false; - auto itr = mTypeDefs.TryGet(*qualifiedFindNamePtr); + auto itr = mTypeDefs.TryGet(*qualifiedFindNamePtr); while (itr) { BfTypeDef* typeDef = *itr; - if ((typeDef->mIsPartial) || + if ((typeDef->mIsPartial) || (typeDef->mDefState == BfTypeDef::DefState_Deleted)) { itr.MoveToNextHashMatch(); continue; } - + if ((typeDef->mFullName == *qualifiedFindNamePtr) && (CheckTypeDefReference(typeDef, project))) { int curPri = 0; @@ -2685,31 +2679,31 @@ bool BfSystem::FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, if ((curPri > ctx->mBestPri) || (ctx->mBestTypeDef == NULL)) { - ctx->mBestTypeDef = typeDef; + ctx->mBestTypeDef = typeDef; ctx->mAmbiguousTypeDef = NULL; ctx->mBestPri = curPri; hadMatch = true; } else if (curPri == ctx->mBestPri) - { + { ctx->mAmbiguousTypeDef = typeDef; } } itr.MoveToNextHashMatch(); } - if (qualifiedFindName.mParts == tempData) - qualifiedFindName.mParts = NULL; + if (qualifiedFindName.mParts == tempData) + qualifiedFindName.mParts = NULL; return hadMatch; } BfTypeDef* BfSystem::FindTypeDef(const StringImpl& typeName, int numGenericArgs, BfProject* project, const Array& namespaceSearch, BfTypeDef** ambiguousTypeDef, BfFindTypeDefFlags flags) { - BfAtomCompositeT<16> qualifiedFindName; + BfAtomCompositeT<16> qualifiedFindName; BfTypeDef* result = NULL; if (ParseAtomComposite(typeName, qualifiedFindName)) - result = FindTypeDef(qualifiedFindName, numGenericArgs, project, namespaceSearch, ambiguousTypeDef, flags); + result = FindTypeDef(qualifiedFindName, numGenericArgs, project, namespaceSearch, ambiguousTypeDef, flags); return result; } @@ -2740,8 +2734,8 @@ BfTypeDef * BfSystem::FindTypeDef(const StringImpl& typeName, BfProject* project } } - if (firstChevIdx != -1) - findName = typeName.Substring(0, firstChevIdx); + if (firstChevIdx != -1) + findName = typeName.Substring(0, firstChevIdx); else findName = typeName; @@ -2760,12 +2754,12 @@ BfTypeDef* BfSystem::FindTypeDefEx(const StringImpl& fullTypeName) int numGenericArgs = 0; String typeName = fullTypeName.Substring(colonPos + 1); - int tildePos = (int)typeName.LastIndexOf('`'); + int tildePos = (int)typeName.LastIndexOf('`'); if (tildePos != -1) { BF_ASSERT(tildePos > (int)typeName.LastIndexOf('.')); numGenericArgs = atoi(typeName.c_str() + tildePos + 1); - typeName.RemoveToEnd(tildePos); + typeName.RemoveToEnd(tildePos); } BfAtomComposite qualifiedFindName; @@ -2775,15 +2769,15 @@ BfTypeDef* BfSystem::FindTypeDefEx(const StringImpl& fullTypeName) BfTypeDef* result = NULL; if (ParseAtomComposite(typeName, qualifiedFindName)) - { + { auto itr = mTypeDefs.TryGet(qualifiedFindName); while (itr) { - BfTypeDef* typeDef = *itr; - if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project)) && + BfTypeDef* typeDef = *itr; + if ((typeDef->mFullName == qualifiedFindName) && (CheckTypeDefReference(typeDef, project)) && (!typeDef->mIsPartial)) - { - if (typeDef->mGenericParamDefs.size() == numGenericArgs) + { + if (typeDef->mGenericParamDefs.size() == numGenericArgs) return typeDef; } itr.MoveToNextHashMatch(); @@ -2804,7 +2798,7 @@ void BfSystem::FindFixitNamespaces(const StringImpl& typeName, int numGenericArg // name and then adds its namespace to the fixitNamespaces for (auto typeDef : mTypeDefs) - { + { if ((typeDef->mName == findName.mParts[0]) && (CheckTypeDefReference(typeDef, project)) && ((numGenericArgs == -1) || (typeDef->mGenericParamDefs.size() == numGenericArgs))) @@ -2821,18 +2815,18 @@ void BfSystem::FindFixitNamespaces(const StringImpl& typeName, int numGenericArg outerName = typeDef->mNamespace.ToString(); fixitNamespaces.insert(outerName); } - } + } } void BfSystem::RemoveTypeDef(BfTypeDef* typeDef) -{ - BF_ASSERT(typeDef->mDefState == BfTypeDef::DefState_Deleted); +{ + BF_ASSERT(typeDef->mDefState == BfTypeDef::DefState_Deleted); // mTypeDef is already locked by the system lock - mTypeDefs.Remove(typeDef); + mTypeDefs.Remove(typeDef); AutoCrit autoCrit(mDataLock); - + if (typeDef->mOuterType != NULL) - { + { // We are in the outer type's mNestedTypes list BfLogSys(this, "Setting mForceUseNextRevision on outer type %p from %p\n", typeDef->mOuterType, typeDef); typeDef->mOuterType->mForceUseNextRevision = true; @@ -2851,8 +2845,8 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef) typeDef->mNameEx->mPendingDerefCount++; } typeDef->mInDeleteQueue = true; - - mTypeDefDeleteQueue.push_back(typeDef); + + mTypeDefDeleteQueue.push_back(typeDef); mTypeMapVersion++; } @@ -2863,7 +2857,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) bool setDeclaringType = !typeDef->mIsCombinedPartial; auto nextTypeDef = typeDef->mNextRevision; - + for (auto prevProperty : typeDef->mProperties) delete prevProperty; typeDef->mProperties = nextTypeDef->mProperties; @@ -2871,12 +2865,12 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) for (auto prop : typeDef->mProperties) prop->mDeclaringType = typeDef; nextTypeDef->mProperties.Clear(); - + if ((typeDef->mDefState != BfTypeDef::DefState_Signature_Changed) && (typeDef->mDefState != BfTypeDef::DefState_New)) { BF_ASSERT(typeDef->mMethods.size() == nextTypeDef->mMethods.size()); - + for (auto prop : typeDef->mProperties) { for (int methodIdx = 0; methodIdx < (int)prop->mMethods.size(); methodIdx++) @@ -2886,7 +2880,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) for (int opIdx = 0; opIdx < (int)typeDef->mOperators.size(); opIdx++) { typeDef->mOperators[opIdx] = (BfOperatorDef*)typeDef->mMethods[typeDef->mOperators[opIdx]->mIdx]; - } + } // Remap methods in-place to previous revision's method list for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) @@ -2910,7 +2904,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) } else { - *methodDef = *nextMethodDef; + *methodDef = *nextMethodDef; if (setDeclaringType) methodDef->mDeclaringType = typeDef; } @@ -2922,7 +2916,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) } } else - { + { typeDef->mOperators = nextTypeDef->mOperators; nextTypeDef->mOperators.Clear(); @@ -2934,23 +2928,23 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) if (setDeclaringType) for (auto method : typeDef->mMethods) method->mDeclaringType = typeDef; - nextTypeDef->mMethods.Clear(); + nextTypeDef->mMethods.Clear(); } for (auto fieldDef : typeDef->mFields) fieldDef->mNextWithSameName = NULL; for (auto propDef : typeDef->mProperties) propDef->mNextWithSameName = NULL; - for (auto methodDef : typeDef->mMethods) - methodDef->mNextWithSameName = NULL; + for (auto methodDef : typeDef->mMethods) + methodDef->mNextWithSameName = NULL; if (typeDef->mSource != NULL) - typeDef->mSource->mRefCount--; + typeDef->mSource->mRefCount--; typeDef->mSource = nextTypeDef->mSource; typeDef->mSource->mRefCount++; typeDef->mPartialIdx = nextTypeDef->mPartialIdx; - typeDef->mTypeDeclaration = nextTypeDef->mTypeDeclaration; + typeDef->mTypeDeclaration = nextTypeDef->mTypeDeclaration; typeDef->mHash = nextTypeDef->mHash; typeDef->mSignatureHash = nextTypeDef->mSignatureHash; typeDef->mFullHash = nextTypeDef->mFullHash; @@ -2968,22 +2962,22 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) BF_ASSERT(typeDef->mFullNameEx == nextTypeDef->mFullNameEx); - typeDef->mProtection = nextTypeDef->mProtection; + typeDef->mProtection = nextTypeDef->mProtection; BF_ASSERT(typeDef->mTypeCode == nextTypeDef->mTypeCode); typeDef->mTypeCode = nextTypeDef->mTypeCode; - + typeDef->mShow = nextTypeDef->mShow; typeDef->mIsAlwaysInclude = nextTypeDef->mIsAlwaysInclude; - typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard; + typeDef->mIsNoDiscard = nextTypeDef->mIsNoDiscard; typeDef->mIsPartial = nextTypeDef->mIsPartial; typeDef->mIsExplicitPartial = nextTypeDef->mIsExplicitPartial; - //mPartialUsed + //mPartialUsed typeDef->mIsCombinedPartial = nextTypeDef->mIsCombinedPartial; typeDef->mIsDelegate = nextTypeDef->mIsDelegate; typeDef->mIsFunction = nextTypeDef->mIsFunction; typeDef->mIsClosure = nextTypeDef->mIsClosure; - typeDef->mIsAbstract = nextTypeDef->mIsAbstract; + typeDef->mIsAbstract = nextTypeDef->mIsAbstract; typeDef->mIsStatic = nextTypeDef->mIsStatic; typeDef->mHasAppendCtor = nextTypeDef->mHasAppendCtor; typeDef->mHasCEOnCompile = nextTypeDef->mHasCEOnCompile; @@ -2992,20 +2986,20 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) typeDef->mHasExtensionMethods = nextTypeDef->mHasExtensionMethods; typeDef->mHasUsingFields = nextTypeDef->mHasUsingFields; typeDef->mIsOpaque = nextTypeDef->mIsOpaque; - - typeDef->mDupDetectedRevision = nextTypeDef->mDupDetectedRevision; - + + typeDef->mDupDetectedRevision = nextTypeDef->mDupDetectedRevision; + for (auto prevDirectNodes : typeDef->mDirectAllocNodes) delete prevDirectNodes; typeDef->mDirectAllocNodes = nextTypeDef->mDirectAllocNodes; nextTypeDef->mDirectAllocNodes.Clear(); for (auto name : typeDef->mNamespaceSearch) - ReleaseAtomComposite(name); + ReleaseAtomComposite(name); typeDef->mNamespaceSearch = nextTypeDef->mNamespaceSearch; for (auto name : typeDef->mNamespaceSearch) RefAtomComposite(name); - + typeDef->mStaticSearch = nextTypeDef->mStaticSearch; typeDef->mInternalAccessSet = nextTypeDef->mInternalAccessSet; @@ -3017,19 +3011,19 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) if (setDeclaringType) for (auto field : typeDef->mFields) field->mDeclaringType = typeDef; - nextTypeDef->mFields.Clear(); - + nextTypeDef->mFields.Clear(); + for (auto genericParam : typeDef->mGenericParamDefs) delete genericParam; typeDef->mGenericParamDefs.Clear(); - + typeDef->mGenericParamDefs = nextTypeDef->mGenericParamDefs; typeDef->mExternalConstraints = nextTypeDef->mExternalConstraints; - nextTypeDef->mGenericParamDefs.Clear(); + nextTypeDef->mGenericParamDefs.Clear(); + + typeDef->mBaseTypes = nextTypeDef->mBaseTypes; + typeDef->mNestedTypes = nextTypeDef->mNestedTypes; - typeDef->mBaseTypes = nextTypeDef->mBaseTypes; - typeDef->mNestedTypes = nextTypeDef->mNestedTypes; - // If we are a partial then the mOuterType gets set to the combined partial so don't do that here if (!typeDef->mIsCombinedPartial) { @@ -3039,17 +3033,15 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef) nestedType->mOuterType = typeDef; } } - typeDef->mPartials = nextTypeDef->mPartials; + typeDef->mPartials = nextTypeDef->mPartials; typeDef->mMethodSet.Clear(); typeDef->mFieldSet.Clear(); - delete typeDef->mUsingFieldData; - typeDef->mUsingFieldData = NULL; typeDef->mPropertySet.Clear(); delete nextTypeDef; typeDef->mNextRevision = NULL; - typeDef->mDefState = BfTypeDef::DefState_Defined; + typeDef->mDefState = BfTypeDef::DefState_Defined; typeDef->mForceUseNextRevision = false; VerifyTypeDef(typeDef); @@ -3069,32 +3061,33 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co { typeDef = new BfTypeDef(); compositeTypeDef->mNextRevision = typeDef; - + typeDef->mIsCombinedPartial = true; - + typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration; typeDef->mSource = partialTypeDef->mSource; typeDef->mSource->mRefCount++; typeDef->mSystem = partialTypeDef->mSystem; typeDef->mTypeCode = partialTypeDef->mTypeCode; + typeDef->mShow = partialTypeDef->mShow; typeDef->mIsFunction = partialTypeDef->mIsFunction; typeDef->mIsDelegate = partialTypeDef->mIsDelegate; typeDef->mNestDepth = partialTypeDef->mNestDepth; typeDef->mOuterType = partialTypeDef->mOuterType; - typeDef->mNamespace = partialTypeDef->mNamespace; + typeDef->mNamespace = partialTypeDef->mNamespace; typeDef->mName = partialTypeDef->mName; typeDef->mName->Ref(); - TrackName(typeDef); + TrackName(typeDef); typeDef->mNameEx = partialTypeDef->mNameEx; typeDef->mNameEx->Ref(); typeDef->mFullName = partialTypeDef->mFullName; typeDef->mFullNameEx = partialTypeDef->mFullNameEx; - typeDef->mProtection = partialTypeDef->mProtection; + typeDef->mProtection = partialTypeDef->mProtection; typeDef->mIsDelegate = partialTypeDef->mIsDelegate; - typeDef->mIsAbstract = partialTypeDef->mIsAbstract; + typeDef->mIsAbstract = partialTypeDef->mIsAbstract; typeDef->mIsStatic = partialTypeDef->mIsStatic; - typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor; + typeDef->mHasAppendCtor = partialTypeDef->mHasAppendCtor; typeDef->mHasCtorNoBody = partialTypeDef->mHasCtorNoBody; typeDef->mHasExtensionMethods = partialTypeDef->mHasExtensionMethods; typeDef->mHasUsingFields = partialTypeDef->mHasUsingFields; @@ -3109,8 +3102,8 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co typeDef->mGenericParamDefs.push_back(newGeneric); } typeDef->mExternalConstraints = partialTypeDef->mExternalConstraints; - - typeDef->mBaseTypes = partialTypeDef->mBaseTypes; + + typeDef->mBaseTypes = partialTypeDef->mBaseTypes; isFirst = true; @@ -3124,31 +3117,31 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co if (partialTypeDef->mTypeCode != BfTypeCode_Extension) { typeDef->mTypeCode = partialTypeDef->mTypeCode; - typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration; - } + typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration; + } // for (auto& externConstraint : partialTypeDef->mExternalConstraints) // typeDef->mExternalConstraints.Add(externConstraint); - } + } // Merge attributes together - typeDef->mIsAbstract |= partialTypeDef->mIsAbstract; + typeDef->mIsAbstract |= partialTypeDef->mIsAbstract; typeDef->mIsStatic |= partialTypeDef->mIsStatic; - typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor; + typeDef->mHasAppendCtor |= partialTypeDef->mHasAppendCtor; typeDef->mHasCEOnCompile |= partialTypeDef->mHasCEOnCompile; typeDef->mHasExtensionMethods |= partialTypeDef->mHasExtensionMethods; typeDef->mHasUsingFields |= partialTypeDef->mHasUsingFields; - typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods; + typeDef->mHasOverrideMethods |= partialTypeDef->mHasOverrideMethods; for (auto innerType : partialTypeDef->mNestedTypes) { typeDef->mNestedTypes.push_back(innerType); } - + //TODO: We had the CLEAR here, but it caused an issue because when we have to rebuild the composite then // we don't actually have the nested types from the original typeDef if they original typedef wasn't rebuilt //partialTypeDef->mNestedTypes.Clear(); // Only reference from main typedef - + for (auto field : partialTypeDef->mFields) { BfFieldDef* newField = new BfFieldDef(); @@ -3157,17 +3150,15 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co typeDef->mFields.push_back(newField); } typeDef->mFieldSet.Clear(); - delete typeDef->mUsingFieldData; - typeDef->mUsingFieldData = NULL; - + bool hadNoDeclMethod = false; int startMethodIdx = (int)typeDef->mMethods.size(); for (auto method : partialTypeDef->mMethods) { bool ignoreNewMethod = false; - + if (typeDef->mTypeCode == BfTypeCode_Interface) - { + { if (method->mMethodDeclaration == NULL) continue; @@ -3175,8 +3166,8 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co { if (methodDeclaration->mProtectionSpecifier == NULL) method->mProtection = BfProtection_Public; - } - } + } + } BfMethodDef* newMethod = NULL; if (method->mMethodType == BfMethodType_Operator) @@ -3188,11 +3179,12 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co } else { - newMethod = new BfMethodDef(); + newMethod = new BfMethodDef(); *newMethod = *method; } + method->mParamNameMap = NULL; newMethod->mIdx = (int)typeDef->mMethods.size(); - for (int paramIdx = 0; paramIdx < (int)newMethod->mParams.size(); paramIdx++) + for (int paramIdx = 0; paramIdx < (int)newMethod->mParams.size(); paramIdx++) { BfParameterDef* param = newMethod->mParams[paramIdx]; BfParameterDef* newParam = new BfParameterDef(); @@ -3208,7 +3200,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co } if (ignoreNewMethod) newMethod->mMethodType = BfMethodType_Ignore; - typeDef->mMethods.push_back(newMethod); + typeDef->mMethods.push_back(newMethod); } typeDef->mMethodSet.Clear(); @@ -3222,7 +3214,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co typeDef->mProperties.push_back(newProp); } typeDef->mPropertySet.Clear(); - + BF_ASSERT(partialTypeDef->mPartials.empty()); partialTypeDef->mPartialIdx = (int)typeDef->mPartials.size(); typeDef->mPartials.push_back(partialTypeDef); @@ -3254,17 +3246,17 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) _HasMethods allHasMethods[2][2] = { 0 }; auto primaryDef = nextRevision->mPartials[0]; - + //Dictionary projectCount; bool hasCtorNoBody = false; - + bool primaryHasFieldInitializers = false; bool anyHasInitializers = false; // For methods that require chaining, make sure the primary def has a definition for (auto partialTypeDef : nextRevision->mPartials) - { + { bool isExtension = partialTypeDef->mTypeDeclaration != nextRevision->mTypeDeclaration; if (!isExtension) primaryDef = partialTypeDef; @@ -3297,22 +3289,24 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) for (auto fieldDef : partialTypeDef->mFields) { - if (!fieldDef->mIsStatic) + if (!fieldDef->mIsStatic) { if (auto fieldDeclaration = BfNodeDynCast(fieldDef->mFieldDeclaration)) - if (fieldDeclaration->mInitializer != NULL) + if (fieldDeclaration->mInitializer != NULL) hasInitializers = true; if (auto paramDeclaration = BfNodeDynCast(fieldDef->mFieldDeclaration)) if (paramDeclaration->mInitializer != NULL) hasInitializers = true; + if (fieldDef->mIsAppend) + hasInitializers = true; } } if (hasInitializers) { - anyHasInitializers = true; + anyHasInitializers = true; if (!isExtension) - primaryHasFieldInitializers = true; + primaryHasFieldInitializers = true; nextRevision->mHasCtorNoBody = true; auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, ""); methodDef->mDeclaringType = partialTypeDef; @@ -3330,11 +3324,11 @@ void BfSystem::FinishCompositePartial(BfTypeDef* compositeTypeDef) if ((allHasMethods[0][0].mCtor == 0) && (allHasMethods[1][0].mCtor > 1)) { - auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Ctor, (allHasMethods[1][0].mCtorPublic > 0) ? BfProtection_Public : BfProtection_Protected, false, ""); + auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_Ctor, (allHasMethods[1][0].mCtorPublic > 0) ? BfProtection_Public : BfProtection_Protected, false, ""); methodDef->mDeclaringType = primaryDef; methodDef->mIsMutating = true; } - + // if (!hasCtorNoBody) // { // auto methodDef = BfDefBuilder::AddMethod(nextRevision, BfMethodType_CtorNoBody, BfProtection_Protected, false, ""); @@ -3399,7 +3393,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) BfLogSys(this, "CopyTypeDef %p from %p Hash: %d\n", typeDef, fromTypeDef, fromTypeDef->mHash); for (auto fromMethodDef : fromTypeDef->mMethods) - { + { BfMethodDef* methodDef; if (fromMethodDef->mIsOperator) { @@ -3413,6 +3407,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) methodDef = new BfMethodDef(); *methodDef = *fromMethodDef; } + fromMethodDef->mParamNameMap = NULL; if (methodDef->mDeclaringType == fromTypeDef) methodDef->mDeclaringType = typeDef; @@ -3421,7 +3416,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) { auto fromParamDef = fromMethodDef->mParams[paramIdx]; BfParameterDef* paramDef = new BfParameterDef(); - *paramDef = *fromParamDef; + *paramDef = *fromParamDef; methodDef->mParams[paramIdx] = paramDef; } @@ -3446,13 +3441,13 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) } for (auto fromPropDef : fromTypeDef->mProperties) - { - BfPropertyDef* propDef = new BfPropertyDef(); + { + BfPropertyDef* propDef = new BfPropertyDef(); *propDef = *fromPropDef; if (propDef->mDeclaringType == fromTypeDef) propDef->mDeclaringType = typeDef; - for (auto& methodDef : propDef->mMethods) - methodDef = typeDef->mMethods[methodDef->mIdx]; + for (auto& methodDef : propDef->mMethods) + methodDef = typeDef->mMethods[methodDef->mIdx]; propDef->mNextWithSameName = NULL; typeDef->mProperties.Add(propDef); } @@ -3466,7 +3461,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) fieldDef->mNextWithSameName = NULL; typeDef->mFields.Add(fieldDef); } - + typeDef->mSystem = fromTypeDef->mSystem; typeDef->mProject = fromTypeDef->mProject; typeDef->mPartialIdx = fromTypeDef->mPartialIdx; @@ -3478,8 +3473,8 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) typeDef->mNestDepth = fromTypeDef->mNestDepth; typeDef->mOuterType = fromTypeDef->mOuterType; - //typeDef->mOuterType = fromTypeDef->mOuterType; - typeDef->mNamespace = fromTypeDef->mNamespace; + //typeDef->mOuterType = fromTypeDef->mOuterType; + typeDef->mNamespace = fromTypeDef->mNamespace; typeDef->mName = fromTypeDef->mName; if (typeDef->mName != mEmptyAtom) @@ -3488,7 +3483,7 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) //typeDef->mName = fromTypeDef->mName; typeDef->mNameEx = fromTypeDef->mNameEx; if (typeDef->mNameEx != NULL) - typeDef->mNameEx->mRefCount++; + typeDef->mNameEx->mRefCount++; //typeDef->mNameEx = fromTypeDef->mNameEx; typeDef->mFullName = fromTypeDef->mFullName; @@ -3498,14 +3493,12 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) typeDef->mProtection = fromTypeDef->mProtection; typeDef->mTypeCode = fromTypeDef->mTypeCode; - - typeDef->mTypeCode = fromTypeDef->mTypeCode; - + typeDef->mShow = fromTypeDef->mShow; typeDef->mIsAlwaysInclude = fromTypeDef->mIsAlwaysInclude; typeDef->mIsNoDiscard = fromTypeDef->mIsNoDiscard; typeDef->mIsPartial = fromTypeDef->mIsPartial; typeDef->mIsExplicitPartial = fromTypeDef->mIsExplicitPartial; - //mPartialUsed + //mPartialUsed typeDef->mIsCombinedPartial = fromTypeDef->mIsCombinedPartial; typeDef->mIsDelegate = fromTypeDef->mIsDelegate; typeDef->mIsFunction = fromTypeDef->mIsFunction; @@ -3521,31 +3514,31 @@ void BfSystem::CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* fromTypeDef) typeDef->mIsOpaque = fromTypeDef->mIsOpaque; typeDef->mDupDetectedRevision = fromTypeDef->mDupDetectedRevision; - + typeDef->mDirectAllocNodes = fromTypeDef->mDirectAllocNodes; fromTypeDef->mDirectAllocNodes.Clear(); - + typeDef->mNamespaceSearch = fromTypeDef->mNamespaceSearch; for (auto name : typeDef->mNamespaceSearch) RefAtomComposite(name); typeDef->mStaticSearch = fromTypeDef->mStaticSearch; typeDef->mInternalAccessSet = fromTypeDef->mInternalAccessSet; - + for (auto fromGenericParamDef : fromTypeDef->mGenericParamDefs) { BfGenericParamDef* genericParamDef = new BfGenericParamDef(); *genericParamDef = *fromGenericParamDef; typeDef->mGenericParamDefs.Add(genericParamDef); - } + } - typeDef->mExternalConstraints = fromTypeDef->mExternalConstraints; + typeDef->mExternalConstraints = fromTypeDef->mExternalConstraints; typeDef->mBaseTypes = fromTypeDef->mBaseTypes; typeDef->mNestedTypes = fromTypeDef->mNestedTypes; - + typeDef->mPartials = fromTypeDef->mPartials; - + VerifyTypeDef(typeDef); } @@ -3564,7 +3557,7 @@ void BfSystem::UpdateEmittedTypeDef(BfTypeDef* typeDef) typeDef->mOuterType = fromTypeDef->mOuterType; for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) - { + { auto methodDef = typeDef->mMethods[methodIdx]; if (methodIdx >= fromTypeDef->mMethods.mSize) { @@ -3606,7 +3599,7 @@ void BfSystem::UpdateEmittedTypeDef(BfTypeDef* typeDef) BfGenericParamDef* genericParam = new BfGenericParamDef(); *genericParam = *fromGenericParam; methodDef->mGenericParams[genericParamIdx] = genericParam; - } + } } typeDef->mOperators.Clear(); @@ -3644,7 +3637,7 @@ void BfSystem::UpdateEmittedTypeDef(BfTypeDef* typeDef) BF_ASSERT(propertyDef->mDeclaringType != typeDef); auto fromPropertyDef = fromTypeDef->mProperties[propertyIdx]; propertyDef->mDeclaringType = fromPropertyDef->mDeclaringType; - } + } typeDef->mGenericParamDefs.Clear(); for (auto fromGenericParamDef : fromTypeDef->mGenericParamDefs) @@ -3686,7 +3679,7 @@ BfTypeDef* BfSystem::GetOuterTypeNonPartial(BfTypeDef* typeDef) if ((checkType == NULL) || (!checkType->mIsPartial)) return checkType; - return GetCombinedPartial(checkType); + return GetCombinedPartial(checkType); } int BfSystem::GetGenericParamIdx(const Array& genericParams, const StringImpl& name) @@ -3716,7 +3709,7 @@ void BfSystem::SummarizeYieldSection() } void BfSystem::CheckLockYield() -{ +{ if (mYieldDisallowCount != 0) return; @@ -3730,7 +3723,7 @@ void BfSystem::CheckLockYield() int mySystemLockPri = mCurSystemLockPri; BF_ASSERT(mSystemLock.mLockCount == 1); mSystemLock.Unlock(); - // Wait for the other thread to actually acquire the lock. This only spins between the time + // Wait for the other thread to actually acquire the lock. This only spins between the time // we get a NotifyWillRequestLock and when that thread actually does the Lock while (mPendingSystemLockPri != -1) { @@ -3747,7 +3740,7 @@ void BfSystem::NotifyWillRequestLock(int priority) } void BfSystem::Lock(int priority) -{ +{ #ifdef _DEBUG if (priority > 0) { @@ -3777,7 +3770,7 @@ void BfSystem::Unlock() void BfSystem::AssertWeHaveLock() { -#ifdef BF_PLATFORM_WINDOWS +#ifdef BF_PLATFORM_WINDOWS BF_ASSERT_REL(((CRITICAL_SECTION*)mSystemLock.mCritSect)->OwningThread == (HANDLE)(uintptr)::GetCurrentThreadId()); #endif } @@ -3810,24 +3803,24 @@ void BfSystem::RemoveOldParsers() { mDataLock.Lock(); - // We can't be allowed to delete old parsers if the new typedefs haven't been + // We can't be allowed to delete old parsers if the new typedefs haven't been // injected yet by the compiler if (mNeedsTypesHandledByCompiler) { mDataLock.Unlock(); return; } - + RemoveDeletedParsers(); - + for (int i = 0; i < (int)mParsers.size(); i++) { auto bfParser = mParsers[i]; - + bool wantsDelete = false; - + if (bfParser->mRefCount == 0) - { + { if ((bfParser->mNextRevision != NULL) || (bfParser->mAwaitingDelete)) { if (bfParser->mNextRevision != NULL) @@ -3842,19 +3835,19 @@ void BfSystem::RemoveOldParsers() mDataLock.Unlock(); delete bfParser; - mDataLock.Lock(); + mDataLock.Lock(); } - } + } } mDataLock.Unlock(); } void BfSystem::RemoveOldData() -{ +{ { AutoCrit autoCrit(mDataLock); - for (int i = 0; i < (int)mTypeDefDeleteQueue.size(); i++) + for (int i = 0; i < (int)mTypeDefDeleteQueue.size(); i++) { auto typeDef = mTypeDefDeleteQueue[i]; mTypeDefDeleteQueue[i] = NULL; @@ -3862,7 +3855,7 @@ void BfSystem::RemoveOldData() delete typeDef; } mTypeDefDeleteQueue.Clear(); - + if (!mProjectDeleteQueue.IsEmpty()) { for (auto project : mProjectDeleteQueue) @@ -3886,7 +3879,7 @@ void BfSystem::RemoveOldData() projectIdx--; } } - } + } } RemoveOldParsers(); @@ -3937,7 +3930,7 @@ BfTypeOptions* BfSystem::GetTypeOptions(int optionsIdx) if (optionsIdx < 0) return NULL; if (optionsIdx < mTypeOptions.size()) - return &mTypeOptions[optionsIdx]; + return &mTypeOptions[optionsIdx]; return &mMergedTypeOptions[optionsIdx - mTypeOptions.size()]; } @@ -3979,12 +3972,12 @@ BF_EXPORT void BF_CALLTYPE BfSystem_Delete(BfSystem* bfSystem) } BF_EXPORT void BF_CALLTYPE BfSystem_CheckLock(BfSystem* bfSystem) -{ +{ BF_ASSERT(bfSystem->mSystemLock.mLockCount == 0); } BF_EXPORT void BF_CALLTYPE BfResolvePassData_Delete(BfResolvePassData* resolvePassData) -{ +{ delete resolvePassData->mAutoComplete; for (auto tempType : resolvePassData->mAutoCompleteTempTypes) delete tempType; @@ -4010,7 +4003,7 @@ BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetMethodGenericParamIdx(BfResolveP } BF_EXPORT void BF_CALLTYPE BfResolvePassData_SetSymbolReferenceTypeDef(BfResolvePassData* resolvePassData, const char* replaceTypeDef) -{ +{ resolvePassData->mQueuedReplaceTypeDef = replaceTypeDef; resolvePassData->mGetSymbolReferenceKind = BfGetSymbolReferenceKind_Type; } @@ -4063,6 +4056,10 @@ BF_EXPORT void* BfResolvePassData_GetEmitEmbedData(BfResolvePassData* resolvePas return NULL; *revision = emitEmbedEntry->mRevision; *charCount = emitEmbedEntry->mParser->mSrcLength; + + auto emitParser = emitEmbedEntry->mParser; + emitParser->mSourceClassifier->FlushDeferredNodes(); + return emitEmbedEntry->mParser->mSourceClassifier->mCharData; } @@ -4072,7 +4069,7 @@ BF_EXPORT bool BfResolvePassData_GetHadEmits(BfResolvePassData* resolvePassData) } BF_EXPORT BfParser* BF_CALLTYPE BfSystem_CreateParser(BfSystem* bfSystem, BfProject* bfProject) -{ +{ return bfSystem->CreateParser(bfProject); } @@ -4090,7 +4087,7 @@ BF_EXPORT void BF_CALLTYPE BfSystem_DeleteParser(BfSystem* bfSystem, BfParser* b typeDef->mDefState = BfTypeDef::DefState_Deleted; } } - //bfSystem->mParserDeleteQueue.push_back(bfParser); + //bfSystem->mParserDeleteQueue.push_back(bfParser); } BF_EXPORT BfCompiler* BF_CALLTYPE BfSystem_CreateCompiler(BfSystem* bfSystem, bool isResolveOnly) @@ -4137,7 +4134,7 @@ BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bf } if (outLine != NULL) - { + { auto parserData = bfError->mSource->ToParserData(); if (parserData != NULL) { @@ -4169,7 +4166,7 @@ BF_EXPORT const char* BfPassInstance_Error_GetMoreInfoData(BfPassInstance* bfPas if (bfPassInstance->mSourceFileNameMap.TryGetValue(moreInfo->mSource, &srcFileName)) { fileName = (char*)srcFileName->c_str(); - } + } } if (moreInfo->mLocation != NULL) @@ -4248,27 +4245,26 @@ BF_EXPORT void BF_CALLTYPE BfSystem_Update(BfSystem* bfSystem) BF_EXPORT void BF_CALLTYPE BfSystem_ReportMemory(BfSystem* bfSystem) { AutoCrit crit(bfSystem->mDataLock); - + MemReporter memReporter; - - + for (auto compiler : bfSystem->mCompilers) { AutoMemReporter autoMemReporter(&memReporter, "Compiler"); compiler->ReportMemory(&memReporter); - } - + } + for (auto typeDef : bfSystem->mTypeDefs) { AutoMemReporter autoMemReporter(&memReporter, "TypeDef"); typeDef->ReportMemory(&memReporter); - } + } for (auto parser : bfSystem->mParsers) { AutoMemReporter autoMemReporter(&memReporter, "Parsers"); parser->ReportMemory(&memReporter); - } + } memReporter.Report(); } @@ -4279,7 +4275,7 @@ BF_EXPORT void BF_CALLTYPE BfSystem_StartTiming() } BF_EXPORT void BF_CALLTYPE BfSystem_PerfZoneStart(const char* name) -{ +{ gPerfManager->ZoneStart(name); } @@ -4298,7 +4294,6 @@ BF_EXPORT void BF_CALLTYPE BfSystem_DbgPrintTimings() gPerfManager->DbgPrint(); } - BF_EXPORT const char* BF_CALLTYPE BfSystem_GetNamespaceSearch(BfSystem* bfSystem, const char* typeName, BfProject* project) { auto typeDef = bfSystem->FindTypeDef(typeName, project); @@ -4325,7 +4320,7 @@ BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, cons bfProject->mDirectory = projectDir; bfProject->mSystem = bfSystem; bfProject->mIdx = (int)bfSystem->mProjects.size(); - bfSystem->mProjects.push_back(bfProject); + bfSystem->mProjects.push_back(bfProject); String safeProjectName = projectName; for (auto& c : safeProjectName) @@ -4347,7 +4342,7 @@ BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, cons break; tryName = safeProjectName + StrFormat("_%d", i); } - bfProject->mSafeName = tryName; + bfProject->mSafeName = tryName; BfLogSys(bfSystem, "Creating project %p\n", bfProject); return bfProject; @@ -4402,11 +4397,11 @@ BF_EXPORT void BF_CALLTYPE BfSystem_AddTypeOptions(BfSystem* bfSystem, char* fil if ((typeOptions.mTypeFilters.IsEmpty()) && (typeOptions.mAttributeFilters.IsEmpty())) return; typeOptions.mSIMDSetting = simdSetting; - typeOptions.mOptimizationLevel = optimizationLevel; + typeOptions.mOptimizationLevel = optimizationLevel; typeOptions.mEmitDebugInfo = emitDebugInfo; typeOptions.mAndFlags = (BfOptionFlags)andFlags; typeOptions.mOrFlags = (BfOptionFlags)orFlags; - typeOptions.mAllocStackTraceDepth = allocStackTraceDepth; + typeOptions.mAllocStackTraceDepth = allocStackTraceDepth; Array methodReflectFilters; Array methodReflectAttributeFilters; @@ -4415,16 +4410,16 @@ BF_EXPORT void BF_CALLTYPE BfSystem_AddTypeOptions(BfSystem* bfSystem, char* fil // When we have method filters we want to apply those to the methods for when we merge options if ((!methodReflectFilters.IsEmpty()) || (!methodReflectAttributeFilters.IsEmpty())) { - for (auto& filter : methodReflectFilters) + for (auto& filter : methodReflectFilters) typeOptions.mReflectMethodFilters.Add({ filter, (BfOptionFlags)andFlags, (BfOptionFlags)orFlags }); for (auto& filter : methodReflectAttributeFilters) typeOptions.mReflectMethodAttributeFilters.Add({ filter, (BfOptionFlags)andFlags, (BfOptionFlags)orFlags }); - + typeOptions.mAndFlags = (BfOptionFlags)(typeOptions.mAndFlags | BfOptionFlags_Reflect_MethodMask); typeOptions.mOrFlags = (BfOptionFlags)(typeOptions.mOrFlags & ~BfOptionFlags_Reflect_MethodMask); } - bfSystem->mTypeOptions.push_back(typeOptions); + bfSystem->mTypeOptions.push_back(typeOptions); } BF_EXPORT void BF_CALLTYPE BfProject_Delete(BfProject* bfProject) @@ -4433,11 +4428,11 @@ BF_EXPORT void BF_CALLTYPE BfProject_Delete(BfProject* bfProject) AutoCrit autoCrit(bfSystem->mSystemLock); bfProject->mDeleteStage = BfProject::DeleteStage_Queued; - bfSystem->mProjectDeleteQueue.push_back(bfProject); + bfSystem->mProjectDeleteQueue.push_back(bfProject); bfSystem->mUsedSafeProjectNames.Remove(bfProject->mSafeName); - BF_ASSERT(bfSystem->mProjects[bfProject->mIdx] == bfProject); - bool wasRemoved = bfSystem->mProjects.Remove(bfProject); + BF_ASSERT(bfSystem->mProjects[bfProject->mIdx] == bfProject); + bool wasRemoved = bfSystem->mProjects.Remove(bfProject); BF_ASSERT(wasRemoved); for (int i = bfProject->mIdx; i < (int)bfSystem->mProjects.size(); i++) @@ -4445,7 +4440,7 @@ BF_EXPORT void BF_CALLTYPE BfProject_Delete(BfProject* bfProject) bfProject->mIdx = -1; -/*#ifdef _DEBUG +/*#ifdef _DEBUG { AutoCrit autoCrit(bfSystem->mSystemLock); for (auto typeDefKV : bfSystem->mTypeDefs) @@ -4470,7 +4465,7 @@ BF_EXPORT void BF_CALLTYPE BfProject_AddDependency(BfProject* bfProject, BfProje } BF_EXPORT void BF_CALLTYPE BfProject_SetDisabled(BfProject* bfProject, bool disabled) -{ +{ bfProject->mDisabled = disabled; } @@ -4478,8 +4473,8 @@ BF_EXPORT void BF_CALLTYPE BfProject_SetOptions(BfProject* bfProject, int target int optLevel, int ltoType, int relocType, int picLevel, BfProjectFlags flags) { bfProject->mTargetType = (BfTargetType)targetType; - bfProject->mStartupObject = startupObject; - + bfProject->mStartupObject = startupObject; + BfCodeGenOptions codeGenOptions; codeGenOptions.mOptLevel = (BfOptLevel)optLevel; codeGenOptions.mLTOType = (BfLTOType)ltoType; @@ -4488,7 +4483,7 @@ BF_EXPORT void BF_CALLTYPE BfProject_SetOptions(BfProject* bfProject, int target codeGenOptions.mMergeFunctions = (flags & BfProjectFlags_MergeFunctions) != 0; codeGenOptions.mLoadCombine = (flags & BfProjectFlags_CombineLoads) != 0; codeGenOptions.mLoopVectorize = (flags & BfProjectFlags_VectorizeLoops) != 0; - codeGenOptions.mSLPVectorize = (flags & BfProjectFlags_VectorizeSLP) != 0; + codeGenOptions.mSLPVectorize = (flags & BfProjectFlags_VectorizeSLP) != 0; if ((flags & BfProjectFlags_AsmOutput) != 0) { static bool setLLVMAsmKind = false; @@ -4500,15 +4495,15 @@ BF_EXPORT void BF_CALLTYPE BfProject_SetOptions(BfProject* bfProject, int target if (!setLLVMAsmKind) { setLLVMAsmKind = true; - BfIRCodeGen::SetAsmKind(codeGenOptions.mAsmKind); + BfIRCodeGen::SetAsmKind(codeGenOptions.mAsmKind); } - } + } bfProject->mCodeGenOptions = codeGenOptions; bfProject->mSingleModule = (flags & BfProjectFlags_SingleModule) != 0; bfProject->mAlwaysIncludeAll = (flags & BfProjectFlags_AlwaysIncludeAll) != 0; bfProject->mPreprocessorMacros.Clear(); - + int startIdx = 0; int idx = 0; while (true) @@ -4547,7 +4542,7 @@ public: std::map mReplaceMap; public: - + String GetTypeName(const StringImpl& typeName) { if (typeName == "long") @@ -4588,8 +4583,8 @@ public: void Visit(BfTypeReference* typeRef) { - String typeName = typeRef->ToString(); - String wantTypeName = GetTypeName(typeName); + String typeName = typeRef->ToString(); + String wantTypeName = GetTypeName(typeName); if (typeName != wantTypeName) { ReplaceRecord replaceRecord = { typeRef, wantTypeName }; @@ -4633,7 +4628,7 @@ public: { SetAndRestoreValue prevInMethod(mInMethod, true); BfElementVisitor::Visit(methodDecl); - } + } void FixStr(String& source) { @@ -4659,10 +4654,10 @@ public: String origFileName = parser->mFileName; origFileName.Insert(3, "Orig_"); - + String source; source.Insert(0, parser->mSrc, parser->mSrcLength); - + String origSource = source; FixStr(origSource); RecursiveCreateDirectory(GetFileDir(origFileName)); @@ -4670,7 +4665,7 @@ public: fwrite(origSource.c_str(), 1, (int)origSource.length(), fp); fclose(fp); - VisitMembers(parser->mRootNode); + VisitMembers(parser->mRootNode); int ofs = 0; for (auto& pair : mReplaceMap) @@ -4702,6 +4697,4 @@ BF_EXPORT void BF_CALLTYPE BfSystem_Log(BfSystem* bfSystem, char* str) { BfLogSys(bfSystem, str); BfLogSys(bfSystem, "\n"); -} - - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 8d9465be..d8706366 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -56,7 +56,7 @@ public: uint32 mAtomUpdateIdx; bool mIsSystemType; Dictionary mPrevNamesMap; - + public: ~BfAtom(); const StringView& ToString() @@ -68,7 +68,7 @@ public: str += mString; } - void Ref(); + void Ref(); }; class BfAtomComposite @@ -80,15 +80,15 @@ public: bool mOwns; public: - BfAtomComposite(); + BfAtomComposite(); BfAtomComposite(BfAtomComposite&& rhs); BfAtomComposite(const BfAtomComposite& rhs); - BfAtomComposite(BfAtom* atom); + BfAtomComposite(BfAtom* atom); BfAtomComposite(const BfAtomComposite& left, const BfAtomComposite& right); BfAtomComposite(const BfAtomComposite& left, BfAtom* right); ~BfAtomComposite(); - - void Set(const BfAtomComposite& left, const BfAtomComposite& right); + + void Set(const BfAtomComposite& left, const BfAtomComposite& right); void Set(BfAtom** atomsA, int countA, BfAtom** atomsB, int countB); BfAtomComposite& operator=(const BfAtomComposite& rhs); bool operator==(const BfAtomComposite& other) const; @@ -102,7 +102,7 @@ public: bool EndsWith(const BfAtomComposite& other) const; BfAtomComposite GetSub(int start, int len) const; void Reference(const BfAtomComposite& other); - + uint32 GetAtomUpdateIdx(); }; @@ -138,17 +138,17 @@ class BfSizedAtomComposite : public BfAtomComposite public: BfAtom* mInitialAlloc[8]; - BfSizedAtomComposite(); - ~BfSizedAtomComposite(); + BfSizedAtomComposite(); + ~BfSizedAtomComposite(); }; struct BfAtomCompositeHash { size_t operator()(const BfAtomComposite& composite) const { - int curHash = 0; - for (int i = 0; i < (int)composite.mSize; i++) - curHash = ((curHash ^ (int)(intptr)composite.mParts[i]->mHash) << 5) - curHash; + int curHash = 0; + for (int i = 0; i < (int)composite.mSize; i++) + curHash = ((curHash ^ (int)(intptr)composite.mParts[i]->mHash) << 5) - curHash; return curHash; } }; @@ -179,7 +179,7 @@ enum BfCompilerOptionFlags BfCompilerOptionFlag_EmitLineInfo = 2, BfCompilerOptionFlag_WriteIR = 4, BfCompilerOptionFlag_GenerateOBJ = 8, - BfCompilerOptionFlag_GenerateBitcode = 0x10, + BfCompilerOptionFlag_GenerateBitcode = 0x10, BfCompilerOptionFlag_ClearLocalVars = 0x20, BfCompilerOptionFlag_RuntimeChecks = 0x40, BfCompilerOptionFlag_EmitDynamicCastCheck = 0x80, @@ -190,7 +190,7 @@ enum BfCompilerOptionFlags BfCompilerOptionFlag_EnableSideStack = 0x1000, BfCompilerOptionFlag_EnableHotSwapping = 0x2000, BfCompilerOptionFlag_IncrementalBuild = 0x4000, - BfCompilerOptionFlag_DebugAlloc = 0x8000, + BfCompilerOptionFlag_DebugAlloc = 0x8000, BfCompilerOptionFlag_OmitDebugHelpers = 0x10000, BfCompilerOptionFlag_NoFramePointerElim = 0x20000, BfCompilerOptionFlag_ArithmeticChecks = 0x40000, @@ -234,7 +234,7 @@ enum BfMethodFlags BfMethodFlags_FastCall = 0x2000, BfMethodFlags_ThisCall = 0x3000, BfMethodFlags_Mutating = 0x4000, - BfMethodFlags_Constructor = 0x8000 + BfMethodFlags_Constructor = 0x8000 }; enum BfObjectFlags : uint8 @@ -344,7 +344,7 @@ enum BfLTOType }; enum BfCFLAAType -{ +{ BfCFLAAType_None, BfCFLAAType_Steensgaard, BfCFLAAType_Andersen, @@ -354,11 +354,11 @@ enum BfCFLAAType enum BfRelocType { BfRelocType_NotSet, - BfRelocType_Static, - BfRelocType_PIC, + BfRelocType_Static, + BfRelocType_PIC, BfRelocType_DynamicNoPIC, BfRelocType_ROPI, - BfRelocType_RWPI, + BfRelocType_RWPI, BfRelocType_ROPI_RWPI }; @@ -366,32 +366,32 @@ enum BfPICLevel { BfPICLevel_NotSet, BfPICLevel_Not, - BfPICLevel_Small, + BfPICLevel_Small, BfPICLevel_Big }; struct BfCodeGenOptions -{ +{ bool mIsHotCompile; bool mWriteObj; bool mWriteBitcode; BfAsmKind mAsmKind; bool mWriteToLib; - bool mWriteLLVMIR; + bool mWriteLLVMIR; int16 mVirtualMethodOfs; int16 mDynSlotOfs; BfRelocType mRelocType; BfPICLevel mPICLevel; - BfSIMDSetting mSIMDSetting; + BfSIMDSetting mSIMDSetting; BfOptLevel mOptLevel; BfLTOType mLTOType; int mSizeLevel; BfCFLAAType mUseCFLAA; bool mUseNewSROA; - + bool mDisableTailCalls; bool mDisableUnitAtATime; bool mDisableUnrollLoops; @@ -410,7 +410,7 @@ struct BfCodeGenOptions bool mUseGVNAfterVectorization; bool mEnableLoopInterchange; bool mEnableLoopLoadElim; - bool mExtraVectorizerPasses; + bool mExtraVectorizerPasses; bool mEnableEarlyCSEMemSSA; bool mEnableGVNHoist; bool mEnableGVNSink; @@ -427,8 +427,8 @@ struct BfCodeGenOptions Val128 mHash; BfCodeGenOptions() - { - mIsHotCompile = false; + { + mIsHotCompile = false; mWriteObj = true; mWriteBitcode = false; mAsmKind = BfAsmKind_None; @@ -436,7 +436,7 @@ struct BfCodeGenOptions mWriteLLVMIR = false; mVirtualMethodOfs = 0; mDynSlotOfs = 0; - + mRelocType = BfRelocType_NotSet; mPICLevel = BfPICLevel_NotSet; mSIMDSetting = BfSIMDSetting_None; @@ -445,7 +445,7 @@ struct BfCodeGenOptions mSizeLevel = 0; mUseCFLAA = BfCFLAAType_None; mUseNewSROA = false; - + mDisableTailCalls = false; mDisableUnitAtATime = false; mDisableUnrollLoops = false; @@ -480,7 +480,7 @@ struct BfCodeGenOptions } void GenerateHash() - { + { HashContext hashCtx; hashCtx.Mixin(mWriteObj); @@ -524,7 +524,6 @@ struct BfCodeGenOptions } }; - enum BfParamKind : uint8 { BfParamKind_Normal, @@ -536,11 +535,18 @@ enum BfParamKind : uint8 BfParamKind_VarArgs }; +enum BfShow : uint8 +{ + BfShow_Show, + BfShow_HideIndirect, + BfShow_Hide +}; + class BfParameterDef { public: String mName; - BfTypeReference* mTypeRef; + BfTypeReference* mTypeRef; BfParameterDeclaration* mParamDeclaration; int mMethodGenericParamIdx; BfParamKind mParamKind; @@ -552,7 +558,7 @@ public: mTypeRef = NULL; mMethodGenericParamIdx = -1; mParamKind = BfParamKind_Normal; - mParamDeclaration = NULL; + mParamDeclaration = NULL; mNamePrefixCount = 0; } void SetName(BfAstNode* nameNode); @@ -570,9 +576,9 @@ public: BfProtection mProtection; uint8 mNamePrefixCount; // Number of @'s bool mIsStatic; - bool mIsNoShow; + BfShow mShow; bool mIsReadOnly; - bool mHasMultiDefs; + bool mHasMultiDefs; public: BfMemberDef() @@ -581,7 +587,7 @@ public: mProtection = BfProtection_Public; mNamePrefixCount = 0; mIsStatic = false; - mIsNoShow = false; + mShow = BfShow_Show; mIsReadOnly = false; mHasMultiDefs = false; } @@ -596,28 +602,30 @@ public: class BfFieldDef : public BfMemberDef { public: - int mIdx; - bool mIsConst; // Note: Consts are also all considered Static + int mIdx; + bool mIsConst; // Note: Consts are also all considered Static BfTypeReference* mTypeRef; BfProtection mUsingProtection; bool mIsInline; bool mIsVolatile; - bool mIsExtern; - bool mIsProperty; + bool mIsExtern; + bool mIsAppend; + bool mIsProperty; BfAstNode* mFieldDeclaration; // It may seem that fields and properties don't need a 'mNextWithSameName', but with extensions it's possible - // to have two libraries which each add a field to a type with the same name + // to have two libraries which each add a field to a type with the same name BfFieldDef* mNextWithSameName; public: BfFieldDef() { mIdx = 0; - mIsConst = false; + mIsConst = false; mTypeRef = NULL; mUsingProtection = BfProtection_Hidden; mIsInline = false; mIsExtern = false; + mIsAppend = false; mIsVolatile = false; mIsProperty = false; mFieldDeclaration = NULL; @@ -677,7 +685,7 @@ public: return paramDecl->mInitializer; return NULL; } - + BfAstNode* GetNameNode() { if (auto fieldDecl = GetFieldDeclaration()) @@ -690,18 +698,18 @@ public: class BfPropertyDef : public BfFieldDef { -public: - Array mMethods; +public: + Array mMethods; BfPropertyDef* mNextWithSameName; public: BfPropertyDef() - { + { mNextWithSameName = NULL; - } + } bool IsVirtual(); - bool HasExplicitInterface(); + bool HasExplicitInterface(); bool IsExpressionBodied(); BfAstNode* GetRefNode(); }; @@ -713,7 +721,7 @@ enum BfGenericParamFlags : uint16 BfGenericParamFlag_Struct = 2, BfGenericParamFlag_StructPtr = 4, BfGenericParamFlag_Enum = 8, - BfGenericParamFlag_Interface = 0x10, + BfGenericParamFlag_Interface = 0x10, BfGenericParamFlag_Concrete = 0x20, BfGenericParamFlag_New = 0x40, BfGenericParamFlag_Delete = 0x80, @@ -759,10 +767,10 @@ public: class BfGenericParamDef : public BfConstraintDef { -public: - String mName; +public: + String mName; Array mNameNodes; // 0 is always the def name - + bool operator==(const BfGenericParamDef& other) const { if (mName != other.mName) @@ -779,7 +787,7 @@ public: class BfExternalConstraintDef : public BfConstraintDef { public: - BfTypeReference* mTypeRef; + BfTypeReference* mTypeRef; }; // CTOR is split into two for Objects - Ctor clears and sets up VData, Ctor_Body executes ctor body code @@ -805,7 +813,7 @@ enum BfCallingConvention : uint8 BfCallingConvention_Unspecified, BfCallingConvention_Cdecl, BfCallingConvention_Stdcall, - BfCallingConvention_Fastcall, + BfCallingConvention_Fastcall, }; #define BF_METHODNAME_MARKMEMBERS "GCMarkMembers" @@ -857,15 +865,16 @@ enum BfComptimeFlags : int8 class BfMethodDef : public BfMemberDef { -public: - BfAstNode* mMethodDeclaration; - BfAstNode* mBody; +public: + BfAstNode* mMethodDeclaration; + BfAstNode* mBody; BfTypeReference* mExplicitInterface; BfTypeReference* mReturnTypeRef; Array mParams; Array mGenericParams; Array mExternalConstraints; + Dictionary* mParamNameMap; BfMethodDef* mNextWithSameName; Val128 mFullHash; @@ -883,7 +892,7 @@ public: bool mWantsBody; bool mCLink; bool mHasAppend; - bool mAlwaysInline; + bool mAlwaysInline; bool mIsNoReturn; bool mIsMutating; bool mIsNoSplat; @@ -891,14 +900,14 @@ public: bool mIsSkipCall; bool mHasComptime; bool mIsOperator; - bool mIsExtern; + bool mIsExtern; bool mIsNoDiscard; bool mHasExplicitThis; bool mAddedAfterEmit; BfCommutableKind mCommutableKind; BfCheckedKind mCheckedKind; - BfImportKind mImportKind; - BfCallingConvention mCallingConvention; + BfImportKind mImportKind; + BfCallingConvention mCallingConvention; public: BfMethodDef() @@ -913,7 +922,7 @@ public: mIsStatic = false; mIsNew = false; mIsPartial = false; - mCLink = false; + mCLink = false; mIsNoReturn = false; mIsMutating = false; mIsNoSplat = false; @@ -927,8 +936,8 @@ public: mAddedAfterEmit = false; mBody = NULL; mExplicitInterface = NULL; - mReturnTypeRef = NULL; - mMethodDeclaration = NULL; + mReturnTypeRef = NULL; + mMethodDeclaration = NULL; mCodeChanged = false; mWantsBody = true; mCommutableKind = BfCommutableKind_None; @@ -937,7 +946,8 @@ public: mMethodType = BfMethodType_Normal; mCallingConvention = BfCallingConvention_Unspecified; mHasAppend = false; - mAlwaysInline = false; + mAlwaysInline = false; + mParamNameMap = NULL; mNextWithSameName = NULL; } @@ -947,23 +957,24 @@ public: bool HasNoThisSplat() { return mIsMutating || mIsNoSplat; } void Reset(); void FreeMembers(); - BfMethodDeclaration* GetMethodDeclaration(); + BfMethodDeclaration* GetMethodDeclaration(); BfPropertyMethodDeclaration* GetPropertyMethodDeclaration(); BfPropertyDeclaration* GetPropertyDeclaration(); BfAstNode* GetRefNode(); - BfTokenNode* GetMutNode(); + BfTokenNode* GetMutNode(); bool HasBody(); - bool IsEmptyPartial(); + bool IsEmptyPartial(); bool IsDefaultCtor(); bool IsCtorOrInit(); - String ToString(); + String ToString(); int GetExplicitParamCount(); + void BuildParamNameMap(); }; class BfOperatorDef : public BfMethodDef { public: - BfOperatorDeclaration* mOperatorDeclaration; + BfOperatorDeclaration* mOperatorDeclaration; public: BfOperatorDef() @@ -984,7 +995,7 @@ public: struct BfTypeDefLookupContext { public: - int mBestPri; + int mBestPri; BfTypeDef* mBestTypeDef; BfTypeDef* mAmbiguousTypeDef; @@ -993,8 +1004,8 @@ public: { mBestPri = (int)0x80000000; mBestTypeDef = NULL; - mAmbiguousTypeDef = NULL; - } + mAmbiguousTypeDef = NULL; + } bool HasValidMatch() { @@ -1024,12 +1035,12 @@ struct BfMemberSetEntry class BfTypeDefMemberSet : public HashSet { -public: +public: int mSourceSize; public: BfTypeDefMemberSet() - { + { mSourceSize = 0; } @@ -1040,39 +1051,7 @@ public: } }; -class BfUsingFieldData -{ -public: - struct FieldRef - { - BfTypeInstance* mTypeInstance; - BfFieldDef* mFieldDef; - - FieldRef() - { - mTypeInstance = NULL; - mFieldDef = NULL; - } - - FieldRef(BfTypeInstance* typeInst, BfFieldDef* fieldDef) - { - mTypeInstance = typeInst; - mFieldDef = fieldDef; - } - }; - - struct Entry - { - Array mConflicts; - SizedArray mLookup; - }; - -public: - Array mUsingFields; - Dictionary mEntries; -}; - -// For partial classes, the first entry in the map will contain the combined data +// For partial classes, the first entry in the map will contain the combined data class BfTypeDef { public: @@ -1093,16 +1072,16 @@ public: public: BfTypeDef* mNextRevision; - + BfSystem* mSystem; BfProject* mProject; BfTypeDeclaration* mTypeDeclaration; - BfSource* mSource; - DefState mDefState; + BfSource* mSource; + DefState mDefState; Val128 mSignatureHash; // Data, methods, etc - Val128 mFullHash; + Val128 mFullHash; Val128 mInlineHash; - + BfTypeDef* mEmitParent; BfTypeDef* mOuterType; BfAtomComposite mNamespace; @@ -1115,25 +1094,25 @@ public: Array mStaticSearch; Array mInternalAccessSet; Array mFields; - BfUsingFieldData* mUsingFieldData; // Created during mFieldSet Array mProperties; Array mMethods; BfTypeDefMemberSet mMethodSet; BfTypeDefMemberSet mFieldSet; BfTypeDefMemberSet mPropertySet; Array mOperators; - Array mGenericParamDefs; + Array mGenericParamDefs; Array mExternalConstraints; - Array mBaseTypes; - Array mNestedTypes; + Array mBaseTypes; + Array mNestedTypes; Array mDirectAllocNodes; - Array mPartials; // Only valid for mIsCombinedPartial - + Array mPartials; // Only valid for mIsCombinedPartial + int mHash; int mPartialIdx; int mNestDepth; int mDupDetectedRevision; // Error state - BfTypeCode mTypeCode; + BfTypeCode mTypeCode; + BfShow mShow; bool mIsAlwaysInclude; bool mIsNoDiscard; bool mIsPartial; @@ -1143,45 +1122,46 @@ public: bool mIsDelegate; bool mIsFunction; bool mIsClosure; - bool mIsAbstract; - bool mIsStatic; + bool mIsAbstract; + bool mIsStatic; bool mHasCEOnCompile; bool mHasAppendCtor; bool mHasCtorNoBody; bool mHasExtensionMethods; - bool mHasOverrideMethods; + bool mHasOverrideMethods; bool mHasUsingFields; bool mIsOpaque; bool mIsNextRevision; - bool mInDeleteQueue; + bool mInDeleteQueue; bool mForceUseNextRevision; public: BfTypeDef() - { + { Init(); } ~BfTypeDef(); void Init() - { + { mName = NULL; mNameEx = NULL; mSystem = NULL; mProject = NULL; - mTypeCode = BfTypeCode_None; + mTypeCode = BfTypeCode_None; + mShow = BfShow_Show; mIsAlwaysInclude = false; mIsNoDiscard = false; mIsExplicitPartial = false; mIsPartial = false; mIsCombinedPartial = false; mTypeDeclaration = NULL; - mSource = NULL; + mSource = NULL; mDefState = DefState_New; - mHash = 0; + mHash = 0; mPartialIdx = -1; - mIsAbstract = false; + mIsAbstract = false; mIsDelegate = false; mIsFunction = false; mIsClosure = false; @@ -1195,30 +1175,29 @@ public: mIsOpaque = false; mPartialUsed = false; mIsNextRevision = false; - mInDeleteQueue = false; + mInDeleteQueue = false; mForceUseNextRevision = false; mDupDetectedRevision = -1; mNestDepth = 0; mEmitParent = NULL; mOuterType = NULL; - mTypeDeclaration = NULL; + mTypeDeclaration = NULL; mNextRevision = NULL; mProtection = BfProtection_Public; - mUsingFieldData = NULL; } BfSource* GetLastSource(); - bool IsGlobalsContainer(); + bool IsGlobalsContainer(); void Reset(); void FreeMembers(); void PopulateMemberSets(); void ClearMemberSets(); - void RemoveGenericParamDef(BfGenericParamDef* genericParamDef); + void RemoveGenericParamDef(BfGenericParamDef* genericParamDef); int GetSelfGenericParamCount(); String ToString(); BfMethodDef* GetMethodByName(const StringImpl& name, int paramCount = -1); BfFieldDef* GetFieldByName(const StringImpl& name); - bool HasAutoProperty(BfPropertyDeclaration* propertyDeclaration); + bool HasAutoProperty(BfPropertyDeclaration* propertyDeclaration); bool ContainsPartial(BfTypeDef* partialTypeDef); bool HasParsingFailed(); String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration); @@ -1294,7 +1273,7 @@ public: SkipEntry() { mIndex = -1; - mRevision = -1; + mRevision = -1; } SkipEntry(int index, int revision) @@ -1357,12 +1336,12 @@ public: enum BfTargetType { BfTargetType_BeefConsoleApplication, - BfTargetType_BeefWindowsApplication, - BfTargetType_BeefLib, + BfTargetType_BeefWindowsApplication, + BfTargetType_BeefLib, BfTargetType_CustomBuild, BfTargetType_BeefTest, BfTargetType_C_ConsoleApplication, - BfTargetType_C_WindowsApplication, + BfTargetType_C_WindowsApplication, BfTargetType_BeefApplication_StaticLib, BfTargetType_BeefApplication_DynamicLib, BfTargetType_BeefLib_StaticLib, @@ -1392,14 +1371,14 @@ public: DeleteStage_AwaitingRefs, }; -public: +public: BfSystem* mSystem; String mName; String mSafeName; String mDirectory; Array mDependencies; BfTargetType mTargetType; - BfCodeGenOptions mCodeGenOptions; + BfCodeGenOptions mCodeGenOptions; bool mDisabled; bool mSingleModule; bool mAlwaysIncludeAll; @@ -1407,11 +1386,11 @@ public: int mIdx; String mStartupObject; - Array mPreprocessorMacros; + Array mPreprocessorMacros; Dictionary mNamespaces; - + HashSet mUsedModules; - HashSet mReferencedTypeData; + HashSet mReferencedTypeData; Val128 mBuildConfigHash; Val128 mVDataConfigHash; @@ -1423,7 +1402,7 @@ public: ~BfProject(); bool ContainsReference(BfProject* refProject); - bool ReferencesOrReferencedBy(BfProject* refProject); + bool ReferencesOrReferencedBy(BfProject* refProject); bool IsTestProject(); }; @@ -1435,7 +1414,7 @@ enum BfWarning BfWarning_CS0162_UnreachableCode = 162, BfWarning_CS0168_VariableDeclaredButNeverUsed = 168, BfWarning_CS0472_ValueTypeNullCompare = 472, - BfWarning_CS1030_PragmaWarning = 1030, + BfWarning_CS1030_PragmaWarning = 1030, BfWarning_BF4201_Only7Hex = 4201, BfWarning_BF4202_TooManyHexForInt = 4202, BfWarning_BF4203_UnnecessaryDynamicCast = 4203, @@ -1458,9 +1437,9 @@ class BfErrorBase public: bool mIsWarning; bool mIsDeferred; - BfSourceData* mSource; + BfSourceData* mSource; int mSrcStart; - int mSrcEnd; + int mSrcEnd; BfErrorLocation* mLocation; public: @@ -1468,7 +1447,7 @@ public: { mIsWarning = false; mIsDeferred = false; - mSource = NULL; + mSource = NULL; mSrcStart = -1; mSrcEnd = -1; mLocation = NULL; @@ -1486,11 +1465,11 @@ public: class BfError : public BfErrorBase { -public: - bool mIsAfter; +public: + bool mIsAfter; bool mIsPersistent; BfWhileSpecializingFlags mIsWhileSpecializing; - bool mIgnore; + bool mIgnore; BfProject* mProject; String mError; int mWarningNumber; @@ -1499,10 +1478,10 @@ public: public: BfError() { - mIsAfter = false; + mIsAfter = false; mIsPersistent = false; mIsWhileSpecializing = BfWhileSpecializingFlag_None; - mIgnore = false; + mIgnore = false; mProject = NULL; mWarningNumber = 0; } @@ -1560,16 +1539,16 @@ public: BfSystem* mSystem; BfCompiler* mCompiler; bool mTrimMessagesToCursor; - int mFailedIdx; + int mFailedIdx; int mWarnIdx; - + Dictionary mSourceFileNameMap; HashSet mErrorSet; Array mErrors; int mIgnoreCount; - int mWarningCount; + int mWarningCount; int mDeferredErrorCount; - Deque mOutStream; + Deque mOutStream; bool mLastWasDisplayed; bool mLastWasAdded; uint8 mClassifierPassId; @@ -1587,9 +1566,9 @@ public: mLastWasDisplayed = false; mLastWasAdded = false; mClassifierPassId = 0; - mWarningCount = 0; + mWarningCount = 0; mDeferredErrorCount = 0; - mIgnoreCount = 0; + mIgnoreCount = 0; mHadSignatureChanges = false; } @@ -1614,7 +1593,7 @@ public: BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode, bool isDeferred = false); BfError* DeferWarn(int warningNumber, const StringImpl& warning, BfAstNode* refNode); BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode); - BfError* WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx); + BfError* WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx); BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None); BfMoreInfo* MoreInfo(const StringImpl& info, bool forceQueue = false); @@ -1628,7 +1607,7 @@ public: BfError* FailAfter(const StringImpl& error, BfAstNode* refNode); BfError* DeferFail(const StringImpl& error, BfAstNode* refNode); void SilentFail(); - + void TryFlushDeferredError(); void WriteErrorSummary(); }; @@ -1655,7 +1634,6 @@ enum BfOptionFlags BfOptionFlags_Reflect_MethodMask = BfOptionFlags_ReflectStaticMethods | BfOptionFlags_ReflectNonStaticMethods | BfOptionFlags_ReflectConstructors, BfOptionFlags_Mask = 0x3FFF - }; enum BfFieldFlags @@ -1668,7 +1646,8 @@ enum BfFieldFlags BfFieldFlags_EnumPayload = 0x100, BfFieldFlags_EnumDiscriminator = 0x200, BfFieldFlags_EnumCase = 0x400, - BfFieldFlags_ReadOnly = 0x800 + BfFieldFlags_ReadOnly = 0x800, + BfFieldFlags_Appended = 0x1000 }; enum BfReflectKind @@ -1680,7 +1659,7 @@ enum BfReflectKind BfReflectKind_DefaultConstructor = 8, BfReflectKind_Constructors = 0x10, BfReflectKind_StaticMethods = 0x20, - BfReflectKind_Methods = 0x40, + BfReflectKind_Methods = 0x40, BfReflectKind_DynamicBoxing = 0x80, BfReflectKind_User = 0x100, BfReflectKind_All = 0x1FF, @@ -1701,15 +1680,15 @@ public: public: Array mTypeFilters; Array mAttributeFilters; - Array mMatchedIndices; + Array mMatchedIndices; int mSIMDSetting; int mOptimizationLevel; - int mEmitDebugInfo; + int mEmitDebugInfo; BfOptionFlags mAndFlags; BfOptionFlags mOrFlags; Array mReflectMethodFilters; Array mReflectMethodAttributeFilters; - int mAllocStackTraceDepth; + int mAllocStackTraceDepth; public: static int Apply(int val, int applyVal) @@ -1717,7 +1696,7 @@ public: if (applyVal != -1) return applyVal; return val; - } + } bool Apply(bool val, BfOptionFlags flags) { @@ -1741,10 +1720,10 @@ enum BfFindTypeDefFlags class BfSystem { -public: - int mPtrSize; +public: + int mPtrSize; bool mIsResolveOnly; - + CritSect mDataLock; // short-lived, hold only while active modifying data // The following are protected by mDataLock: HashSet mUsedSafeProjectNames; @@ -1772,11 +1751,11 @@ public: uint32 mYieldTickCount; int mHighestYieldTime; // The following are protected by mSystemLock - can only be accessed by the compiling thread - Dictionary mSystemTypeDefs; - BfTypeDefMap mTypeDefs; + Dictionary mSystemTypeDefs; + BfTypeDefMap mTypeDefs; bool mNeedsTypesHandledByCompiler; - BumpAllocator mAlloc; - int mAtomCreateIdx; + BumpAllocator mAlloc; + int mAtomCreateIdx; Dictionary mAtomMap; Array mAtomGraveyard; uint32 mAtomUpdateIdx; @@ -1811,7 +1790,7 @@ public: BfTypeDef* mTypeChar16; BfTypeDef* mTypeChar32; BfTypeDef* mTypeSingle; - BfTypeDef* mTypeDouble; + BfTypeDef* mTypeDouble; BfDirectStrTypeReference* mDirectVoidTypeRef; BfDirectStrTypeReference* mDirectBoolTypeRef; @@ -1827,58 +1806,57 @@ public: public: BfSystem(); ~BfSystem(); - + BfAtom* GetAtom(const StringImpl& string); BfAtom* FindAtom(const StringImpl& string); // Doesn't create a ref BfAtom* FindAtom(const StringView& string); // Doesn't create a ref - void ReleaseAtom(BfAtom* atom); + void ReleaseAtom(BfAtom* atom); void ProcessAtomGraveyard(); void RefAtomComposite(const BfAtomComposite& atomComposite); - void ReleaseAtomComposite(const BfAtomComposite& atomComposite); + void ReleaseAtomComposite(const BfAtomComposite& atomComposite); void SanityCheckAtomComposite(const BfAtomComposite& atomComposite); void TrackName(BfTypeDef* typeDef); - void UntrackName(BfTypeDef* typeDef); + void UntrackName(BfTypeDef* typeDef); bool ParseAtomComposite(const StringView& name, BfAtomComposite& composite, bool addRefs = false); - void CreateBasicTypes(); + void CreateBasicTypes(); bool DoesLiteralFit(BfTypeCode typeCode, int64 value); bool DoesLiteralFit(BfTypeCode typeCode, uint64 value); bool DoesLiteralFit(BfTypeCode typeCode, const BfVariant& variant); - BfParser* CreateParser(BfProject* bfProject); - BfCompiler* CreateCompiler(bool isResolveOnly); + BfParser* CreateParser(BfProject* bfProject); + BfCompiler* CreateCompiler(bool isResolveOnly); BfProject* GetProject(const StringImpl& projName); - BfTypeReference* GetTypeRefElement(BfTypeReference* typeRef); + BfTypeReference* GetTypeRefElement(BfTypeReference* typeRef); BfTypeDef* FilterDeletedTypeDef(BfTypeDef* typeDef); - bool CheckTypeDefReference(BfTypeDef* typeDef, BfProject* project); + bool CheckTypeDefReference(BfTypeDef* typeDef, BfProject* project); BfTypeDef* FindTypeDef(const BfAtomComposite& findName, int numGenericArgs = 0, BfProject* project = NULL, const Array& namespaceSearch = Array(), BfTypeDef** ambiguousTypeDef = NULL, BfFindTypeDefFlags flags = BfFindTypeDefFlag_None); bool FindTypeDef(const BfAtomComposite& findName, int numGenericArgs, BfProject* project, const BfAtomComposite& checkNamespace, bool allowPrivate, BfTypeDefLookupContext* ctx); BfTypeDef* FindTypeDef(const StringImpl& typeName, int numGenericArgs = 0, BfProject* project = NULL, const Array& namespaceSearch = Array(), BfTypeDef** ambiguousTypeDef = NULL, BfFindTypeDefFlags flags = BfFindTypeDefFlag_None); BfTypeDef* FindTypeDef(const StringImpl& typeName, BfProject* project); BfTypeDef* FindTypeDefEx(const StringImpl& typeName); void ClearTypeDefCache(); - void FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set& fixitNamespaces); + void FindFixitNamespaces(const StringImpl& typeName, int numGenericArgs, BfProject* project, std::set& fixitNamespaces); void RemoveTypeDef(BfTypeDef* typeDef); //BfTypeDefMap::Iterator RemoveTypeDef(BfTypeDefMap::Iterator typeDefItr); void AddNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject); void RemoveNamespaceUsage(const BfAtomComposite& namespaceStr, BfProject* bfProject); - bool ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* bfProject); + bool ContainsNamespace(const BfAtomComposite& namespaceStr, BfProject* bfProject); void InjectNewRevision(BfTypeDef* typeDef); void AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* compositeTypeDef, BfTypeDef* partialTypeDef); - void FinishCompositePartial(BfTypeDef* compositeTypeDef); + void FinishCompositePartial(BfTypeDef* compositeTypeDef); void CopyTypeDef(BfTypeDef* typeDef, BfTypeDef* nextTypeDef); void UpdateEmittedTypeDef(BfTypeDef* typeDef); BfTypeDef* GetCombinedPartial(BfTypeDef* typeDef); BfTypeDef* GetOuterTypeNonPartial(BfTypeDef* typeDef); - int GetGenericParamIdx(const Array& genericParams, const StringImpl& name); int GetGenericParamIdx(const Array& genericParams, BfTypeReference* typeRef); - void StartYieldSection(); + void StartYieldSection(); void CheckLockYield(); // Yields to a higher priority request void SummarizeYieldSection(); @@ -1907,7 +1885,7 @@ public: public: AutoDisallowYield(BfSystem* system) - { + { mSystem = system; mSystem->mYieldDisallowCount++; mHeld = true; @@ -1940,7 +1918,6 @@ public: } }; - #ifdef _DEBUG #ifdef BF_PLATFORM_WINDOWS @@ -1978,7 +1955,6 @@ public: #define BfLogX(logIdx, fmt, ...) {} // Nothing #endif - #ifdef BF_WANTS_LOG_SYS #define BfLogSys(sys, fmt, ...) DoBfLog((sys)->mIsResolveOnly ? 1 : 2, fmt, ##__VA_ARGS__) #define BfLogSysM(fmt, ...) DoBfLog(mSystem->mIsResolveOnly ? 1 : 2, fmt, ##__VA_ARGS__) @@ -2054,7 +2030,6 @@ namespace std }; } - namespace std { template<> diff --git a/IDEHelper/Compiler/BfTargetTriple.cpp b/IDEHelper/Compiler/BfTargetTriple.cpp index 37fb863d..d1bb152c 100644 --- a/IDEHelper/Compiler/BfTargetTriple.cpp +++ b/IDEHelper/Compiler/BfTargetTriple.cpp @@ -39,4 +39,4 @@ BfMachineType BfTargetTriple::GetMachineType() if (!mParsed) Parse(); return mMachineType; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfType.h b/IDEHelper/Compiler/BfType.h index bfafa7c8..2f2c44b7 100644 --- a/IDEHelper/Compiler/BfType.h +++ b/IDEHelper/Compiler/BfType.h @@ -3,5 +3,4 @@ NS_BF_BEGIN - NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfUtil.cpp b/IDEHelper/Compiler/BfUtil.cpp index dee396a3..cb015a79 100644 --- a/IDEHelper/Compiler/BfUtil.cpp +++ b/IDEHelper/Compiler/BfUtil.cpp @@ -60,7 +60,7 @@ String Beefy::EncodeFileName(const StringImpl& fromStr) path.Insert(0, fromStr.mPtr, 80); else path += fromStr; - + path.Replace("$", "\\"); for (auto& c : path) { @@ -178,7 +178,7 @@ bool Beefy::BfCheckWildcard(const StringImpl& wildcard, const StringImpl& checkS break; } - prevFilterC = filterC; + prevFilterC = filterC; } return matched; diff --git a/IDEHelper/Compiler/BfUtil.h b/IDEHelper/Compiler/BfUtil.h index 07c60fdf..39456e08 100644 --- a/IDEHelper/Compiler/BfUtil.h +++ b/IDEHelper/Compiler/BfUtil.h @@ -41,7 +41,7 @@ public: public: SetAndRestoreValue() { - mVarPtr = NULL; + mVarPtr = NULL; } SetAndRestoreValue(T& varRef) @@ -54,14 +54,14 @@ public: SetAndRestoreValue(T& varRef, T newVal) { mPrevVal = varRef; - mVarPtr = &varRef; + mVarPtr = &varRef; varRef = newVal; mNewVal = newVal; } SetAndRestoreValue(T& varRef, T newVal, bool doSet) { - mPrevVal = varRef; + mPrevVal = varRef; mVarPtr = &varRef; if (doSet) varRef = newVal; @@ -183,14 +183,14 @@ public: mVals.pop_back(); return val; } - + if (mZeroAlloc) { void* addr = malloc(sizeof(T)); memset(addr, 0, sizeof(T)); val = new(addr) T(); } - else + else val = new T(); if (mOwnsAll) mVals.push_back(val); @@ -226,15 +226,15 @@ inline void EncodeSLEB128(uint8*& buf, int value) bool hasMore; do { - uint8 curByte = (uint8)(value & 0x7f); + uint8 curByte = (uint8)(value & 0x7f); value >>= 7; hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) || ((value == -1) && ((curByte & 0x40) != 0)))); if (hasMore) curByte |= 0x80; - *(buf++) = curByte; + *(buf++) = curByte; } - while (hasMore); + while (hasMore); } inline void EncodeSLEB128(uint8*& buf, int64_t value) @@ -242,15 +242,15 @@ inline void EncodeSLEB128(uint8*& buf, int64_t value) bool hasMore; do { - uint8 curByte = (uint8)(value & 0x7f); + uint8 curByte = (uint8)(value & 0x7f); value >>= 7; hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) || ((value == -1) && ((curByte & 0x40) != 0)))); if (hasMore) curByte |= 0x80; - *(buf++) = curByte; + *(buf++) = curByte; } - while (hasMore); + while (hasMore); } #pragma warning(push) @@ -258,7 +258,7 @@ inline void EncodeSLEB128(uint8*& buf, int64_t value) /// Utility function to decode a SLEB128 value. inline int64_t DecodeSLEB128(const uint8*& p) -{ +{ int value = 0; int shift = 0; int curByte; @@ -267,7 +267,6 @@ inline int64_t DecodeSLEB128(const uint8*& p) curByte = (uint8_t)*p++; value |= ((curByte & 0x7f) << shift); shift += 7; - } while (curByte >= 128); // Sign extend negative numbers. if (((curByte & 0x40) != 0) && (shift < 64)) diff --git a/IDEHelper/Compiler/BfVarDeclChecker.cpp b/IDEHelper/Compiler/BfVarDeclChecker.cpp index 5c0702f3..a0884d0d 100644 --- a/IDEHelper/Compiler/BfVarDeclChecker.cpp +++ b/IDEHelper/Compiler/BfVarDeclChecker.cpp @@ -10,4 +10,4 @@ BfVarDeclChecker::BfVarDeclChecker() void BfVarDeclChecker::Visit(BfVariableDeclaration * binOpExpr) { mHasVarDecl = true; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/BfVarDeclChecker.h b/IDEHelper/Compiler/BfVarDeclChecker.h index 4b9632e8..80af731b 100644 --- a/IDEHelper/Compiler/BfVarDeclChecker.h +++ b/IDEHelper/Compiler/BfVarDeclChecker.h @@ -17,5 +17,4 @@ public: virtual void Visit(BfVariableDeclaration* binOpExpr) override; }; - NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/CeDebugger.cpp b/IDEHelper/Compiler/CeDebugger.cpp index 631fa792..dd402f46 100644 --- a/IDEHelper/Compiler/CeDebugger.cpp +++ b/IDEHelper/Compiler/CeDebugger.cpp @@ -60,7 +60,6 @@ CePendingExpr::~CePendingExpr() ////////////////////////////////////////////////////////////////////////// - CeEvaluationContext::CeEvaluationContext(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo, BfTypedValue contextValue) { Init(winDebugger, expr, formatInfo, contextValue); @@ -69,16 +68,16 @@ CeEvaluationContext::CeEvaluationContext(CeDebugger* winDebugger, const StringIm void CeEvaluationContext::Init(CeDebugger* ceDebugger, const StringImpl& expr, CeFormatInfo* formatInfo, BfTypedValue contextValue) { mDebugger = ceDebugger; - + mCallStackIdx = 0; mParser = NULL; mReducer = NULL; mPassInstance = NULL; mExprEvaluator = NULL; mExprNode = NULL; - + if (expr.empty()) - return; + return; int atPos = (int)expr.IndexOf('@'); if ((atPos != -1) && (atPos < expr.mLength - 2) && (expr[atPos + 1] == '0') && (expr[atPos + 2] == 'x')) @@ -135,7 +134,7 @@ void CeEvaluationContext::Init(CeDebugger* ceDebugger, const StringImpl& expr, C } } - mParser = new BfParser(ceDebugger->mCompiler->mSystem); + mParser = new BfParser(ceDebugger->mCompiler->mSystem); mPassInstance = new BfPassInstance(ceDebugger->mCompiler->mSystem); auto terminatedExpr = expr + ";"; mParser->SetSource(terminatedExpr.c_str(), (int)terminatedExpr.length()); @@ -197,7 +196,7 @@ BfTypedValue CeEvaluationContext::EvaluateInContext(BfTypedValue contextTypedVal auto ceFrame = mDebugger->GetFrame(mCallStackIdx); auto module = mDebugger->mCeMachine->mCeModule; - + SetAndRestoreValue prevTypeInstance(module->mCurTypeInstance, ceFrame->mFunction->mMethodInstance->GetOwner()); SetAndRestoreValue prevMethodInstance(module->mCurMethodInstance, ceFrame->mFunction->mMethodInstance); SetAndRestoreValue prevPassInstance(mDebugger->mCompiler->mPassInstance, mPassInstance); @@ -260,7 +259,7 @@ CeDebugger::CeDebugger(DebugManager* debugManager, BfCompiler* bfCompiler) mDebugPendingExpr = NULL; mCurDbgState = NULL; mBreakpointVersion = 0; - mBreakpointCacheDirty = false; + mBreakpointCacheDirty = false; mBreakpointFramesDirty = false; mCurDisasmFuncId = 0; mActiveBreakpoint = NULL; @@ -285,7 +284,7 @@ String CeDebugger::TypeToString(BfType* type, CeTypeModKind typeModKind) if (typeModKind == CeTypeModKind_ReadOnly) str += "readonly "; else if (typeModKind == CeTypeModKind_Const) - str += "const "; + str += "const "; str += mCeMachine->mCeModule->TypeToString(type); return str; } @@ -363,10 +362,10 @@ String CeDebugger::GetDbgAllocInfo() void CeDebugger::Update() { AutoCrit autoCrit(mCeMachine->mCritSect); - + if ((mRunState == RunState_Terminated) || (mRunState == RunState_Terminating)) return; - + if (mDebugPendingExpr != NULL) { if (mDebugPendingExpr->mDone) @@ -374,10 +373,10 @@ void CeDebugger::Update() else mRunState = RunState_DebugEval; } - else if (mCeMachine->mDbgPaused) - mRunState = RunState_Paused; - else - mRunState = RunState_Running; + else if (mCeMachine->mDbgPaused) + mRunState = RunState_Paused; + else + mRunState = RunState_Running; } void CeDebugger::UpdateBreakpointFrames() @@ -392,7 +391,7 @@ void CeDebugger::UpdateBreakpointFrames() } void CeDebugger::ContinueDebugEvent() -{ +{ AutoCrit autoCrit(mCeMachine->mCritSect); mRunState = RunState_Running; @@ -435,9 +434,9 @@ bool CeDebugger::CheckConditionalBreakpoint(CeBreakpoint* breakpoint) { StringT<256> expr; StringT<256> subjectExpr; - _SplitExpr(conditional->mExpr, expr, subjectExpr); + _SplitExpr(conditional->mExpr, expr, subjectExpr); - conditional->mDbgEvaluationContext = new CeEvaluationContext(this, expr); + conditional->mDbgEvaluationContext = new CeEvaluationContext(this, expr); conditional->mDbgEvaluationContext->mCallStackIdx = -1; } @@ -451,7 +450,6 @@ bool CeDebugger::CheckConditionalBreakpoint(CeBreakpoint* breakpoint) { if (!error->mIsWarning) errorStr = error->mError; - } String condError = StrFormat("error Conditional breakpoint expression '%s' failed: %s", conditional->mExpr.c_str(), errorStr.c_str()); mDebugManager->mOutMessages.push_back(condError); @@ -487,7 +485,7 @@ bool CeDebugger::CheckConditionalBreakpoint(CeBreakpoint* breakpoint) return false; break; } - + if (!breakpoint->mLogging.IsEmpty()) { auto ceContext = mCeMachine->mCurContext; @@ -501,14 +499,14 @@ bool CeDebugger::CheckConditionalBreakpoint(CeBreakpoint* breakpoint) CeFormatInfo formatInfo; formatInfo.mCallStackIdx = -1; - + auto prevRunState = mRunState; mRunState = RunState_Paused; // We need to be paused to avoid certain errors in the eval String displayString; String expr; _SplitExpr(breakpoint->mLogging, expr, formatInfo.mSubjectExpr); - + ProcessEvalString(BfTypedValue(), expr, displayString, formatInfo, NULL, false); mRunState = prevRunState; @@ -520,7 +518,7 @@ bool CeDebugger::CheckConditionalBreakpoint(CeBreakpoint* breakpoint) if (!breakpoint->mBreakAfterLogging) return false; } - + return true; } @@ -533,7 +531,7 @@ Breakpoint* CeDebugger::CreateBreakpoint(const StringImpl& fileName, int lineNum breakpoint->mRequestedLineNum = lineNum; breakpoint->mLineNum = lineNum; breakpoint->mColumn = wantColumn; - breakpoint->mInstrOffset = instrOffset; + breakpoint->mInstrOffset = instrOffset; mBreakpoints.Add(breakpoint); mBreakpointVersion++; @@ -572,7 +570,6 @@ void CeDebugger::CheckBreakpoint(Breakpoint* breakpoint) void CeDebugger::HotBindBreakpoint(Breakpoint* breakpoint, int lineNum, int hotIdx) { - } int64 CeDebugger::ValueToInt(addr_ce addr, BfType* type) @@ -602,7 +599,7 @@ int64 CeDebugger::ValueToInt(addr_ce addr, BfType* type) } int64 CeDebugger::ValueToInt(const BfTypedValue& typedVal) -{ +{ auto ceModule = mCeMachine->mCeModule; auto constant = ceModule->mBfIRBuilder->GetConstant(typedVal.mValue); @@ -610,13 +607,13 @@ int64 CeDebugger::ValueToInt(const BfTypedValue& typedVal) return 0; if (typedVal.IsAddr()) - { + { BfType* type = typedVal.mType; if (type->IsTypedPrimitive()) type = type->GetUnderlyingType(); if ((type->IsInteger()) || (type->IsBoolean())) - { + { auto ceTypedVal = GetAddr(constant); if (ceTypedVal) return ValueToInt((addr_ce)ceTypedVal.mAddr, type); @@ -630,9 +627,9 @@ int64 CeDebugger::ValueToInt(const BfTypedValue& typedVal) auto fromConstGEP = (BfConstantExtractValue*)constant; auto fromTarget = ceModule->mBfIRBuilder->GetConstantById(fromConstGEP->mTarget); if (fromTarget->mConstType == BfConstType_AggCE) - { + { auto aggCE = (BfConstantAggCE*)fromTarget; - + auto dbgTypeInfo = GetDbgTypeInfo(aggCE->mType); if (dbgTypeInfo == NULL) return 0; @@ -658,6 +655,7 @@ void CeDebugger::DeleteBreakpoint(Breakpoint* breakpoint) mBreakpoints.Remove((CeBreakpoint*)breakpoint); delete breakpoint; ClearBreakpointCache(); + mBreakpointVersion++; } void CeDebugger::DetachBreakpoint(Breakpoint* breakpoint) @@ -669,6 +667,7 @@ void CeDebugger::MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantCol breakpoint->mLineNum = lineNum; breakpoint->mColumn = wantColumn; ClearBreakpointCache(); + mBreakpointVersion++; } void CeDebugger::MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount) @@ -676,7 +675,7 @@ void CeDebugger::MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int b } void CeDebugger::DisableBreakpoint(Breakpoint* breakpoint) -{ +{ } void CeDebugger::SetBreakpointCondition(Breakpoint* breakpoint, const StringImpl& conditionExpr) @@ -725,7 +724,6 @@ void CeDebugger::BreakAll() { mCeMachine->mSpecialCheck = true; mCeMachine->mDbgWantBreak = true; - } bool CeDebugger::TryRunContinue() @@ -750,7 +748,7 @@ bool CeDebugger::SetupStep(int frameIdx) return false; } - auto ceMachine = mCeMachine; + auto ceMachine = mCeMachine; auto ceContext = mCeMachine->mCurContext; if (entryIdx < ceFrame->mFunction->mEmitTable.mSize - 1) @@ -766,7 +764,7 @@ bool CeDebugger::SetupStep(int frameIdx) } } else - ceMachine->mStepState.mNextInstIdx = ceFrame->mFunction->mCode.mSize; + ceMachine->mStepState.mNextInstIdx = ceFrame->mFunction->mCode.mSize; ceMachine->mStepState.mStartDepth = ceContext->mCallStack.mSize - frameIdx; ceMachine->mSpecialCheck = true; @@ -806,7 +804,7 @@ void CeDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, i return; if (inAssembly) - { + { int32 instIdx = (int32)lineNumOrAsmAddr; if (instIdx < ceFrame->mFunction->mCode.mSize) { @@ -836,7 +834,7 @@ void CeDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, i } CeFrame* CeDebugger::GetFrame(int callStackIdx) -{ +{ auto ceContext = mCeMachine->mCurContext; if (ceContext == NULL) return NULL; @@ -936,7 +934,7 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread) autoComplete.mModule = module; autoComplete.mCompiler = module->mCompiler; autoComplete.mSystem = module->mSystem; - + BfResolvePassData resolvePass; resolvePass.mParsers.Add(pendingExpr->mParser); resolvePass.mAutoComplete = &autoComplete; @@ -963,14 +961,14 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread) { BfExprEvaluator exprEvaluator(mCeMachine->mCeModule); exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_Comptime); - exprEvaluator.VisitChildNoRef(pendingExpr->mExprNode); - exprResult = exprEvaluator.GetResult(); + exprEvaluator.VisitChildNoRef(pendingExpr->mExprNode); + exprResult = exprEvaluator.GetResult(); origExprResult = exprResult; if ((exprResult) && (!exprResult.mType->IsComposite())) exprResult = module->LoadValue(exprResult); module->FixIntUnknown(exprResult); } - + if (dbgState.mBlockedSideEffects) { if ((mCeMachine->mDbgPaused) && ((pendingExpr->mExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0)) @@ -981,7 +979,7 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread) return "!sideeffects"; } - + if (!exprResult) { auto resultType = mCeMachine->mCeModule->ResolveTypeRef(pendingExpr->mExprNode, {}, BfPopulateType_Data, BfResolveTypeRefFlag_IgnoreLookupError); @@ -1075,7 +1073,7 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread) // val += "\n:canEdit"; // } - if ((origExprResult.mType != NULL) && (!origExprResult.mType->IsComposite()) && (!origExprResult.mType->IsRef()) && + if ((origExprResult.mType != NULL) && (!origExprResult.mType->IsComposite()) && (!origExprResult.mType->IsRef()) && (origExprResult.IsAddr()) && (!origExprResult.IsReadOnly())) { val += "\n:canEdit"; @@ -1083,7 +1081,7 @@ String CeDebugger::DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread) if (pendingExpr->mCursorPos != -1) val += GetAutocompleteOutput(autoComplete); - + return val; } @@ -1101,7 +1099,7 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int auto ceContext = mCeMachine->mCurContext; bool valIsAddr = false; - BfParser* parser = new BfParser(mCompiler->mSystem); + BfParser* parser = new BfParser(mCompiler->mSystem); BfPassInstance* bfPassInstance = new BfPassInstance(mCompiler->mSystem); @@ -1138,14 +1136,14 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int } parser->SetSource(terminatedExpr.c_str(), (int)terminatedExpr.length()); - parser->Parse(bfPassInstance); + parser->Parse(bfPassInstance); BfReducer bfReducer; bfReducer.mAlloc = parser->mAlloc; bfReducer.mSystem = mCompiler->mSystem; bfReducer.mPassInstance = bfPassInstance; bfReducer.mVisitorPos = BfReducer::BfVisitorPos(parser->mRootNode); - bfReducer.mVisitorPos.MoveNext(); + bfReducer.mVisitorPos.MoveNext(); bfReducer.mSource = parser; BfAstNode* exprNode = NULL; if (parseAsType) @@ -1155,8 +1153,8 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int parser->Close(); formatInfo.mCallStackIdx = callStackIdx; - - CePendingExpr* pendingExpr = new CePendingExpr(); + + CePendingExpr* pendingExpr = new CePendingExpr(); pendingExpr->mPassInstance = bfPassInstance; pendingExpr->mParser = parser; pendingExpr->mCallStackIdx = callStackIdx; @@ -1229,7 +1227,7 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int pendingExpr->mExplitType = explicitType; pendingExpr->mFormatInfo = formatInfo; - + String result = DoEvaluate(pendingExpr, false); if (result == "!pending") { @@ -1250,7 +1248,7 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int void CeDebugger::ClearBreakpointCache() { - if (!mCeMachine->mDbgPaused) + if (!mCeMachine->mDbgPaused) mCeMachine->mSpecialCheck = true; mBreakpointFramesDirty = true; mBreakpointCacheDirty = true; @@ -1265,7 +1263,7 @@ void CeDebugger::UpdateBreakpointAddrs() { breakpoint->mCurBindAddr = 1; } - + CeFunction* ceFunction = NULL; if (!mCeMachine->mFunctionIdMap.TryGetValue(mCurDisasmFuncId, &ceFunction)) return; @@ -1283,7 +1281,7 @@ void CeDebugger::UpdateBreakpointCache() mBreakpointCacheDirty = false; if (!mFileInfo.IsEmpty()) - return; + return; for (int i = 0; i < (int)mBreakpoints.mSize; i++) { auto breakpoint = mBreakpoints[i]; @@ -1322,7 +1320,7 @@ void CeDebugger::UpdateBreakpoints(CeFunction* ceFunction) UpdateBreakpointCache(); - ceFunction->UnbindBreakpoints(); + ceFunction->UnbindBreakpoints(); String path; int scope = -1; @@ -1363,7 +1361,7 @@ void CeDebugger::UpdateBreakpoints(CeFunction* ceFunction) int bestRequestedBindLine = 0; while ((idx >= 0) && (idx < ceFileInfo->mOrderedBreakpoints.mSize)) - { + { auto breakpoint = ceFileInfo->mOrderedBreakpoints[idx]; if (usedBreakpointSet.IsSet(breakpoint->mIdx)) { @@ -1382,10 +1380,10 @@ void CeDebugger::UpdateBreakpoints(CeFunction* ceFunction) int lineDiff = emitEntry.mLine - breakpoint->mLineNum; if ((lineDiff < 0) || (lineDiff > 4)) break; - + if ((breakpoint->mHasBound) && (lineDiff != 0)) break; - + bestRequestedBindLine = breakpoint->mRequestedLineNum; } @@ -1435,11 +1433,11 @@ CeDbgTypeInfo* CeDebugger::GetDbgTypeInfo(int typeId) mDbgTypeInfoMap.Remove(typeId); return NULL; } - dbgTypeInfo->mType = type; + dbgTypeInfo->mType = type; auto typeInst = type->ToTypeInstance(); if (typeInst != NULL) - { + { for (int fieldIdx = 0; fieldIdx < typeInst->mFieldInstances.mSize; fieldIdx++) { auto& fieldInst = typeInst->mFieldInstances[fieldIdx]; @@ -1464,7 +1462,6 @@ CeDbgTypeInfo* CeDebugger::GetDbgTypeInfo(int typeId) } } } - } return dbgTypeInfo; } @@ -1512,7 +1509,6 @@ static String IntTypeToString(T val, const StringImpl& name, DwDisplayInfo* disp binary = "'" + binary; binary = ((val & ((T)1 << i)) ? "1" : "0") + binary; - } return StrFormat("0b'%s\n%s", binary.c_str(), name.c_str()); } @@ -1595,7 +1591,7 @@ String CeDebugger::GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, b auto typeInst = type->ToTypeInstance(); if (typeInst == NULL) return ""; - + auto module = typeInst->mModule; String retVal; @@ -1606,7 +1602,7 @@ String CeDebugger::GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, b retVal += StrFormat("[base]\tthis,this=%d@0x%X, nd, na, nv", typeInst->mBaseType->mTypeId, addr); fieldCount++; } - + auto ceContext = mCompiler->mCeMachine->mCurContext; bool didStaticCtor = ceContext->mStaticCtorExecSet.Contains(type->mTypeId); @@ -1616,7 +1612,7 @@ String CeDebugger::GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, b auto fieldDef = fieldInst.GetFieldDef(); if (fieldDef == NULL) continue; - + if (fieldDef->mIsStatic != isStatic) { if (fieldDef->mIsStatic) @@ -1638,7 +1634,7 @@ String CeDebugger::GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, b else { retVal += "\t"; - retVal += fieldDef->mName; + retVal += fieldDef->mName; retVal += StrFormat(",this=%d@0x%X", typeInst->mTypeId, addrInst); } @@ -1649,7 +1645,7 @@ String CeDebugger::GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, b { if (fieldCount > 0) retVal += "\n"; - + retVal += StrFormat("Static values\tcomptype(%d)", typeInst->mTypeId); } @@ -1924,8 +1920,8 @@ String CeDebugger::MaybeQuoteFormatInfoParam(const StringImpl& str) } BfTypedValue CeDebugger::EvaluateInContext(const BfTypedValue& contextTypedValue, const StringImpl& subExpr, CeFormatInfo* formatInfo, String* outReferenceId, String* outErrors) -{ - CeEvaluationContext dbgEvaluationContext(this, subExpr, formatInfo, contextTypedValue); +{ + CeEvaluationContext dbgEvaluationContext(this, subExpr, formatInfo, contextTypedValue); // if (formatInfo != NULL) // { // dbgEvaluationContext.mDbgExprEvaluator->mSubjectExpr = formatInfo->mSubjectExpr; @@ -2023,11 +2019,11 @@ String CeDebugger::GetArrayItems(DebugVisualizerEntry* debugVis, BfType* valueTy BfTypedValue condVal = conditionEvaluationContext.EvaluateInContext(curNode); if (!condVal) break; - + auto ceTypedVal = GetAddr(curNode); if (!ceTypedVal) break; - + if (ValueToInt(condVal) != 0) { auto val = curNode; @@ -2064,11 +2060,11 @@ String CeDebugger::GetLinkedListItems(DebugVisualizerEntry* debugVis, addr_ce en CeEvaluationContext nextEvaluationContext(this, debugVis->mNextPointer); CeEvaluationContext valueEvaluationContext(this, debugVis->mValuePointer); auto ceModule = mCeMachine->mCeModule; - + String addrs; bool checkLeft = true; - + int mapIdx; for (mapIdx = 0; mapIdx < count; mapIdx++) { @@ -2102,7 +2098,7 @@ String CeDebugger::GetLinkedListItems(DebugVisualizerEntry* debugVis, addr_ce en curNode = nextEvaluationContext.EvaluateInContext(curNode); } count = mapIdx; - + if (outContinuationData != NULL) { CeTypedValue ceNodeVal = GetAddr(curNode); @@ -2114,7 +2110,7 @@ String CeDebugger::GetLinkedListItems(DebugVisualizerEntry* debugVis, addr_ce en } String CeDebugger::GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData) -{ +{ CeEvaluationContext nextEvaluationContext(this, debugVis->mNextPointer); auto ceModule = mCeMachine->mCeModule; @@ -2125,7 +2121,7 @@ String CeDebugger::GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedVal count = -1; return ""; } - + auto ceDictTypedVal = GetAddr(dictValue); if (!ceDictTypedVal) return ""; @@ -2155,10 +2151,10 @@ String CeDebugger::GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedVal while (encodeCount < count) { if (nodeIdx != -1) - { + { addr_ce entryAddr = (addr_ce)ceElemTypedVal.mAddr + (nodeIdx * entrySize); - BfTypedValue entryValue = BfTypedValue(ceModule->mBfIRBuilder->CreateConstAggCE(ceModule->mBfIRBuilder->MapType(entryType), entryAddr), entryType); + BfTypedValue entryValue = BfTypedValue(ceModule->mBfIRBuilder->CreateConstAggCE(ceModule->mBfIRBuilder->MapType(entryType), entryAddr), entryType); addrs += EncodeDataPtr(entryAddr, false); BfTypedValue nextValue = nextEvaluationContext.EvaluateInContext(entryValue); @@ -2181,7 +2177,7 @@ String CeDebugger::GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedVal } count = encodeCount; - + if (outContinuationData != NULL) { *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(dictValue.mType, false) + EncodeDataPtr((addr_ce)ceDictTypedVal.mAddr, false) + @@ -2203,25 +2199,25 @@ String CeDebugger::GetTreeItems(DebugVisualizerEntry* debugVis, Array& //TODO: // bool checkLeft = true; -// +// // if ((curNode.mPtr & 2) != 0) // Flag from continuation // { // checkLeft = false; // curNode.mPtr &= (addr_ce)~2; // } -// +// // HashSet seenAddrs; -// +// // for (int mapIdx = 0; mapIdx < count; mapIdx++) // { // BfTypedValue readNode; // while (true) // { // bool checkNode = (curNode.mPtr & 1) == 0; -// +// // readNode = curNode; // readNode.mPtr &= (addr_ce)~1; -// +// // if (checkLeft) // { // BfTypedValue leftValue = leftEvaluationContext.EvaluateInContext(readNode); @@ -2237,7 +2233,7 @@ String CeDebugger::GetTreeItems(DebugVisualizerEntry* debugVis, Array& // checkLeft = false; // break; // Handle node // } -// +// // parentList.push_back(curNode.mPtr); // curNode = leftValue; // } @@ -2267,34 +2263,34 @@ String CeDebugger::GetTreeItems(DebugVisualizerEntry* debugVis, Array& // // Failed // break; // } -// +// // curNode.mPtr = parentList.back(); // parentList.pop_back(); // continue; // Don't check against seenAddrs // } // } -// +// // if (!seenAddrs.Add(curNode.mPtr)) // { // // Failed! // return ""; // } // } -// -// +// +// // BfTypedValue val = valueEvaluationContext.EvaluateInContext(readNode); // if (valueType == NULL) // valueType = val.mType; -// +// // String addr = EncodeDataPtr(val.mPtr, false); // addrs += addr; -// +// // curNode.mPtr |= 1; // Node handled // } -// +// // if (!checkLeft) // curNode.mPtr |= 2; -// +// // if (outContinuationData != NULL) // { // *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(valueType, false) + EncodeDataPtr(curNode.mType, false) + EncodeDataPtr(curNode.mPtr, false); @@ -2306,7 +2302,7 @@ String CeDebugger::GetTreeItems(DebugVisualizerEntry* debugVis, Array& } String CeDebugger::GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) -{ +{ if (!mCeMachine->mDbgPaused) return ""; @@ -2321,26 +2317,26 @@ String CeDebugger::GetCollectionContinuation(const StringImpl& continuationData, // BfTypedValue curNode; // curNode.mType = (DbgType*)DecodeLocalDataPtr(dataPtr); // curNode.mPtr = DecodeTargetDataPtr(dataPtr); -// +// // Array parentList; // String newContinuationData; // while (*dataPtr != 0) // parentList.push_back(DecodeTargetDataPtr(dataPtr)); -// +// // String retVal = GetTreeItems(dbgCompileUnit, debugVis, parentList, valueType, curNode, count, &newContinuationData); // retVal += "\n" + newContinuationData; // return retVal; } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_LinkedList) - { + { addr_ce endNodePtr = DecodeTargetDataPtr(dataPtr); BfType* valueType = (BfType*)DecodeLocalDataPtr(dataPtr); BfType* nodeType = (BfType*)DecodeLocalDataPtr(dataPtr); - + BfTypedValue curNode = BfTypedValue( ceModule->mBfIRBuilder->CreateIntToPtr(DecodeTargetDataPtr(dataPtr), ceModule->mBfIRBuilder->MapType(nodeType)), nodeType); - + String newContinuationData; if (count < 0) @@ -2352,9 +2348,9 @@ String CeDebugger::GetCollectionContinuation(const StringImpl& continuationData, } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Array) { - BfType* valueType = (BfType*)DecodeLocalDataPtr(dataPtr); - - auto nodeType = (BfType*)DecodeLocalDataPtr(dataPtr); + BfType* valueType = (BfType*)DecodeLocalDataPtr(dataPtr); + + auto nodeType = (BfType*)DecodeLocalDataPtr(dataPtr); BfTypedValue curNode = BfTypedValue( ceModule->mBfIRBuilder->CreateIntToPtr(DecodeTargetDataPtr(dataPtr), ceModule->mBfIRBuilder->MapType(nodeType)), nodeType); @@ -2369,7 +2365,7 @@ String CeDebugger::GetCollectionContinuation(const StringImpl& continuationData, return retVal; } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary) - { + { auto dictValueType = (BfType*)DecodeLocalDataPtr(dataPtr); BfTypedValue dictValue = BfTypedValue( ceModule->mBfIRBuilder->CreateIntToPtr(DecodeTargetDataPtr(dataPtr), ceModule->mBfIRBuilder->MapType(dictValueType)), @@ -2397,9 +2393,9 @@ CeTypedValue CeDebugger::GetAddr(BfConstant* constant, BfType* type) auto globalVar = (BfGlobalVar*)constant; String varName(globalVar->mName); - + if (varName.StartsWith("__bfStrObj")) - { + { int stringId = atoi(varName.c_str() + 10); auto addr = ceContext->GetString(stringId); return CeTypedValue(addr, globalVar->mType); @@ -2429,17 +2425,17 @@ CeTypedValue CeDebugger::GetAddr(BfConstant* constant, BfType* type) return CeTypedValue(fieldInfo->mAddr, globalVar->mType); } else if (constant->mTypeCode == BfTypeCode_StringId) - { + { auto stringType = module->ResolveTypeDef(module->mCompiler->mStringTypeDef)->ToTypeInstance(); if ((type != NULL) && (type->IsPointer())) { BfType* charType = module->GetPrimitiveType(BfTypeCode_Char8); - BfType* charPtrType = module->CreatePointerType(charType); + BfType* charPtrType = module->CreatePointerType(charType); auto addr = ceContext->GetString(constant->mInt32) + stringType->mInstSize; return CeTypedValue(addr, module->mBfIRBuilder->MapType(charPtrType)); } else - { + { auto addr = ceContext->GetString(constant->mInt32); return CeTypedValue(addr, module->mBfIRBuilder->MapType(stringType)); } @@ -2474,15 +2470,15 @@ CeTypedValue CeDebugger::GetAddr(BfConstant* constant, BfType* type) if (!typedVal) return CeTypedValue(); - auto dbgTypeInfo = GetDbgTypeInfo(typedVal.mType); + auto dbgTypeInfo = GetDbgTypeInfo(typedVal.mType); if (dbgTypeInfo == NULL) return CeTypedValue(); auto addr = typedVal.mAddr; if (gepConst->mIdx0 != 0) - addr += gepConst->mIdx0 * dbgTypeInfo->mType->GetUnderlyingType()->GetStride(); - + addr += gepConst->mIdx0 * dbgTypeInfo->mType->GetUnderlyingType()->GetStride(); + return CeTypedValue(addr, module->mBfIRBuilder->MapType(dbgTypeInfo->mType)); } else if (constant->mConstType == BfConstType_GEP32_2) @@ -2496,7 +2492,7 @@ CeTypedValue CeDebugger::GetAddr(BfConstant* constant, BfType* type) auto dbgTypeInfo = GetDbgTypeInfo(typedVal.mType); - if ((dbgTypeInfo != NULL) && + if ((dbgTypeInfo != NULL) && ((dbgTypeInfo->mType->IsPointer()) || ((dbgTypeInfo->mType->IsRef())))) dbgTypeInfo = GetDbgTypeInfo(dbgTypeInfo->mType->GetUnderlyingType()->mTypeId); @@ -2520,7 +2516,7 @@ CeTypedValue CeDebugger::GetAddr(BfConstant* constant, BfType* type) ptrType = module->CreatePointerType(ptrType); } } - + if (ptrType == NULL) { if (gepConst->mIdx1 > dbgTypeInfo->mFieldOffsets.mSize) @@ -2570,7 +2566,7 @@ String CeDebugger::ReadString(BfTypeCode charType, intptr addr, intptr maxLength maxLength = BF_MIN(formatInfo.mMaxCount, maxLength); if (maxLength == -1) - maxLength = 8 * 1024 * 1024; // Is 8MB crazy? + maxLength = 8 * 1024 * 1024; // Is 8MB crazy? if (!formatInfo.mRawString) maxLength = BF_MIN(maxLength, maxShowSize); @@ -2838,15 +2834,15 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const { return "!Invalid expression"; } - + bool didAlloc = false; - addr_ce addr = 0; + addr_ce addr = 0; defer( { if (didAlloc) mCurDbgState->mCeContext->CeFree(addr); - } + } ); if (constant->mConstType == BfConstType_AggCE) @@ -2878,19 +2874,19 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const if (!mCurDbgState->mCeContext->WriteConstant(mCeMachine->mCeModule, addr, constant, typedValue.mType)) { return StrFormat("!Failed to encode value"); - } + } } DwDisplayInfo* displayInfo = GetDisplayInfo(formatInfo.mReferenceId); char str[32]; - String result; + String result; auto memStart = mCurDbgState->mCeContext->mMemory.mVals; int checkMemSize = typedValue.mType->mSize; if (typedValue.mType->IsPointer()) checkMemSize = typedValue.mType->GetUnderlyingType()->mSize; - + uint8* data = ceContext->GetMemoryPtr(addr, checkMemSize); if ((addr != 0) && (data == NULL)) { @@ -2900,9 +2896,9 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const return "!Invalid address"; } - addr_ce dataAddr = addr; + addr_ce dataAddr = addr; if ((typedValue.IsAddr()) && (typedValue.mType->IsObjectOrInterface())) - dataAddr = *(addr_ce*)data; + dataAddr = *(addr_ce*)data; if (formatInfo.mRawString) { @@ -2935,7 +2931,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const displayStrFormatInfo.mArrayLength = -1; // Why did we have this "na" on here? It made "void*[3]" type things show up as "{,,}" - //String evalStr = "((" + innerType->ToStringRaw(language) + "*)" + EncodeDataPtr(ptrVal, true) + StrFormat(")[%d], na", idx); + //String evalStr = "((" + innerType->ToStringRaw(language) + "*)" + EncodeDataPtr(ptrVal, true) + StrFormat(")[%d], na", idx); String evalStr = StrFormat("((comptype(%d))(void*)", ptrType->mTypeId) + EncodeDataPtr(ptrVal, true) + StrFormat(")[%lld]", idx); BfTypedValue evalResult = EvaluateInContext(typedValue, evalStr, &displayStrFormatInfo); @@ -2976,7 +2972,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const _ShowArraySummary(retVal, ptrVal, formatInfo.mArrayLength, elementType); - String idxStr = "[{0}]"; + String idxStr = "[{0}]"; retVal += "\n" + TypeToString(typedValue); @@ -3066,7 +3062,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const { // addr = *(addr_ce*)data; // dataAddr = addr; -// +// // data = ceContext->GetMemoryPtr(addr, checkMemSize); // if ((addr != 0) && (data == NULL)) // return "!Invalid address"; @@ -3130,7 +3126,6 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const retVal += ", refid=" + MaybeQuoteFormatInfoParam(formatInfo.mReferenceId); retVal += StrFormat(", this=%d@0x%X", innerType->mTypeId, ptrVal); - } retVal += "\n:canEdit\n:editVal\t" + EncodeDataPtr((uint32)addr, true); @@ -3142,7 +3137,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const if (typedValue.mType->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)typedValue.mType; - + BfTypeCode typeCode = primType->mTypeDef->mTypeCode; if (typeCode == BfTypeCode_IntPtr) typeCode = (primType->mSize == 8) ? BfTypeCode_Int64 : BfTypeCode_Int32; @@ -3163,7 +3158,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const else return StrFormat("true (%d)\n%s", val, TypeToString(origTypedValue.mType, typeModKind).c_str()); } - break; + break; case BfTypeCode_Char8: { auto val = *(uint8*)(data); @@ -3181,7 +3176,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const result = "'\\0'\n"; return result + TypeToString(origTypedValue.mType, typeModKind); } - break; + break; case BfTypeCode_Char16: { auto val = *(uint16*)(data); @@ -3198,7 +3193,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const result = "'\\0'\n"; return result + TypeToString(origTypedValue.mType, typeModKind); } - break; + break; case BfTypeCode_Char32: { auto val = *(uint32*)(data); @@ -3246,7 +3241,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const else //if (floatDisplayType == DwFloatDisplayType_HexLower) sprintf(str, "0x%04x", *(uint32*)data); return StrFormat("%s\n%s", str, TypeToString(origTypedValue.mType, typeModKind).c_str()); - } + } case BfTypeCode_Double: { DwFloatDisplayType floatDisplayType = displayInfo->mFloatDisplayType; @@ -3264,7 +3259,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const } } } - + if (typedValue.mType->IsSizedArray()) { auto arrayType = (BfSizedArrayType*)typedValue.mType; @@ -3272,10 +3267,10 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const String retVal; addr_ce ptrVal = addr; - + intptr arraySize = arrayType->mElementCount; intptr innerSize = innerType->GetStride(); - + String idxStr = "[{0}]"; if (innerType->IsChar()) @@ -3299,7 +3294,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const String referenceId = TypeToString(typedValue.mType); String evalStr; - // Why did we have the "na"? Do we not want to show addresses for all members? + // Why did we have the "na"? Do we not want to show addresses for all members? auto ptrType = module->CreatePointerType(innerType); @@ -3310,14 +3305,14 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const "\t" + idxStr + "\t" + evalStr; return retVal; } - + if (typedValue.mType->IsEnum()) { if (formatInfo.mRawString) return ""; String retVal; - if (typedValue.mType->IsTypedPrimitive()) + if (typedValue.mType->IsTypedPrimitive()) { int64 bitsLeft = ValueToInt(typedValue); int valueCount = 0; @@ -3398,25 +3393,25 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const auto fieldDef = fieldInstance.GetFieldDef(); if (!fieldInstance.mIsEnumPayloadCase) continue; - + int tagId = -fieldInstance.mDataIdx - 1; if (dscrVal == tagId) { auto evalResult = BfTypedValue(module->mBfIRBuilder->CreateConstAggCE( module->mBfIRBuilder->MapType(fieldInstance.mResolvedType), (addr_ce)dataAddr), fieldInstance.mResolvedType, true); - + String innerResult = TypedValueToString(evalResult, "", formatInfo, NULL); int crPos = (int)innerResult.IndexOf('\n'); if (crPos != -1) innerResult.RemoveToEnd(crPos); retVal += "."; - retVal += fieldDef->mName; - retVal += innerResult; + retVal += fieldDef->mName; + retVal += innerResult; retVal += "\n" + TypeToString(origTypedValue.mType, typeModKind); retVal += "\n:canEdit"; - + retVal += "\n" + GetMemberList(fieldInstance.mResolvedType, addr, dataAddr, false); return retVal; } @@ -3459,14 +3454,14 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const if ((((origTypedValue.mType->IsObjectOrInterface()) || (origTypedValue.mType->IsPointer())) && (!formatInfo.mHidePointers) || (dataAddr == 0))) - { + { retVal = EncodeDataPtr((uint32)dataAddr, true); retVal += " "; if (!ceContext->CheckMemory(dataAddr, displayType->mInstSize)) isMemoryValid = false; } - + bool isBadSrc = false; bool isNull = dataAddr == 0; bool hadCustomDisplayString = false; @@ -3475,7 +3470,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const bool useActualRawType = false; bool isTuple = typedValue.mType->IsTuple(); - + String ptrDataStr; if (!formatInfo.mIgnoreDerivedClassInfo) @@ -3494,11 +3489,11 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const } } } - + BfTypedValue summaryTypedValue = typedValue; if ((actualType != NULL) && (actualType != displayType)) - { + { summaryTypedValue = BfTypedValue(module->mBfIRBuilder->CreateIntToPtr(addr, module->mBfIRBuilder->MapType(actualType)), actualType); } @@ -3506,7 +3501,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const Array dbgVisWildcardCaptures; if ((!formatInfo.mNoVisualizers) && (!isNull) && (!isBadSrc)) - { + { debugVis = FindVisualizerForType(summaryTypedValue.mType, &dbgVisWildcardCaptures); } @@ -3568,8 +3563,8 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const } else if ((!isNull) && (!formatInfo.mNoVisualizers) && (!hadCustomDisplayString)) { - // Create our own custom display - + // Create our own custom display + String firstRet; String bigRet = isTuple ? "(" : "{ "; @@ -3577,15 +3572,15 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const BfType* summaryType = summaryTypedValue.mType; bool summaryDone = false; bool truncatedMemberList = false; - + String summaryDataStr = ptrDataStr; String splatStr; if (dataAddr == -1) splatStr = expr; while ((summaryType != NULL) && (isMemoryValid)) - { - if ((summaryType->IsTypedPrimitive()) + { + if ((summaryType->IsTypedPrimitive()) //&& ((summaryType->mBaseTypes.IsEmpty()) || (!summaryType->mBaseTypes.front()->mBaseType->IsTypedPrimitive()))) ) { @@ -3744,7 +3739,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const bigRet += result; //formatInfo.mEmbeddedDisplayCount = displayStrFormatInfo.mEmbeddedDisplayCount; memberIdx++; - } + } } } @@ -3752,12 +3747,12 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const break; // Find first base class with members - BfType* nextSummaryType = summaryTypeInst->mBaseType; + BfType* nextSummaryType = summaryTypeInst->mBaseType; summaryType = nextSummaryType; if ((summaryType == NULL) || (summaryType == module->mContext->mBfObjectType)) break; - + // If we don't have many members then find a base class with some members to show if ((memberIdx != 0) && (displayString.length() >= 255)) { @@ -3774,7 +3769,7 @@ String CeDebugger::TypedValueToString(const BfTypedValue& origTypedValue, const if ((memberIdx == 1) && (!truncatedMemberList) && (firstRet.IndexOf('{') == -1) && (!isTuple)) displayString += "{ " + firstRet + " }"; else - displayString += bigRet; + displayString += bigRet; } retVal += displayString; @@ -3822,10 +3817,10 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* { auto debugVisualizers = mDebugManager->mDebugVisualizers; auto ceModule = mCeMachine->mCeModule; - + if (formatInfo.mExpandItemDepth > 10) // Avoid crashing on circular ExpandItems return; - + bool isReadOnly = false; // if (useTypedValue.mIsReadOnly) // isReadOnly = true; @@ -3978,7 +3973,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* int dimSize1 = lowerDimSizes[0]; int dimSize2 = lowerDimSizes[1]; int dimSize3 = lowerDimSizes[2]; - + BfTypedValue headPointer = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures), &formatInfo); if ((headPointer.mType != NULL) && (headPointer.mType->IsPointer())) { @@ -4023,7 +4018,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* BfType* valueType = NULL; if (!debugVis->mValueType.empty()) { - valueType = FindType(debugVisualizers->DoStringReplace(debugVis->mValueType, dbgVisWildcardCaptures)); + valueType = FindType(debugVisualizers->DoStringReplace(debugVis->mValueType, dbgVisWildcardCaptures)); } BfTypedValue headPointer = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mHeadPointer, dbgVisWildcardCaptures), &formatInfo); @@ -4104,12 +4099,12 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* BfType* valueType = NULL; if (!debugVis->mValueType.empty()) { - valueType = FindType(debugVisualizers->DoStringReplace(debugVis->mValueType, dbgVisWildcardCaptures)); + valueType = FindType(debugVisualizers->DoStringReplace(debugVis->mValueType, dbgVisWildcardCaptures)); } BfTypedValue sizeValue = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); BfTypedValue headPointer = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mHeadPointer, dbgVisWildcardCaptures), &formatInfo); - + if ((sizeValue) && (headPointer) && (sizeValue.mType->IsInteger()) && (ValueToInt(sizeValue) > 0)) { BfTypedValue curNode = headPointer; @@ -4154,7 +4149,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* if (isReadOnly) evalStr += ", ne"; retVal += "\n:repeat" + StrFormat("\t%d\t%d\t%d", 0, size, 10000) + - "\t[{0}]\t" + evalStr + "\t" + EncodeDataPtr(firstAddr, false); + "\t[{0}]\t" + evalStr + "\t" + EncodeDataPtr(firstAddr, false); if (hasSecondAddr) retVal += "\t" + EncodeDataPtr(secondAddr, false); @@ -4171,7 +4166,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* { BfTypedValue sizeValue = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); BfTypedValue entriesPtrValue = EvaluateInContext(typedValue, debugVisualizers->DoStringReplace(debugVis->mEntries, dbgVisWildcardCaptures), &formatInfo); - + if ((sizeValue) && (entriesPtrValue) && (sizeValue.mType->IsInteger()) && (ValueToInt(sizeValue) > 0)) { String continuationData; @@ -4208,7 +4203,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* } if (formatInfo.mExpandItemDepth == 0) - { + { retVal += "\n[Raw View]\tthis,this=" + ptrUseDataStr + ", nv"; } } @@ -4228,7 +4223,7 @@ String CeDebugger::EvaluateContinue() if (!mDebugPendingExpr->mDone) return "!pending"; - + String result = mDebugPendingExpr->mResult; delete mDebugPendingExpr; mDebugPendingExpr = NULL; @@ -4263,15 +4258,15 @@ String CeDebugger::GetAutoLocals(int callStackIdx, bool showRegs) String result; - auto ceFrame = GetFrame(callStackIdx); + auto ceFrame = GetFrame(callStackIdx); if (ceFrame == NULL) return result; - + int scopeIdx = -1; auto ceEntry = ceFrame->mFunction->FindEmitEntry(ceFrame->GetInstIdx()); if (ceEntry != NULL) scopeIdx = ceEntry->mScope; - + int instIdx = ceFrame->GetInstIdx(); if (ceFrame->mFunction->mDbgInfo != NULL) { @@ -4318,9 +4313,9 @@ String CeDebugger::GetAutoLocals(int callStackIdx, bool showRegs) else { dbgInfo[i].mIncluded = false; - } + } } - + for (int i = 0; i < ceFunction->mDbgInfo->mVariables.mSize; i++) { auto& dbgVar = ceFunction->mDbgInfo->mVariables[i]; @@ -4332,7 +4327,7 @@ String CeDebugger::GetAutoLocals(int callStackIdx, bool showRegs) result += "\n"; } } - } + } return result; } @@ -4355,10 +4350,10 @@ DebugVisualizerEntry* CeDebugger::FindVisualizerForType(BfType* dbgType, ArraymDebugVisualizers->FindEntryForType(ceModule->TypeToString(dbgType), DbgFlavor_Unknown, wildcardCaptures); if (entry == NULL) - { + { auto typeInst = dbgType->ToTypeInstance(); if ((typeInst != NULL) && (typeInst->mBaseType != NULL)) - entry = FindVisualizerForType(typeInst->mBaseType, wildcardCaptures); + entry = FindVisualizerForType(typeInst->mBaseType, wildcardCaptures); } return entry; @@ -4400,7 +4395,7 @@ void CeDebugger::ClearCallStack() void CeDebugger::UpdateCallStack(bool slowEarlyOut) { AutoCrit autoCrit(mCeMachine->mCritSect); - + if (!mDbgCallStack.IsEmpty()) return; @@ -4408,7 +4403,7 @@ void CeDebugger::UpdateCallStack(bool slowEarlyOut) for (int frameIdx = ceContext->mCallStack.mSize - 1; frameIdx >= 0; frameIdx--) { auto ceFrame = &ceContext->mCallStack[frameIdx]; - + auto instIdx = ceFrame->GetInstIdx(); auto emitEntry = ceFrame->mFunction->FindEmitEntry(instIdx); if (emitEntry == NULL) @@ -4417,7 +4412,7 @@ void CeDebugger::UpdateCallStack(bool slowEarlyOut) int scopeIdx = emitEntry->mScope; int prevInlineIdx = -1; while (scopeIdx != -1) - { + { CeDbgStackInfo ceDbgStackInfo; ceDbgStackInfo.mFrameIdx = frameIdx; ceDbgStackInfo.mScopeIdx = scopeIdx; @@ -4447,7 +4442,7 @@ int CeDebugger::GetCallStackCount() if (!mCeMachine->mDbgPaused) return 0; - UpdateCallStack(); + UpdateCallStack(); return mDbgCallStack.mSize; } @@ -4522,7 +4517,7 @@ void CeDebugger::GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackI if (outStackIdx != NULL) *outStackIdx = (int)ceContext->mCallStack.mSize - i - 1; } - } + } } String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) @@ -4543,8 +4538,8 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou FrameFlags_HadError = 0x10 }; - auto ceContext = mCeMachine->mCurContext; - + auto ceContext = mCeMachine->mCurContext; + *addr = 0; *outFile = ""; *outHotIdx = 0; @@ -4560,11 +4555,11 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou return ""; auto& dbgCallstackInfo = mDbgCallStack[stackFrameIdx]; - + if (dbgCallstackInfo.mFrameIdx == -1) { if (ceContext->mCurCallSource != NULL) - { + { int line = -1; int lineChar = -1; auto parserData = ceContext->mCurCallSource->mRefNode->GetParserData(); @@ -4574,7 +4569,7 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou *outLine = line; *outColumn = lineChar; *outFile = parserData->mFileName; - } + } } // Entry marker @@ -4605,14 +4600,14 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou if (ceFunction->mFailed) *outFlags |= FrameFlags_HadError; - + int instIdx = (int)(ceFrame->mInstPtr - &ceFunction->mCode[0] - 2); BF_ASSERT(ceFunction->mId != -1); *addr = ((intptr)ceFunction->mId << 32) | instIdx; CeEmitEntry* emitEntry = ceFunction->FindEmitEntry(instIdx); - + *outStackSize = ceContext->mStackSize - ceFrame->mStackAddr; if (stackFrameIdx < mDbgCallStack.mSize - 1) { @@ -4623,12 +4618,11 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou *outStackSize = prevFrame->mStackAddr - ceFrame->mStackAddr; } } - CeDbgScope* ceScope = NULL; if (dbgCallstackInfo.mScopeIdx != -1) ceScope = &ceFunction->mDbgScopes[dbgCallstackInfo.mScopeIdx]; - + if (emitEntry != NULL) { if (emitEntry->mScope != -1) @@ -4656,18 +4650,18 @@ String CeDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* ou auto callTableEntry = &ceFunction->mCallTable[ceScope->mMethodVal]; return ceContext->mCurModule->MethodToString(callTableEntry->mFunctionInfo->mMethodInstance); } - } + } return ceContext->mCurModule->MethodToString(ceFrame->mFunction->mMethodInstance); } BfType* CeDebugger::FindType(const StringImpl& name) -{ +{ if (name == "System.Object") return mCeMachine->mCeModule->mContext->mBfObjectType; BfParser parser(mCompiler->mSystem); - BfPassInstance passInstance(mCompiler->mSystem); + BfPassInstance passInstance(mCompiler->mSystem); parser.SetSource(name.c_str(), (int)name.length()); parser.Parse(&passInstance); @@ -4680,7 +4674,7 @@ BfType* CeDebugger::FindType(const StringImpl& name) reducer.mSource = &parser; auto typeRef = reducer.CreateTypeRef(parser.mRootNode->GetFirst()); parser.Close(); - + auto ceModule = mCeMachine->mCeModule; SetAndRestoreValue prevIgnoreErrors(ceModule->mIgnoreErrors, true); SetAndRestoreValue prevIgnoreWarning(ceModule->mIgnoreWarnings, true); @@ -4698,7 +4692,7 @@ String CeDebugger::Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) int CeDebugger::GetJmpState(int stackFrameIdx) { AutoCrit autoCrit(mDebugManager->mCritSect); - + if (!mCeMachine->mDbgPaused) return -1; @@ -4773,7 +4767,7 @@ String CeDebugger::DisassembleAt(intptr address) mCurDisasmFuncId = (int)(address >> 32); UpdateBreakpointAddrs(); - + CeFunction* ceFunction = NULL; if (!mCeMachine->mFunctionIdMap.TryGetValue(mCurDisasmFuncId, &ceFunction)) return ""; @@ -4785,13 +4779,13 @@ String CeDebugger::DisassembleAt(intptr address) dumpCtx.mEnd = dumpCtx.mPtr + ceFunction->mCode.mSize; uint8* start = dumpCtx.mStart; - + dumpCtx.mStr += StrFormat("T Frame Size: %d\n", ceFunction->mFrameSize); dumpCtx.mStr += StrFormat("A %llX\n", (intptr)mCurDisasmFuncId << 32); int curEmitIdx = 0; CeEmitEntry* prevEmitEntry = NULL; - CeEmitEntry* curEmitEntry = NULL; + CeEmitEntry* curEmitEntry = NULL; String prevSourcePath; @@ -4831,11 +4825,11 @@ String CeDebugger::DisassembleAt(intptr address) } prevEmitEntry = curEmitEntry; - } + } } - + dumpCtx.mStr += StrFormat("D %04X: ", ofs); - dumpCtx.Next(); + dumpCtx.Next(); dumpCtx.mStr += "\n"; if (dumpCtx.mJmp != -1) @@ -4843,7 +4837,7 @@ String CeDebugger::DisassembleAt(intptr address) dumpCtx.mStr += StrFormat("J %X\n", dumpCtx.mJmp); dumpCtx.mJmp = -1; } - } + } return dumpCtx.mStr; } @@ -4929,4 +4923,4 @@ bool CeDebugger::IsOnDemandDebugger() bool CeDebugger::GetEmitSource(const StringImpl& filePath, String& outText) { return false; -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/CeDebugger.h b/IDEHelper/Compiler/CeDebugger.h index 375ee140..f37743e1 100644 --- a/IDEHelper/Compiler/CeDebugger.h +++ b/IDEHelper/Compiler/CeDebugger.h @@ -29,7 +29,7 @@ public: class CeBreakpoint : public Breakpoint { -public: +public: uintptr mCurBindAddr; bool mHasBound; int mIdx; @@ -37,7 +37,7 @@ public: public: CeBreakpoint() - { + { mCurBindAddr = 1; mHasBound = false; mIdx = -1; @@ -62,7 +62,7 @@ struct CeFormatInfo intptr mArrayLength; intptr mOverrideCount; intptr mMaxCount; - DwDisplayType mDisplayType; + DwDisplayType mDisplayType; int mTotalSummaryLength; String mReferenceId; String mSubjectExpr; @@ -86,7 +86,7 @@ struct CeFormatInfo mMaxCount = -1; mTotalSummaryLength = 0; mDisplayType = DwDisplayType_NotSpecified; - mExpandItemDepth = 0; + mExpandItemDepth = 0; } }; @@ -99,7 +99,7 @@ public: BfPassInstance* mPassInstance; BfExprEvaluator* mExprEvaluator; BfExpression* mExprNode; - BfTypedValue mResultOverride; + BfTypedValue mResultOverride; String mExprString; BfTypedValue mExplicitThis; @@ -110,7 +110,7 @@ public: void Init(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue()); bool HasExpression(); ~CeEvaluationContext(); - BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue, CeDbgState* dbgState = NULL); + BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue, CeDbgState* dbgState = NULL); String GetErrorStr(); bool HadError(); }; @@ -153,9 +153,9 @@ public: BfAstNode* mExprNode; String mReferenceId; int mCallStackIdx; - String mResult; + String mResult; int mIdleTicks; - String mException; + String mException; bool mDone; CePendingExpr(); @@ -197,7 +197,7 @@ public: { public: int mFieldIdx; - int64 mVal; + int64 mVal; }; public: @@ -243,16 +243,16 @@ public: CeMachine* mCeMachine; DebugManager* mDebugManager; CePendingExpr* mDebugPendingExpr; - CeDbgState* mCurDbgState; + CeDbgState* mCurDbgState; Array mBreakpoints; - Dictionary mFileInfo; + Dictionary mFileInfo; Dictionary mDbgTypeInfoMap; Array mDbgCallStack; CeEvaluationContext* mCurEvaluationContext; CeBreakpoint* mActiveBreakpoint; int mBreakpointVersion; - bool mBreakpointCacheDirty; + bool mBreakpointCacheDirty; bool mBreakpointFramesDirty; int mCurDisasmFuncId; int mPendingActiveFrameOffset; @@ -270,7 +270,7 @@ public: bool CheckConditionalBreakpoint(CeBreakpoint* breakpoint); bool SetupStep(int frameIdx = 0); - CeFrame* GetFrame(int callStackIdx); + CeFrame* GetFrame(int callStackIdx); String DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread); String Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags); DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId); @@ -296,7 +296,7 @@ public: void UpdateBreakpointCache(); void UpdateBreakpointFrames(); void UpdateBreakpointAddrs(); - void UpdateBreakpoints(CeFunction* ceFunction); + void UpdateBreakpoints(CeFunction* ceFunction); void Continue(); CeDbgTypeInfo* GetDbgTypeInfo(int typeId); CeDbgTypeInfo* GetDbgTypeInfo(BfIRType irType); @@ -346,7 +346,7 @@ public: virtual void StepIntoSpecific(intptr addr) override; virtual void StepOver(bool inAssembly) override; virtual void StepOut(bool inAssembly) override; - virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) override; + virtual void SetNextStatement(bool inAssembly, const StringImpl& fileName, int64 lineNumOrAsmAddr, int wantColumn) override; //virtual DbgTypedValue GetRegister(const StringImpl& regName, CPURegisters* registers, Array* regForms = NULL) override; virtual String Evaluate(const StringImpl& expr, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) override; virtual String EvaluateContinue() override; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 97bcdf12..96e094e3 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -103,7 +103,7 @@ static CeOpInfo gOpInfo[] = {"Jmp", CEOI_None, CEOI_JMPREL}, {"JmpIf", CEOI_None, CEOI_JMPREL, CEOI_FrameRef8}, {"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef8}, - {"Error", CEOI_None, CEOI_IMM32}, + {"Error", CEOI_None, CEOI_IMM32}, {"DynamicCastCheck", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32}, {"GetReflectType", CEOI_FrameRef, CEOI_IMM32}, {"GetString", CEOI_FrameRef, CEOI_IMM32}, @@ -118,8 +118,8 @@ static CeOpInfo gOpInfo[] = {"FrameAddrOfs_32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32}, {"ConstData", CEOI_FrameRef, CEOI_IMM32}, {"ConstDataRef", CEOI_FrameRef, CEOI_IMM32}, - {"Zero", CEOI_None, CEOI_FrameRef, CEOI_IMM32}, - + {"Zero", CEOI_None, CEOI_FrameRef, CEOI_IMM32}, + {"Const_8", CEOI_FrameRef8, CEOI_IMM8}, {"Const_16", CEOI_FrameRef16, CEOI_IMM16}, {"Const_32", CEOI_FrameRef32, CEOI_IMM32}, @@ -190,14 +190,14 @@ static CeOpInfo gOpInfo[] = {"CeOp_Conv_F64_U32", CEOI_FrameRef32, CEOI_FrameRefF64}, {"CeOp_Conv_F64_U64", CEOI_FrameRef64, CEOI_FrameRefF64}, {"CeOp_Conv_F64_F32", CEOI_FrameRefF32, CEOI_FrameRefF64}, - + CEOPINFO_SIZED_NUMERIC_PLUSF_2("Abs", CEOI_FrameRef, CEOI_FrameRef), {"AddConst_I8", CEOI_FrameRef8, CEOI_FrameRef8, CEOI_IMM8}, {"AddConst_I16", CEOI_FrameRef16, CEOI_FrameRef16, CEOI_IMM16}, {"AddConst_I32", CEOI_FrameRef32, CEOI_FrameRef32, CEOI_IMM32}, {"AddConst_I64", CEOI_FrameRef64, CEOI_FrameRef64, CEOI_IMM64}, {"AddConst_F32", CEOI_FrameRefF32, CEOI_FrameRefF32, CEOI_IMMF32}, - {"AddConst_F64", CEOI_FrameRefF64, CEOI_FrameRefF64, CEOI_IMMF64}, + {"AddConst_F64", CEOI_FrameRefF64, CEOI_FrameRefF64, CEOI_IMMF64}, CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Sub", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Mul", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), @@ -211,7 +211,7 @@ static CeOpInfo gOpInfo[] = CEOPINFO_SIZED_NUMERIC_3("Shl", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_UNUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), - + CEOPINFO_SIZED_FLOAT_2("Acos", CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_FLOAT_2("Asin", CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_FLOAT_2("Atan", CEOI_FrameRef, CEOI_FrameRef), @@ -240,7 +240,7 @@ static CeOpInfo gOpInfo[] = CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_SGT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_3("Cmp_UGT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_SGE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), - CEOPINFO_SIZED_NUMERIC_3("Cmp_UGE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), + CEOPINFO_SIZED_NUMERIC_3("Cmp_UGE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_2("Neg", CEOI_FrameRef, CEOI_FrameRef), {"Not_I1", CEOI_FrameRef8, CEOI_FrameRef8}, CEOPINFO_SIZED_NUMERIC_2("Not", CEOI_FrameRef, CEOI_FrameRef), @@ -404,7 +404,7 @@ CeEmitEntry* CeFunction::FindEmitEntry(int instIdx, int* entryIdx) if (!mCode.IsEmpty()) { int lo = 0; - int hi = mEmitTable.size() - 1; + int hi = mEmitTable.size() - 1; while (lo <= hi) { i = (lo + hi) / 2; @@ -439,7 +439,6 @@ int CeFunction::SafeGetId() } __except (EXCEPTION_EXECUTE_HANDLER) { - } return 0; #else @@ -549,7 +548,7 @@ void CeDumpContext::DumpOperandInfo(CeOperandInfoKind operandInfoKind) mStr += '['; int32 size = CE_GET(int32); for (int i = 0; i < size; i++) - { + { if (i != 0) mStr += ", "; uint8 val = CE_GET(uint8); @@ -557,7 +556,7 @@ void CeDumpContext::DumpOperandInfo(CeOperandInfoKind operandInfoKind) sprintf(str, "%X", val); mStr += str; } - mStr += ']'; + mStr += ']'; } break; case CEOI_JMPREL: @@ -587,8 +586,8 @@ void CeDumpContext::Next() } } - CeOpInfo& opInfo = gOpInfo[op]; - + CeOpInfo& opInfo = gOpInfo[op]; + auto argPtr = mPtr; if (mCeFunction->mDbgInfo != NULL) @@ -647,17 +646,17 @@ void CeDumpContext::Next() auto methodInstance = callEntry.mFunctionInfo->mMethodInstance; auto ceModule = mCeFunction->mCeMachine->mCeModule; if (!callEntry.mFunctionInfo->mMethodRef.IsNull()) - { + { auto methodRef = callEntry.mFunctionInfo->mMethodRef; auto methodDef = methodRef.mTypeInstance->mTypeDef->mMethods[methodRef.mMethodNum]; methodInstance = ceModule->GetMethodInstance(methodRef.mTypeInstance, methodDef, - methodRef.mMethodGenericArguments).mMethodInstance; + methodRef.mMethodGenericArguments).mMethodInstance; } if (methodInstance != NULL) mStr += StrFormat(" ; %s", ceModule->MethodToString(methodInstance).c_str()); mPtr = endPtr; - } + } } void CeDumpContext::Dump() @@ -669,11 +668,11 @@ void CeDumpContext::Dump() uint8* start = mPtr; int curEmitIdx = 0; CeEmitEntry* curEmitEntry = NULL; - + while (mPtr < mEnd) { int ofs = mPtr - start; - + while ((curEmitIdx < mCeFunction->mEmitTable.mSize - 1) && (ofs >= mCeFunction->mEmitTable[curEmitIdx + 1].mCodePos)) curEmitIdx++; if (curEmitIdx < mCeFunction->mEmitTable.mSize) @@ -683,12 +682,12 @@ void CeDumpContext::Dump() Next(); if ((curEmitEntry != NULL) && (curEmitEntry->mScope != -1)) - { + { mStr += StrFormat(" @%d[%s:%d]", curEmitIdx, GetFileName(mCeFunction->mDbgScopes[curEmitEntry->mScope].mFilePath).c_str(), curEmitEntry->mLine + 1, curEmitEntry->mColumn + 1); } - mStr += "\n"; + mStr += "\n"; } } @@ -723,8 +722,8 @@ void CeBuilder::Emit(CeOp val) void CeBuilder::EmitSizedOp(CeOp val, int size) { CeSizeClass sizeClass = GetSizeClass(size); - Emit((CeOp)(val + sizeClass)); - if (sizeClass == CeSizeClass_X) + Emit((CeOp)(val + sizeClass)); + if (sizeClass == CeSizeClass_X) Emit((int32)size); } @@ -773,19 +772,19 @@ void CeBuilder::EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, if (endIdx - startIdx >= 18) { // int gteLabel = mCurLabelIdx++; -// +// // auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock); -// +// // int midIdx = startIdx + (endIdx - startIdx) / 2; // auto& switchCase = switchInst->mCases[midIdx]; // auto switchBlock = GetOperand(switchCase.mBlock); // auto mcValue = GetOperand(switchInst->mValue); // auto valueType = GetType(mcValue); -// +// // AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); // AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE)); // switchBlock.mBlock->AddPred(mActiveBlock); -// +// // CreateBinarySwitchSection(switchInst, startIdx, midIdx); // AllocInst(BeMCInstKind_Br, mcDefaultBlock); // CreateLabel(-1, gteLabel); @@ -818,7 +817,7 @@ void CeBuilder::EmitFrameOffset(const CeOperand& val) void CeBuilder::FlushPhi(CeBlock* ceBlock, int targetBlockIdx) { - for (int i = 0; i < (int)ceBlock->mPhiOutgoing.size(); i++) + for (int i = 0; i < (int)ceBlock->mPhiOutgoing.size(); i++) { auto& phiOutgoing = ceBlock->mPhiOutgoing[i]; if (phiOutgoing.mPhiBlockIdx == targetBlockIdx) @@ -839,7 +838,7 @@ void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeO { CeOp op = iOp; if (lhs.mType->IsIntable()) - { + { if (lhs.mType->mSize == 1) op = iOp; else if (lhs.mType->mSize == 2) @@ -855,7 +854,7 @@ void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeO { BF_ASSERT(fOp != CeOp_InvalidOp); if (lhs.mType->mSize == 4) - op = fOp; + op = fOp; else if (lhs.mType->mSize == 8) op = (CeOp)(fOp + 1); else @@ -864,7 +863,7 @@ void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeO else Fail("Invalid binary operand"); Emit(op); - + if (!result) result = FrameAlloc(lhs.mType); EmitFrameOffset(result); @@ -903,7 +902,7 @@ void CeBuilder::EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result = FrameAlloc(val.mType); EmitFrameOffset(result); - EmitFrameOffset(val); + EmitFrameOffset(val); } void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* outResult, bool allowNonStdSize) @@ -924,7 +923,7 @@ void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* ou isStdSize = false; op = (CeOp)(baseOp + 4); } - + Emit(op); if (!isStdSize) @@ -938,9 +937,9 @@ void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* ou { *outResult = FrameAlloc(operand.mType); EmitFrameOffset(*outResult); - } + } - EmitFrameOffset(operand); + EmitFrameOffset(operand); } CeOperand CeBuilder::FrameAlloc(BeType* type) @@ -950,7 +949,7 @@ CeOperand CeBuilder::FrameAlloc(BeType* type) CeOperand result; result.mKind = CeOperandKind_FrameOfs; result.mFrameOfs = -mFrameSize; - result.mType = type; + result.mType = type; return result; } @@ -1024,6 +1023,19 @@ int CeBuilder::GetCallTableIdx(BeFunction* beFunction, CeOperand* outOperand) callEntry.mFunctionInfo = ceFunctionInfo; *callIdxPtr = (int)mCeFunction->mCallTable.size(); mCeFunction->mCallTable.Add(callEntry); + + if (ceFunctionInfo != NULL) + { + auto callerType = mCeFunction->mCeFunctionInfo->GetOwner(); + auto calleeType = ceFunctionInfo->GetOwner(); + + if ((callerType != NULL) && (calleeType != NULL)) + { + // This will generally already be set, but there are some error cases (such as duplicate type names) + // where this will not be set yet + callerType->mModule->AddDependency(calleeType, callerType, BfDependencyMap::DependencyFlag_Calls); + } + } } return *callIdxPtr; } @@ -1032,7 +1044,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme { if (value == NULL) return CeOperand(); - + BeType* errorType = mIntPtrType; CeErrorKind errorKind = CeErrorKind_None; @@ -1079,7 +1091,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme Emit(CeOp_GetString); EmitFrameOffset(result); Emit((int32)*stringTableIdxPtr); - + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef( mCeMachine->mCeModule->mCompiler->mStringTypeDef, BfPopulateType_Data); @@ -1093,13 +1105,13 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme BfFieldInstance** fieldInstancePtr = NULL; if (mStaticFieldInstanceMap.TryGetValue(globalVar->mName, &fieldInstancePtr)) - { + { int* staticFieldTableIdxPtr = NULL; if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr)) { CeStaticFieldEntry staticFieldEntry; staticFieldEntry.mTypeId = (*fieldInstancePtr)->mOwner->mTypeId; - staticFieldEntry.mName = globalVar->mName; + staticFieldEntry.mName = globalVar->mName; staticFieldEntry.mSize = globalVar->mType->mSize; *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size(); mCeFunction->mStaticFieldTable.Add(staticFieldEntry); @@ -1138,7 +1150,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme case BeCastConstant::TypeId: { auto constant = (BeCastConstant*)value; - + CeOperand mcOperand; auto result = GetOperand(constant->mTarget); result.mType = constant->mType; @@ -1170,7 +1182,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme return result; } - case BeTypeCode_Boolean: + case BeTypeCode_Boolean: case BeTypeCode_Double: dataPtr = &constant->mUInt64; dataSize = constant->mType->mSize; @@ -1196,20 +1208,20 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme result.mType = constant->mType; return result; } - + // if (relTo.mKind == CeOperandKind_Immediate_Null) // { // mcOperand.mKind = CeOperandKind_Immediate_Null; // mcOperand.mType = constant->mType; // return mcOperand; // } -// +// // mcOperand = AllocVirtualReg(constant->mType); // auto vregInfo = GetVRegInfo(mcOperand); // vregInfo->mDefOnFirstUse = true; // vregInfo->mRelTo = relTo; // vregInfo->mIsExpr = true; -// +// //return mcOperand; } } @@ -1240,10 +1252,10 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme CeSizeClass sizeClass = GetSizeClass(dataSize); Emit((CeOp)(CeOp_Const_8 + sizeClass)); EmitFrameOffset(result); - if (sizeClass == CeSizeClass_X) + if (sizeClass == CeSizeClass_X) Emit((int32)dataSize); if (dataPtr != 0) - Emit(dataPtr, dataSize); + Emit(dataPtr, dataSize); else { for (int i = 0; i < dataSize; i++) @@ -1251,7 +1263,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme } return result; - } + } } break; case BeStructConstant::TypeId: @@ -1259,7 +1271,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme int* constDataPtr = NULL; auto structConstant = (BeStructConstant*)value; if (mConstDataMap.TryAdd(structConstant, NULL, &constDataPtr)) - { + { CeConstStructData constStructData; constStructData.mQueueFixups = true; errorKind = mCeMachine->WriteConstant(constStructData, structConstant, NULL); @@ -1294,27 +1306,27 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme } } else - { + { errorKind = CeErrorKind_GlobalVariable; } } - break; + break; case BeGEP1Constant::TypeId: { auto gepConstant = (BeGEP1Constant*)value; - + auto mcVal = GetOperand(gepConstant->mTarget); - + BePointerType* ptrType = (BePointerType*)mcVal.mType; BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer); - + auto result = mcVal; - - // We assume we never do both an idx0 and idx1 at once. Fix if we change that. + + // We assume we never do both an idx0 and idx1 at once. Fix if we change that. int64 byteOffset = 0; BeType* elementType = NULL; byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize; - + result = FrameAlloc(ptrType); EmitSizedOp(CeOp_AddConst_I8, mPtrSize); EmitFrameOffset(result); @@ -1327,19 +1339,19 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme case BeGEP2Constant::TypeId: { auto gepConstant = (BeGEP2Constant*)value; - + auto mcVal = GetOperand(gepConstant->mTarget); - + BePointerType* ptrType = (BePointerType*)mcVal.mType; BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer); - + auto result = mcVal; - - // We assume we never do both an idx0 and idx1 at once. Fix if we change that. + + // We assume we never do both an idx0 and idx1 at once. Fix if we change that. int64 byteOffset = 0; BeType* elementType = NULL; byteOffset += gepConstant->mIdx0 * ptrType->mElementType->mSize; - + if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct) { BeStructType* structType = (BeStructType*)ptrType->mElementType; @@ -1354,7 +1366,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme elementType = arrayType->mElementType; byteOffset = gepConstant->mIdx1 * elementType->GetStride(); } - + auto elementPtrType = mCeMachine->GetBeContext()->GetPointerTo(elementType); result = FrameAlloc(elementPtrType); EmitSizedOp(CeOp_AddConst_I8, mPtrSize); @@ -1370,16 +1382,16 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme // Note: this only handles zero-aggregates auto extractConstant = (BeExtractValueConstant*)value; auto elementType = extractConstant->GetType(); - - auto mcVal = GetOperand(extractConstant->mTarget); - + + auto mcVal = GetOperand(extractConstant->mTarget); + BeConstant beConstant; beConstant.mType = elementType; beConstant.mUInt64 = 0; return GetOperand(&beConstant); } break; - case BeFunction::TypeId: + case BeFunction::TypeId: { auto beFunction = (BeFunction*)value; CeOperand operand; @@ -1415,7 +1427,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme CeOperand* operandPtr = NULL; mValueToOperand.TryGetValue(value, &operandPtr); - + if (errorKind != CeErrorKind_None) { Emit(CeOp_Error); @@ -1441,7 +1453,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme if ((operand.mKind == CeOperandKind_AllocaAddr) && (!allowAlloca)) { auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen; - + auto ptrType = mCeMachine->GetBeContext()->GetPointerTo(operand.mType); auto result = FrameAlloc(ptrType); Emit((mPtrSize == 4) ? CeOp_FrameAddr_32 : CeOp_FrameAddr_64); @@ -1477,7 +1489,7 @@ int CeBuilder::DbgCreateMethodRef(BfMethodInstance* methodInstance, const String dbgMethodRef.mMethodRef = methodInstance; int* valuePtr = NULL; if (mDbgMethodRefMap.TryAdd(dbgMethodRef, NULL, &valuePtr)) - { + { *valuePtr = mCeFunction->mDbgMethodRefTable.mSize; mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef); } @@ -1490,11 +1502,11 @@ void CeBuilder::HandleParams() // int regIdxOfs = 0; // int paramOfs = 0; auto retType = mBeFunction->GetFuncType()->mReturnType; - + int frameOffset = 0; if (mCeFunction->mMaxReturnSize > 0) - { + { mReturnVal.mKind = CeOperandKind_AllocaAddr; mReturnVal.mFrameOfs = frameOffset; frameOffset += mCeFunction->mMaxReturnSize; @@ -1509,7 +1521,7 @@ void CeBuilder::HandleParams() auto& typeParam = funcType->mParams[paramIdx + paramOfs]; auto& param = mBeFunction->mParams[paramIdx + paramOfs]; auto beArg = beModule->GetArgument(paramIdx + paramOfs); - auto paramType = typeParam.mType; + auto paramType = typeParam.mType; CeOperand ceOperand; ceOperand.mKind = CeOperandKind_FrameOfs; @@ -1539,8 +1551,8 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance dupMethodInstance->mIsReified = true; dupMethodInstance->mInCEMachine = false; // Only have the original one - - // We can't use methodInstance->mMethodInstanceGroup because we may add foreign method instances which + + // We can't use methodInstance->mMethodInstanceGroup because we may add foreign method instances which // would reallocate the methodInstanceGroup BfMethodInstanceGroup methodInstanceGroup; methodInstanceGroup.mOwner = methodInstance->mMethodInstanceGroup->mOwner; @@ -1555,7 +1567,7 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true, forceIRWrites); irCodeGen->SetState(beState); irBuilder->SetState(irState); - + if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL) mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete; @@ -1576,14 +1588,14 @@ void CeBuilder::Build() mCeFunction->mFailed = true; auto methodInstance = mCeFunction->mMethodInstance; - + if (methodInstance != NULL) { BfMethodInstance dupMethodInstance; dupMethodInstance.CopyFrom(methodInstance); auto methodDef = methodInstance->mMethodDef; - bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation()); + bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation()); int dependentGenericStartIdx = 0; if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) || ((methodInstance->GetOwner()->IsGenericTypeInstance()) && (!isGenericVariation) && (!methodInstance->mMethodDef->mIsLocalMethod) && (!methodInstance->mIsUnspecialized)))) @@ -1598,12 +1610,12 @@ void CeBuilder::Build() dupMethodInstance.GetMethodInfoEx()->mGenericTypeBindings = dupUnspecMethodInstance.mMethodInfoEx->mGenericTypeBindings; } } - + // Clear this so we can properly get QueueStaticField calls - mCeMachine->mCeModule->mStaticFieldRefs.Clear(); + mCeMachine->mCeModule->mStaticFieldRefs.Clear(); int startFunctionCount = (int)beModule->mFunctions.size(); - ProcessMethod(methodInstance, &dupMethodInstance, true); + ProcessMethod(methodInstance, &dupMethodInstance, true); if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized) return; @@ -1611,7 +1623,7 @@ void CeBuilder::Build() { mCeFunction->mFailed = true; return; - } + } mBeFunction = (BeFunction*)irCodeGen->GetBeValue(dupMethodInstance.mIRFunction.mId); mIntPtrType = irCodeGen->mBeContext->GetPrimitiveType((mPtrSize == 4) ? BeTypeCode_Int32 : BeTypeCode_Int64); @@ -1624,7 +1636,7 @@ void CeBuilder::Build() if (beFunction->mBlocks.IsEmpty()) continue; - CeFunction* innerFunction = new CeFunction(); + CeFunction* innerFunction = new CeFunction(); innerFunction->mCeMachine = mCeMachine; innerFunction->mIsVarReturn = beFunction->mIsVarReturn; innerFunction->mCeInnerFunctionInfo = new CeInnerFunctionInfo(); @@ -1663,10 +1675,10 @@ void CeBuilder::Build() mCeFunction->mCeInnerFunctionInfo->mBeFunction = NULL; } - SetAndRestoreValue prevBeFunction(beModule->mActiveFunction, mBeFunction); - + SetAndRestoreValue prevBeFunction(beModule->mActiveFunction, mBeFunction); + // Create blocks - for (int blockIdx = 0; blockIdx < (int)mBeFunction->mBlocks.size(); blockIdx++) + for (int blockIdx = 0; blockIdx < (int)mBeFunction->mBlocks.size(); blockIdx++) { auto beBlock = mBeFunction->mBlocks[blockIdx]; @@ -1684,17 +1696,17 @@ void CeBuilder::Build() { auto beBlock = mBeFunction->mBlocks[blockIdx]; auto& ceBlock = mBlocks[blockIdx]; - + for (int instIdx = 0; instIdx < (int)beBlock->mInstructions.size(); instIdx++) { auto inst = beBlock->mInstructions[instIdx]; - + int instType = inst->GetTypeId(); switch (instType) { case BePhiInst::TypeId: - { + { auto castedInst = (BePhiInst*)inst; auto resultType = castedInst->GetType(); @@ -1710,7 +1722,7 @@ void CeBuilder::Build() CePhiOutgoing phiOutgoing; phiOutgoing.mPhiValue = phiIncoming->mValue; phiOutgoing.mPhiInst = castedInst; - phiOutgoing.mPhiBlockIdx = blockIdx; + phiOutgoing.mPhiBlockIdx = blockIdx; incomingBlock.mPhiOutgoing.Add(phiOutgoing); } } @@ -1721,7 +1733,7 @@ void CeBuilder::Build() auto castedInst = (BeRetInst*)inst; if (castedInst->mRetValue != NULL) { - auto retType = castedInst->mRetValue->GetType(); + auto retType = castedInst->mRetValue->GetType(); mCeFunction->mMaxReturnSize = BF_MAX(retType->mSize, mCeFunction->mMaxReturnSize); } } @@ -1739,11 +1751,11 @@ void CeBuilder::Build() { auto beBlock = mBeFunction->mBlocks[blockIdx]; auto ceBlock = &mBlocks[blockIdx]; - + ceBlock->mEmitOfs = GetCodePos(); if (blockIdx == 0) - HandleParams(); + HandleParams(); for (int instIdx = 0; instIdx < (int)beBlock->mInstructions.size(); instIdx++) { @@ -1752,8 +1764,8 @@ void CeBuilder::Build() int startCodePos = GetCodePos(); - mCurDbgLoc = inst->mDbgLoc; - + mCurDbgLoc = inst->mDbgLoc; + if ((prevEmitDbgPos != mCurDbgLoc) && (mCurDbgLoc != NULL)) { auto _GetScope = [&](BeMDNode* mdNode, int inlinedAt) @@ -1762,12 +1774,12 @@ void CeBuilder::Build() BeDbgFunction* dbgFunc = NULL; String nameAdd; - while (auto dbgLexicalBlock = BeValueDynCast(mdNode)) + while (auto dbgLexicalBlock = BeValueDynCast(mdNode)) mdNode = dbgLexicalBlock->mScope; - + if (dbgFunc = BeValueDynCast(mdNode)) { - dbgFile = dbgFunc->mFile; + dbgFile = dbgFunc->mFile; } else if (auto dbgLoc = BeValueDynCast(mdNode)) dbgFile = dbgLoc->GetDbgFile(); @@ -1790,14 +1802,14 @@ void CeBuilder::Build() if (dbgFunc != NULL) { if (dbgFunc->mValue == NULL) - { + { if (!dbgFunc->mLinkageName.IsEmpty()) { int methodRefIdx = atoi(dbgFunc->mLinkageName.c_str()); dbgScope.mMethodVal = methodRefIdx | CeDbgScope::MethodValFlag_MethodRef; } else - { + { CeDbgMethodRef dbgMethodRef; dbgMethodRef.mNameMod = dbgFunc->mName; @@ -1808,7 +1820,7 @@ void CeBuilder::Build() mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef); } dbgScope.mMethodVal = *valuePtr | CeDbgScope::MethodValFlag_MethodRef; - } + } } else if (dbgFunc->mValue != mBeFunction) dbgScope.mMethodVal = GetCallTableIdx(dbgFunc->mValue, NULL); @@ -1829,10 +1841,10 @@ void CeBuilder::Build() int* valuePtr = NULL; if (mDbgInlineMap.TryAdd(dbgLoc, NULL, &valuePtr)) { - CeDbgInlineEntry inlineEntry; + CeDbgInlineEntry inlineEntry; inlineEntry.mLine = dbgLoc->mLine; inlineEntry.mColumn = dbgLoc->mColumn; - + auto inlinedAt = _GetInlinedScope(dbgLoc->mDbgInlinedAt); inlineEntry.mScope = _GetScope(dbgLoc->mDbgScope, inlinedAt); @@ -1843,7 +1855,7 @@ void CeBuilder::Build() }; int inlinedAt = _GetInlinedScope(mCurDbgLoc->mDbgInlinedAt); - scopeIdx = _GetScope(mCurDbgLoc->mDbgScope, inlinedAt); + scopeIdx = _GetScope(mCurDbgLoc->mDbgScope, inlinedAt); } int instType = inst->GetTypeId(); @@ -1860,9 +1872,10 @@ void CeBuilder::Build() } switch (instType) - { - case BeNopInst::TypeId: - case BeLifetimeStartInst::TypeId: + { + case BeNopInst::TypeId: + case BeLifetimeSoftEndInst::TypeId: + case BeLifetimeStartInst::TypeId: case BeLifetimeExtendInst::TypeId: case BeValueScopeStartInst::TypeId: case BeValueScopeEndInst::TypeId: @@ -1890,7 +1903,7 @@ void CeBuilder::Build() bool isAligned16 = false; int align = castedInst->mAlign; BeType* allocType = castedInst->mType; - bool preservedVolatiles = false; + bool preservedVolatiles = false; if (castedInst->mArraySize != NULL) { @@ -1900,7 +1913,7 @@ void CeBuilder::Build() ceSize.mImmediate = ceSize.mImmediate * mcArraySize.mImmediate; } else - { + { inHeadAlloca = false; if (ceSize.mImmediate == 1) { @@ -1939,12 +1952,12 @@ void CeBuilder::Build() Emit(CeOp_AdjustSPNeg); EmitFrameOffset(ceSize); } - + auto ptrType = beModule->mContext->GetPointerTo(allocType); result = FrameAlloc(ptrType); Emit(CeOp_GetSP); - EmitFrameOffset(result); + EmitFrameOffset(result); } } break; @@ -1961,11 +1974,11 @@ void CeBuilder::Build() result.mKind = CeOperandKind_FrameOfs; } else - { + { ceTarget.mKind = CeOperandKind_FrameOfs; result = FrameAlloc(ceTarget.mType); EmitSizedOp(CeOp_Move_8, ceTarget, NULL, true); - Emit((int32)result.mFrameOfs); + Emit((int32)result.mFrameOfs); } } else @@ -1973,9 +1986,9 @@ void CeBuilder::Build() BF_ASSERT(ceTarget.mType->IsPointer()); auto pointerType = (BePointerType*)ceTarget.mType; auto elemType = pointerType->mElementType; - + CeOperand refOperand = ceTarget; - refOperand.mType = elemType; + refOperand.mType = elemType; EmitSizedOp(CeOp_Load_8, refOperand, &result, true); } } @@ -2056,7 +2069,7 @@ void CeBuilder::Build() else { // Non-zero constant. Weird case, just do an actual MOV - result = FrameAlloc(toType); + result = FrameAlloc(toType); EmitSizedOp(CeOp_Const_8, result, NULL, true); int64 val = mcValue.mImmediate; Emit(&val, toType->mSize); @@ -2090,17 +2103,17 @@ void CeBuilder::Build() // For truncating values, no actual instructions are needed // Note that a copy is not needed because of SSA rules result = ceValue; - result.mType = toType; + result.mType = toType; } else - { + { result = FrameAlloc(toType); CeOp op = CeOp_InvalidOp; - + BeTypeCode fromTypeCode = fromType->mTypeCode; BeTypeCode toTypeCode = toType->mTypeCode; - + if ((castedInst->mValSigned) && (castedInst->mToSigned)) { switch (fromTypeCode) @@ -2158,7 +2171,7 @@ void CeBuilder::Build() break; case BeTypeCode_Int64: switch (toTypeCode) - { + { case BeTypeCode_Float: op = CeOp_Conv_I64_F32; break; @@ -2311,18 +2324,18 @@ void CeBuilder::Build() break; } } - + if (op == CeOp_InvalidOp) { Fail("Invalid conversion op"); } else { - Emit(op); + Emit(op); EmitFrameOffset(result); EmitFrameOffset(ceValue); - } - } + } + } } } break; @@ -2338,7 +2351,7 @@ void CeBuilder::Build() Emit((int32)mcPtr.mFrameOfs); } else - { + { EmitSizedOp(CeOp_Store_8, mcVal, NULL, true); EmitFrameOffset(mcPtr); } @@ -2346,7 +2359,7 @@ void CeBuilder::Build() break; case BeRetInst::TypeId: case BeSetRetInst::TypeId: - { + { auto castedInst = (BeRetInst*)inst; if (castedInst->mRetValue != NULL) { @@ -2368,7 +2381,7 @@ void CeBuilder::Build() Emit((int32)setRetInst->mReturnTypeId); } } - break; + break; case BeCmpInst::TypeId: { auto castedInst = (BeCmpInst*)inst; @@ -2388,7 +2401,7 @@ void CeBuilder::Build() iOp = CeOp_Cmp_NE_I8; fOp = CeOp_Cmp_NE_F32; break; - + case BeCmpKind_SLT: iOp = CeOp_Cmp_SLT_I8; fOp = CeOp_Cmp_SLT_F32; @@ -2431,15 +2444,15 @@ void CeBuilder::Build() EmitBinaryOp(iOp, fOp, ceLHS, ceRHS, result); // auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS); -// +// // auto cmpResultIdx = (int)mCmpResults.size(); // BeCmpResult cmpResult; // cmpResult.mCmpKind = castedInst->mCmpKind; // mCmpResults.push_back(cmpResult); -// +// // result.mKind = BeMCOperandKind_CmpResult; // result.mCmpResultIdx = cmpResultIdx; -// +// // mcInst->mResult = result; } break; @@ -2468,7 +2481,7 @@ void CeBuilder::Build() auto arrayType = (BeSizedArrayType*)ptrType->mElementType; auto elementPtrType = beModule->mContext->GetPointerTo(arrayType->mElementType); - + if (ceIdx1.IsImmediate()) { if (ceIdx1.mImmediate == 0) @@ -2539,7 +2552,7 @@ void CeBuilder::Build() EmitFrameOffset(ofsValue); } else - { + { auto mcElementSize = FrameAlloc(mIntPtrType); Emit(CeOp_Const_64); EmitFrameOffset(mcElementSize); @@ -2550,16 +2563,16 @@ void CeBuilder::Build() EmitFrameOffset(ofsValue); EmitFrameOffset(ceIdx1); EmitFrameOffset(mcElementSize); - + Emit(CeOp_Add_I64); EmitFrameOffset(result); EmitFrameOffset(ceVal); EmitFrameOffset(ofsValue); - } + } } } else - Fail("Invalid GEP"); + Fail("Invalid GEP"); } else { @@ -2589,7 +2602,7 @@ void CeBuilder::Build() { Fail("Invalid gep target"); } - + auto elementPtrType = beModule->mContext->GetPointerTo(elementType); if (byteOffset != 0) @@ -2609,7 +2622,7 @@ void CeBuilder::Build() } } else - { + { CeOperand mcRelOffset; int relScale = 1; if (ceIdx0.IsImmediate()) @@ -2624,7 +2637,7 @@ void CeBuilder::Build() Emit((int32)byteOffset); if (mPtrSize == 8) Emit((int32)0); - } + } } else { @@ -2665,17 +2678,17 @@ void CeBuilder::Build() EmitFrameOffset(ceVal); EmitFrameOffset(ofsValue); } - } + } } } break; case BeExtractValueInst::TypeId: { auto castedInst = (BeExtractValueInst*)inst; - + BeConstant* constant = BeValueDynCast(castedInst->mAggVal); CeOperand mcAgg; - + if (constant != NULL) { result.mImmediate = 0; @@ -2759,7 +2772,7 @@ void CeBuilder::Build() byteOffset = structMember.mByteOffset; memberType = structMember.mType; } - + if (byteOffset != 0) { auto ptrVal = FrameAlloc(beModule->mContext->GetPrimitiveType(BeTypeCode_Int32)); @@ -2784,7 +2797,7 @@ void CeBuilder::Build() { auto castedInst = (BeBrInst*)inst; auto targetBlock = GetOperand(castedInst->mTargetBlock); - + BF_ASSERT(targetBlock.mKind == CeOperandKind_Block); FlushPhi(ceBlock, targetBlock.mBlockIdx); @@ -2795,7 +2808,7 @@ void CeBuilder::Build() break; } - EmitJump(CeOp_Jmp, targetBlock); + EmitJump(CeOp_Jmp, targetBlock); } break; case BeCondBrInst::TypeId: @@ -2804,15 +2817,15 @@ void CeBuilder::Build() auto testVal = GetOperand(castedInst->mCond, true); auto trueBlock = GetOperand(castedInst->mTrueBlock); auto falseBlock = GetOperand(castedInst->mFalseBlock); - + FlushPhi(ceBlock, trueBlock.mBlockIdx); - - EmitJump(CeOp_JmpIf, trueBlock); + + EmitJump(CeOp_JmpIf, trueBlock); EmitFrameOffset(testVal); FlushPhi(ceBlock, falseBlock.mBlockIdx); - EmitJump(CeOp_Jmp, falseBlock); + EmitJump(CeOp_Jmp, falseBlock); } break; case BePhiInst::TypeId: @@ -2848,21 +2861,21 @@ void CeBuilder::Build() int numVals = castedInst->mCases.size(); if (numVals > 0) - { + { EmitBinarySwitchSection(castedInst, 0, castedInst->mCases.size()); } auto mcDefaultBlock = GetOperand(castedInst->mDefaultBlock); - EmitJump(CeOp_Jmp, mcDefaultBlock); + EmitJump(CeOp_Jmp, mcDefaultBlock); } break; case BeCallInst::TypeId: { - auto castedInst = (BeCallInst*)inst; + auto castedInst = (BeCallInst*)inst; BeType* returnType = NULL; bool isVarArg = false; bool useAltArgs = false; - + CeOperand ceFunc; BeFunctionType* beFuncType = NULL; CeOperand virtTarget; @@ -2873,8 +2886,8 @@ void CeBuilder::Build() { switch (intrin->mKind) { - case BfIRIntrinsic_Abs: - EmitUnaryOp(CeOp_Abs_I8, CeOp_Abs_F32, GetOperand(castedInst->mArgs[0].mValue), result); + case BfIRIntrinsic_Abs: + EmitUnaryOp(CeOp_Abs_I8, CeOp_Abs_F32, GetOperand(castedInst->mArgs[0].mValue), result); break; case BfIRIntrinsic_Cast: { @@ -2911,7 +2924,7 @@ void CeBuilder::Build() // Nothing to do break; case BfIRIntrinsic_AtomicAdd: - EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result); + EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result); break; case BfIRIntrinsic_AtomicOr: EmitBinaryOp(CeOp_Or_I8, CeOp_InvalidOp, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result); @@ -3005,7 +3018,7 @@ void CeBuilder::Build() EmitFrameOffset(arg0); EmitFrameOffset(arg1); } - + break; } } @@ -3034,7 +3047,7 @@ void CeBuilder::Build() { virtTarget = GetOperand(beGetVirtualFunc->mValue); virtualTableIdx = beGetVirtualFunc->mVirtualTableIdx; - + auto resultType = beGetVirtualFunc->GetType(); BF_ASSERT(resultType->IsPointer()); beFuncType = (BeFunctionType*)((BePointerType*)resultType)->mElementType; @@ -3051,17 +3064,17 @@ void CeBuilder::Build() } else { - ceFunc = GetOperand(castedInst->mFunc, false, true); + ceFunc = GetOperand(castedInst->mFunc, false, true); auto funcType = castedInst->mFunc->GetType(); if (funcType->IsPointer()) { auto ptrType = (BePointerType*)funcType; if (ptrType->mElementType->mTypeCode == BeTypeCode_Function) { - beFuncType = (BeFunctionType*)ptrType->mElementType; + beFuncType = (BeFunctionType*)ptrType->mElementType; } - } - } + } + } if ((ceFunc) || (virtualTableIdx != -1)) { @@ -3084,7 +3097,7 @@ void CeBuilder::Build() if (beFuncType->mReturnType->mSize > 0) { Emit(CeOp_AdjustSPConst); - Emit((int32)-beFuncType->mReturnType->mSize); + Emit((int32)-beFuncType->mReturnType->mSize); } if (!ceFunc) @@ -3105,14 +3118,14 @@ void CeBuilder::Build() EmitFrameOffset(thisOperand); Emit((int32)virtualTableIdx); } - + if (ceFunc.mKind == CeOperandKind_CallTableIdx) { CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32)); Emit(CeOp_GetMethod); EmitFrameOffset(result); Emit((int32)ceFunc.mCallTableIdx); - + ceFunc = result; } @@ -3137,11 +3150,11 @@ void CeBuilder::Build() { auto castedInst = (BeMemSetInst*)inst; auto ceAddr = GetOperand(castedInst->mAddr); - + if (auto constVal = BeValueDynCast(castedInst->mVal)) { if (auto constSize = BeValueDynCast(castedInst->mSize)) - { + { if (constVal->mUInt8 == 0) { Emit(CeOp_MemSet_Const); @@ -3149,7 +3162,7 @@ void CeBuilder::Build() Emit((uint8)0); Emit((int32)constSize->mUInt32); break; - } + } } } @@ -3159,16 +3172,16 @@ void CeBuilder::Build() Emit(CeOp_MemSet); EmitFrameOffset(ceAddr); EmitFrameOffset(ceVal); - EmitFrameOffset(ceSize); + EmitFrameOffset(ceSize); } break; - case BeFenceInst::TypeId: + case BeFenceInst::TypeId: break; case BeStackSaveInst::TypeId: { result = FrameAlloc(mIntPtrType); Emit(CeOp_GetSP); - EmitFrameOffset(result); + EmitFrameOffset(result); } break; case BeStackRestoreInst::TypeId: @@ -3202,7 +3215,7 @@ void CeBuilder::Build() result = FrameAlloc(ptrType); Emit(CeOp_GetReflectType); - EmitFrameOffset(result); + EmitFrameOffset(result); Emit((int32)castedInst->mTypeId); } break; @@ -3219,11 +3232,11 @@ void CeBuilder::Build() EmitFrameOffset(mcValue); Emit((int32)castedInst->mTypeId); } - break; + break; case BeDbgDeclareInst::TypeId: { auto castedInst = (BeDbgDeclareInst*)inst; - auto mcValue = GetOperand(castedInst->mValue, true); + auto mcValue = GetOperand(castedInst->mValue, true); if (mCeFunction->mDbgInfo != NULL) { @@ -3240,7 +3253,7 @@ void CeBuilder::Build() { mDbgVariableMap[castedInst->mValue] = mCeFunction->mDbgInfo->mVariables.mSize; - CeDbgVariable dbgVariable; + CeDbgVariable dbgVariable; dbgVariable.mName = castedInst->mDbgVar->mName; dbgVariable.mValue = mcValue; dbgVariable.mType = mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId]; @@ -3281,7 +3294,7 @@ void CeBuilder::Build() mValueToOperand[inst] = result; if ((startCodePos != GetCodePos()) && (prevEmitDbgPos != mCurDbgLoc)) - { + { CeEmitEntry emitEntry; emitEntry.mCodePos = startCodePos; emitEntry.mScope = scopeIdx; @@ -3302,7 +3315,7 @@ void CeBuilder::Build() emitEntry.mLine = -1; emitEntry.mColumn = -1; } - mCeFunction->mEmitTable.Add(emitEntry); + mCeFunction->mEmitTable.Add(emitEntry); prevEmitDbgPos = mCurDbgLoc; } @@ -3327,11 +3340,11 @@ void CeBuilder::Build() Fail("No method definition available"); return; } - - if (mCeFunction->mGenError.IsEmpty()) - mCeFunction->mFailed = false; - mCeFunction->mFrameSize = mFrameSize; + if (mCeFunction->mGenError.IsEmpty()) + mCeFunction->mFailed = false; + + mCeFunction->mFrameSize = mFrameSize; } ////////////////////////////////////////////////////////////////////////// @@ -3345,7 +3358,7 @@ CeContext::CeContext() mExecuteId = -1; mStackSize = -1; - mCurCallSource = NULL; + mCurCallSource = NULL; mHeap = new ContiguousHeap(); mCurFrame = NULL; mCurModule = NULL; @@ -3354,7 +3367,7 @@ CeContext::CeContext() mCallerTypeInstance = NULL; mCallerActiveTypeDef = NULL; mCurExpectingType = NULL; - mCurEmitContext = NULL; + mCurEmitContext = NULL; } CeContext::~CeContext() @@ -3389,16 +3402,16 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) ((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0) && !mCurModule->mHadBuildError); if (bfError == NULL) return NULL; - + auto passInstance = mCeMachine->mCompiler->mPassInstance; - + for (int stackIdx = mCallStack.size(); stackIdx >= 0; stackIdx--) { bool isHeadEntry = stackIdx == mCallStack.size(); auto* ceFrame = (isHeadEntry) ? &curFrame : &mCallStack[stackIdx]; - auto ceFunction = ceFrame->mFunction; - + auto ceFunction = ceFrame->mFunction; + CeEmitEntry* emitEntry = ceFunction->FindEmitEntry(ceFrame->mInstPtr - ceFunction->mCode.mVals - 1); StringT<256> err; if (isHeadEntry) @@ -3406,23 +3419,23 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) err = str; err += " "; } - + auto contextMethodInstance = mCallerMethodInstance; auto contextTypeInstance = mCallerTypeInstance; if (stackIdx > 1) { auto func = mCallStack[stackIdx - 1].mFunction; - contextMethodInstance = func->mCeFunctionInfo->mMethodInstance; + contextMethodInstance = func->mCeFunctionInfo->mMethodInstance; contextTypeInstance = contextMethodInstance->GetOwner(); } auto _AddCeMethodInstance = [&](BfMethodInstance* methodInstance) { SetAndRestoreValue prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance); - SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance); - err += mCeMachine->mCeModule->MethodToString(methodInstance, BfMethodNameFlag_OmitParams); + SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance); + err += mCeMachine->mCeModule->MethodToString(methodInstance, BfMethodNameFlag_OmitParams); }; - + auto _AddError = [&](const StringImpl& filePath, int line, int column) { err += StrFormat(" at line% d:%d in %s", line + 1, column + 1, filePath.c_str()); @@ -3448,14 +3461,14 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) int line = emitEntry->mLine; int column = emitEntry->mColumn; - String fileName; + String fileName; if (prevInlineIdx != -1) { auto dbgInlineInfo = &ceFunction->mDbgInlineTable[prevInlineIdx]; line = dbgInlineInfo->mLine; column = dbgInlineInfo->mColumn; - } + } CeDbgScope* ceScope = &ceFunction->mDbgScopes[scopeIdx]; if (ceScope->mMethodVal == -1) @@ -3480,7 +3493,7 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) } _AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, line, column); - + if (ceScope->mInlinedAt == -1) break; auto inlineInfo = &ceFrame->mFunction->mDbgInlineTable[ceScope->mInlinedAt]; @@ -3496,12 +3509,12 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) if (ceFunction->mMethodInstance != NULL) _AddCeMethodInstance(ceFunction->mMethodInstance); - else + else _AddCeMethodInstance(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance); if ((emitEntry != NULL) && (emitEntry->mScope != -1)) { - _AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, emitEntry->mLine, emitEntry->mColumn); + _AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, emitEntry->mLine, emitEntry->mColumn); } else { @@ -3530,7 +3543,7 @@ void CeContext::CalcWorkingDir() void CeContext::FixRelativePath(StringImpl& path) { - CalcWorkingDir(); + CalcWorkingDir(); if (!mWorkingDir.IsEmpty()) path = GetAbsPath(path, mWorkingDir); } @@ -3539,13 +3552,13 @@ bool CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value) { if (mCurModule == NULL) return false; - if (mCurModule->mCurTypeInstance == NULL) + if (mCallerTypeInstance == NULL) return false; if ((mCurEvalFlags & CeEvalFlags_NoRebuild) != 0) return false; - if (mCurModule->mCurTypeInstance->mCeTypeInfo == NULL) - mCurModule->mCurTypeInstance->mCeTypeInfo = new BfCeTypeInfo(); - mCurModule->mCurTypeInstance->mCeTypeInfo->mRebuildMap[key] = value; + if (mCallerTypeInstance->mCeTypeInfo == NULL) + mCallerTypeInstance->mCeTypeInfo = new BfCeTypeInfo(); + mCallerTypeInstance->mCeTypeInfo->mRebuildMap[key] = value; mCurModule->mCompiler->mHasComptimeRebuilds = true; return true; } @@ -3572,7 +3585,7 @@ void CeContext::AddFileRebuild(const StringImpl& path) uint8* CeContext::CeMalloc(int size) { #ifdef CE_ENABLE_HEAP - auto heapRef = mHeap->Alloc(size); + auto heapRef = mHeap->Alloc(size); auto ceAddr = mStackSize + heapRef; int sizeDelta = (ceAddr + size) - mMemory.mSize; if (sizeDelta > 0) @@ -3599,7 +3612,7 @@ addr_ce CeContext::CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elem BfType* elemType = arrayType->GetUnderlyingType(); auto countOffset = arrayType->mBaseType->mFieldInstances[0].mDataOffset; - auto elemOffset = arrayType->mFieldInstances[0].mDataOffset; + auto elemOffset = arrayType->mFieldInstances[0].mDataOffset; int allocSize = elemOffset + elemType->GetStride() * count; @@ -3640,7 +3653,7 @@ addr_ce CeContext::GetReflectType(int typeId) return *addrPtr; auto ceModule = mCeMachine->mCeModule; - SetAndRestoreValue ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false); + SetAndRestoreValue ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false); if (ceModule->mContext->mBfTypeType == NULL) ceModule->mContext->ReflectInit(); @@ -3655,8 +3668,8 @@ addr_ce CeContext::GetReflectType(int typeId) ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods); Dictionary usedStringMap; - auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false); - + auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false); + BeValue* beValue = NULL; if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData)) { @@ -3675,7 +3688,7 @@ addr_ce CeContext::GetReflectType(int typeId) if (auto constant = BeValueDynCast(beValue)) *addrPtr = GetConstantData(constant); - // We need to 'get' again because we might have resized + // We need to 'get' again because we might have resized return *addrPtr; } @@ -3776,11 +3789,11 @@ addr_ce CeContext::GetReflectSpecializedType(addr_ce unspecializedTypeAddr, addr } addr_ce CeContext::GetString(int stringId) -{ +{ addr_ce* ceAddrPtr = NULL; if (!mStringMap.TryAdd(stringId, NULL, &ceAddrPtr)) return *ceAddrPtr; - + BfTypeInstance* stringTypeInst = (BfTypeInstance*)mCeMachine->mCeModule->ResolveTypeDef(mCeMachine->mCompiler->mStringTypeDef, BfPopulateType_Data); String str; @@ -3792,9 +3805,9 @@ addr_ce CeContext::GetString(int stringId) } int allocSize = stringTypeInst->mInstSize + (int)str.length() + 1; - int charsOffset = stringTypeInst->mInstSize; - - uint8* mem = CeMalloc(allocSize); + int charsOffset = stringTypeInst->mInstSize; + + uint8* mem = CeMalloc(allocSize); memset(mem, 0, allocSize); @@ -3842,7 +3855,7 @@ void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry) if (constEntry.mHash.IsZero()) { constEntry.mHash = Hash128(constEntry.mData.mVals, constEntry.mData.mSize); - if (!constEntry.mFixups.IsEmpty()) + if (!constEntry.mFixups.IsEmpty()) constEntry.mHash = Hash128(&constEntry.mFixups[0], constEntry.mFixups.mSize * sizeof(CeConstStructFixup), constEntry.mHash); } @@ -3866,14 +3879,14 @@ void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry) *(addr_ce*)(constEntry.mFixedData.mVals + fixup.mOffset) = addrPtr + stringTypeInst->mInstSize; } } - } + } constEntry.mBindExecuteId = mExecuteId; } bool CeContext::CheckMemory(addr_ce addr, int32 size) { - if ((addr < 0x10000) || (addr + size > mMemory.mSize)) + if ((addr < 0x10000) || (addr + size > mMemory.mSize)) return false; return true; } @@ -3930,7 +3943,7 @@ bool CeContext::GetStringFromAddr(addr_ce strInstAddr, StringImpl& str) } int32 ptrVal = *(int32*)(strInst + ptrOffset); - + if (charPtr != NULL) str.Insert(str.length(), charPtr, lenVal); return true; @@ -3963,9 +3976,9 @@ bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolde auto customAttr = customAttributes->Get(attributeIdx); if (customAttr == NULL) return false; - + auto ceContext = mCeMachine->AllocContext(); - BfIRValue foreignValue = ceContext->CreateAttribute(mCurCallSource->mRefNode, module, constHolder, customAttr); + BfIRValue foreignValue = ceContext->CreateAttribute(mCurCallSource->mRefNode, module, constHolder, customAttr); auto foreignConstant = module->mBfIRBuilder->GetConstant(foreignValue); if (foreignConstant->mConstType == BfConstType_AggCE) { @@ -3976,7 +3989,7 @@ bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolde auto attrConstant = module->mBfIRBuilder->GetConstant(value); if ((attrConstant == NULL) || (!WriteConstant(module, resultAddr, attrConstant, customAttr->mType))) Fail("Failed to decode attribute"); - } + } mCeMachine->ReleaseContext(ceContext); @@ -3991,7 +4004,7 @@ BfType* CeContext::GetCustomAttributeType(BfCustomAttributes* customAttributes, auto customAttr = customAttributes->Get(attributeIdx); if (customAttr == NULL) return NULL; - + return customAttr->mType; } @@ -4074,7 +4087,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta auto elemType = type->GetUnderlyingType(); addr_ce elemsAddr = 0; - addr_ce arrayAddr = CeAllocArray((BfArrayType*)type, aggConstant->mValues.size(), elemsAddr); + addr_ce arrayAddr = CeAllocArray((BfArrayType*)type, aggConstant->mValues.size(), elemsAddr); for (int i = 0; i < (int)aggConstant->mValues.size(); i++) { @@ -4084,14 +4097,14 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta if (!WriteConstant(module, elemsAddr + i * elemType->GetStride(), fieldConstant, elemType)) return false; } - + if (ptrSize == 4) CE_GETC(int32) = arrayAddr; else CE_GETC(int64) = arrayAddr; return true; - } + } else if ((type->IsInstanceOf(module->mCompiler->mSpanTypeDef)) && (isParams)) { auto elemType = type->GetUnderlyingType(); @@ -4120,7 +4133,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta } } else - { + { BF_ASSERT(type->IsStruct()); module->PopulateType(type); @@ -4154,7 +4167,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta auto fieldDef = fieldInstance.GetFieldDef(); if (!fieldInstance.mIsEnumPayloadCase) continue; - int tagIdx = -fieldInstance.mDataIdx - 1; + int tagIdx = -fieldInstance.mDataIdx - 1; if (fieldConstant->mInt32 == tagIdx) payloadType = fieldInstance.mResolvedType; } @@ -4176,7 +4189,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta return false; innerType = payloadType; } - + auto fieldConstant = module->mBfIRBuilder->GetConstant(dataVal); if (fieldConstant == NULL) return false; @@ -4211,7 +4224,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta } if (constant->mConstType == BfConstType_ArrayZero8) - { + { memset(mMemory.mVals + addr, 0, constant->mInt32); return true; } @@ -4227,7 +4240,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta auto constAggData = (BfConstantAggCE*)constant; if (type->IsPointer()) - { + { if (ptrSize == 4) CE_GETC(int32) = constAggData->mCEAddr; else @@ -4235,7 +4248,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta } else { - BF_ASSERT(type->IsComposite()); + BF_ASSERT(type->IsComposite()); memcpy(mMemory.mVals + addr, mMemory.mVals + constAggData->mCEAddr, type->mSize); } return true; @@ -4250,7 +4263,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta if (constant->mConstType == BfConstType_Box) { - auto constBox = (BfConstantBox*)constant; + auto constBox = (BfConstantBox*)constant; auto boxedType = GetBfType(constBox->mToType); if (boxedType == NULL) return false; @@ -4263,7 +4276,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta auto& fieldInstance = boxedTypeInst->mFieldInstances.back(); auto boxedMem = CeMalloc(boxedTypeInst->mInstSize); - memset(boxedMem, 0, ptrSize*2); + memset(boxedMem, 0, ptrSize*2); *(int32*)boxedMem = boxedTypeInst->mTypeId; auto constTarget = module->mBfIRBuilder->GetConstantById(constBox->mTarget); @@ -4299,7 +4312,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta memset(mMemory.mVals + addr, 0, type->mSize); return true; } - + if (constant->mConstType == BfConstType_GEP32_2) { auto gepConst = (BfConstantGEP32_2*)constant; @@ -4328,7 +4341,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta if (strncmp(globalVar->mName, "__bfStrObj", 10) == 0) { int stringId = atoi(globalVar->mName + 10); - addr_ce strAddr = GetString(stringId); + addr_ce strAddr = GetString(stringId); if (ptrSize == 4) CE_GETC(int32) = strAddr; else @@ -4338,7 +4351,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta } if (constant->mTypeCode == BfTypeCode_StringId) - { + { addr_ce strAddr = GetString(constant->mInt32); if (type->IsPointer()) @@ -4368,7 +4381,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta if (constant->mConstType == BfConstType_ExtractValue) { Array extractStack; - auto checkConstant = constant; + auto checkConstant = constant; while (true) { if (checkConstant == NULL) @@ -4385,13 +4398,12 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta if (checkConstant->mConstType == BfConstType_AggCE) return WriteConstant(module, addr, checkConstant, type, isParams); - } - } + } + } return false; } - #define CE_CREATECONST_CHECKPTR(PTR, SIZE) \ if ((((uint8*)(PTR) - memStart) - 0x10000) + (SIZE) > (memSize - 0x10000)) \ { \ @@ -4458,7 +4470,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType return BfIRValue(); } - + if (bfType->IsTypedPrimitive()) return CreateConstant(module, ptr, bfType->GetUnderlyingType(), outType); @@ -4468,7 +4480,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType if (bfType->IsTypeInstance()) { auto typeInst = bfType->ToTypeInstance(); - + uint8* instData = ptr; // if ((typeInst->IsObject()) && (!isBaseType)) // { @@ -4612,15 +4624,15 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType Fail(StrFormat("Reference type '%s' return value not allowed", module->TypeToString(typeInst).c_str())); return BfIRValue(); } - + if (typeInst->mBaseType != NULL) { auto result = CreateConstant(module, instData, typeInst->mBaseType); if (!result) return BfIRValue(); fieldVals.Add(result); - } - + } + if (typeInst->IsUnion()) { auto innerType = typeInst->GetUnionInnerType(); @@ -4667,7 +4679,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType } } } - + for (auto& fieldVal : fieldVals) { if (!fieldVal) @@ -4694,7 +4706,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType if (!elemValue) return BfIRValue(); values.Add(elemValue); - } + } return irBuilder->CreateConstAgg(irBuilder->MapType(sizedArrayType, BfIRPopulateType_Full), values); } @@ -4708,7 +4720,7 @@ BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfI module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType); if (ceAttrAddr == 0) - ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals; + ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals; BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr); BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType); @@ -4752,10 +4764,10 @@ BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfI module->Fail("Attribute prop failed", targetSrc); return ceAttrVal; } - + SizedArray setArgs; if (!customAttribute->mType->IsValuelessType()) - setArgs.Add(ceAttrVal); + setArgs.Add(ceAttrVal); if (!setProperty.mParam.mType->IsValuelessType()) { auto constant = constHolder->GetConstant(setProperty.mParam.mValue); @@ -4763,7 +4775,7 @@ BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfI { module->AssertErrorState(); return ceAttrVal; - } + } setArgs.Add(module->ConstantToCurrent(constant, constHolder, setProperty.mParam.mType, true)); } @@ -4776,7 +4788,7 @@ BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfI { BfFieldInstance* fieldInstance = setField.mFieldRef; if (fieldInstance->mDataOffset < 0) - continue; + continue; auto constant = constHolder->GetConstant(setField.mParam.mValue); WriteConstant(module, ceAttrAddr + fieldInstance->mDataOffset, constant, fieldInstance->mResolvedType); } @@ -4784,7 +4796,6 @@ BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfI return ceAttrVal; } - BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType) { // DISABLED @@ -4801,19 +4812,19 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod SetAndRestoreValue prevCallerMethodInstance(mCallerMethodInstance, module->mCurMethodInstance); SetAndRestoreValue prevCallerTypeInstance(mCallerTypeInstance, module->mCurTypeInstance); SetAndRestoreValue prevCallerActiveTypeDef(mCallerActiveTypeDef, module->GetActiveTypeDef()); - SetAndRestoreValue prevExpectingType(mCurExpectingType, expectingType); - + SetAndRestoreValue prevExpectingType(mCurExpectingType, expectingType); + SetAndRestoreValue prevCtxResolvingVar(module->mContext->mResolvingVarField, false); SetAndRestoreValue moduleCurMethodInstance(module->mCurMethodInstance, methodInstance); - SetAndRestoreValue moduleCurTypeInstance(module->mCurTypeInstance, methodInstance->GetOwner()); + SetAndRestoreValue moduleCurTypeInstance(module->mCurTypeInstance, methodInstance->GetOwner()); - SetAndRestoreValue prevCurExecuteId(mCurModule->mCompiler->mCurCEExecuteId, mCeMachine->mExecuteId); + SetAndRestoreValue prevCurExecuteId(mCurModule->mCompiler->mCurCEExecuteId, mCeMachine->mExecuteId); // Reentrancy may occur as methods need defining //SetAndRestoreValue prevMethodStateInConstEval(module->mCurMethodState, NULL); if (mCeMachine->mAppendAllocInfo != NULL) - { + { if (mCeMachine->mAppendAllocInfo->mAppendSizeValue) { bool isConst = mCeMachine->mAppendAllocInfo->mAppendSizeValue.IsConst(); @@ -4836,7 +4847,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod int appendAllocIdx = -1; bool hasAggData = false; if (!methodInstance->mMethodDef->mIsStatic) - { + { if (!methodInstance->GetOwner()->IsValuelessType()) { thisArgIdx = 0; @@ -4850,7 +4861,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod } if (checkConstant->mConstType == BfConstType_ExtractValue) - { + { auto gepConst = (BfConstantExtractValue*)checkConstant; BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget); checkConstant = module->mBfIRBuilder->GetConstant(targetConst); @@ -4862,7 +4873,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod } if ((methodInstance->GetParamCount() >= 1) && (methodInstance->GetParamKind(0) == BfParamKind_AppendIdx)) - appendAllocIdx = 1; + appendAllocIdx = 1; } int paramCompositeSize = 0; @@ -4879,9 +4890,9 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod if ((!paramType->IsValuelessType()) && (!paramType->IsVar())) break; } - - BfType* compositeType = paramType->IsComposite() ? paramType : NULL; - + + BfType* compositeType = paramType->IsComposite() ? paramType : NULL; + auto arg = args[argIdx]; bool isConst = arg.IsConst(); if (isConst) @@ -4911,7 +4922,11 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod if (!isConst) { - if ((argIdx != thisArgIdx) && (argIdx != appendAllocIdx)) + if ((argIdx == thisArgIdx) && (methodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)) + { + // Allow non-const 'this' for ctor + } + else if (argIdx != appendAllocIdx) { Fail(StrFormat("Non-constant argument for param '%s'", methodInstance->GetParamName(paramIdx).c_str())); return BfTypedValue(); @@ -4930,7 +4945,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry) { - String error = "Comptime method preparation recursion"; + String error = "Comptime method preparation recursion"; auto curContext = this; while (curContext != NULL) { @@ -4946,9 +4961,9 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod } if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized) - mCeMachine->PrepareFunction(ceFunction, NULL); + mCeMachine->PrepareFunction(ceFunction, NULL); - Array prevCallStack; + Array prevCallStack; auto stackPtr = &mMemory[0] + mStackSize; auto* memStart = &mMemory[0]; @@ -4956,7 +4971,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod if (!mCallStack.IsEmpty()) { BF_ASSERT((flags & CeEvalFlags_DbgCall) != 0); - prevCallStack = mCallStack; + prevCallStack = mCallStack; stackPtr = &mMemory[0] + mCallStack.back().mStackAddr; mCallStack.Clear(); } @@ -4991,7 +5006,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod Fail("Return value too large (>2GB)"); return BfTypedValue(); } - + if (memSize > mMemory.mSize) mMemory.Resize(memSize); stackPtr = &mMemory[0] + mStackSize; @@ -5071,12 +5086,12 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod } auto constant = module->mBfIRBuilder->GetConstant(arg); - BfType* compositeType = paramType->IsComposite() ? paramType : NULL; + BfType* compositeType = paramType->IsComposite() ? paramType : NULL; if (((constant->mConstType == BfConstType_AggZero) || (constant->mConstType == BfConstType_Agg)) && ((paramType->IsPointer()) || (paramType->IsRef()))) compositeType = paramType->GetUnderlyingType(); if (compositeType != NULL) - { + { useCompositeAddr -= compositeType->mSize; if (!WriteConstant(module, useCompositeAddr, constant, compositeType, isParams)) { @@ -5090,9 +5105,9 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod if (argIdx == thisArgIdx) thisAddr = addr64; memcpy(stackPtr, &addr64, ceModule->mSystem->mPtrSize); - } + } else - { + { stackPtr -= paramType->mSize; auto useCompositeAddr = stackPtr - memStart; if (!WriteConstant(module, useCompositeAddr, constant, paramType, isParams)) @@ -5143,7 +5158,8 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod mCeMachine->mAppendAllocInfo = NULL; BfType* returnType = NULL; - bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr, returnType); + BfType* castReturnType = NULL; + bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr, returnType, castReturnType); memStart = &mMemory[0]; addr_ce retInstAddr = retAddr; @@ -5208,7 +5224,7 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod else if ((returnType->IsComposite()) || (returnType->IsValuelessType())) { returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstAggZero(module->mBfIRBuilder->MapType(returnType, BfIRPopulateType_Identity)), returnType); - } + } } mCallStack.Clear(); @@ -5223,6 +5239,13 @@ BfTypedValue CeContext::Call(CeCallSource callSource, BfModule* module, BfMethod mCallStack = prevCallStack; } + if ((castReturnType != NULL) && (returnValue)) + { + auto castedReturnValue = module->Cast(callSource.mRefNode, returnValue, castReturnType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromComptimeReturn)); + if (castedReturnValue) + return castedReturnValue; + } + return returnValue; } @@ -5481,7 +5504,7 @@ public: } }; -bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType) +bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType, BfType*& castReturnType) { auto ceModule = mCeMachine->mCeModule; CeFunction* ceFunction = startFunction; @@ -5520,7 +5543,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* stackPtr += memOffset; framePtr += memOffset; }; - + auto _DbgPause = [&]() { int itr = 0; @@ -5539,41 +5562,40 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* /// { AutoCrit autoCrit(mCeMachine->mCritSect); - + if ((mCeMachine->mDebugger->mDebugPendingExpr != NULL) && (itr == 0)) { // Abandon evaluating expression - prevPendingExpr = mCeMachine->mDebugger->mDebugPendingExpr; + prevPendingExpr = mCeMachine->mDebugger->mDebugPendingExpr; mCeMachine->mDebugger->mDebugPendingExpr = NULL; } if (itr == 0) mCallStack.Add(_GetCurFrame()); - mCeMachine->mDbgPaused = true; + mCeMachine->mDbgPaused = true; } - - + mCeMachine->mDebugEvent.WaitFor(); - + CePendingExpr* pendingExpr = NULL; /// { AutoCrit autoCrit(mCeMachine->mCritSect); mCeMachine->mDbgPaused = false; - + if (mCeMachine->mStepState.mKind != CeStepState::Kind_Evaluate) { mCallStack.pop_back(); _FixVariables(); break; } - + mCeMachine->mStepState.mKind = CeStepState::Kind_None; String result; - if (mCeMachine->mDebugger->mDebugPendingExpr != NULL) - pendingExpr = mCeMachine->mDebugger->mDebugPendingExpr; - } + if (mCeMachine->mDebugger->mDebugPendingExpr != NULL) + pendingExpr = mCeMachine->mDebugger->mDebugPendingExpr; + } if (pendingExpr == NULL) continue;; @@ -5594,9 +5616,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto _Fail = [&](const StringImpl& error) { - Fail(_GetCurFrame(), error); - - if (mCeMachine->mDebugger != NULL) + auto bfError = Fail(_GetCurFrame(), error); + if ((bfError != NULL) && (mCeMachine->mDebugger != NULL)) { mCeMachine->mDebugger->OutputRawMessage(StrFormat("error %s", error.c_str())); _DbgPause(); @@ -5641,6 +5662,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* Fail(_GetCurFrame(), "Array out of bounds"); return false; } + else if (checkFunction->mFunctionKind == CeFunctionKind_OOB) + { + Fail(_GetCurFrame(), "Object not initialized"); + return false; + } else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc) { int64 size; @@ -5649,7 +5675,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else size = *(int64*)((uint8*)stackPtr + 8); CE_CHECKALLOC(size); - uint8* ptr = CeMalloc(size); + uint8* ptr = CeMalloc(size); CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize); } else if (checkFunction->mFunctionKind == CeFunctionKind_Free) @@ -5661,7 +5687,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError) { - int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0); + int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0); int32 stackOffset = *(int32*)(stackPtr + ceModule->mSystem->mPtrSize); if (mCeMachine->mDebugger != NULL) @@ -5720,7 +5746,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* int32 typeId = *(int32*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize); auto reflectType = GetReflectType(typeId); _FixVariables(); - CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); } else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeByName) { @@ -5745,9 +5771,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); } else if (checkFunction->mFunctionKind == CeFunctionKind_Type_ToString) - { + { int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize); - + BfType* type = GetBfType(typeId); bool success = false; if (type == NULL) @@ -5755,7 +5781,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Invalid type"); return false; } - + SetAndRestoreValue prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, mCallerMethodInstance); SetAndRestoreValue prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, mCallerTypeInstance); CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->TypeToString(type)), ptrSize); @@ -5813,17 +5839,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute) { - int64 methodHandle = *(int64*)((uint8*)stackPtr + 1); + int64 methodHandle = *(int64*)((uint8*)stackPtr + 1); int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 8); - addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4); + addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { _Fail("Invalid method instance"); return false; - } - bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr); + } + bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr); _FixVariables(); *(addr_ce*)(stackPtr + 0) = success; } @@ -5883,15 +5909,15 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttributeType) { - int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); - int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8); + int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { _Fail("Invalid method instance"); return false; - } + } auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx); if (attrType != NULL) CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize); @@ -5902,8 +5928,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount) { int32 typeId = *(int32*)((uint8*)stackPtr + 4); - - CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId)); + + CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId)); if (typeInfo == NULL) { _Fail("Invalid type"); @@ -5916,8 +5942,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { int32 typeId = *(int32*)((uint8*)stackPtr + 8); int32 methodIdx = *(int32*)((uint8*)stackPtr + 8+4); - - CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId)); + + CeTypeInfo* typeInfo = mCeMachine->GetTypeInfo(GetBfType(typeId)); if (typeInfo == NULL) { _Fail("Invalid type"); @@ -5931,35 +5957,35 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* *(int64*)(stackPtr + 0) = (int64)(intptr)typeInfo->mMethodInstances[methodIdx]; } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_ToString) - { + { int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); - + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { _Fail("Invalid method instance"); return false; } - + CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->MethodToString(methodInstance)), ptrSize); _FixVariables(); } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetName) - { + { int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); - + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { _Fail("Invalid method instance"); return false; } - + CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->mName), ptrSize); _FixVariables(); } - else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo) - { + else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo) + { // int32 mReturnType // int32 mParamCount // int32 mGenericArgCount @@ -5967,14 +5993,14 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* // int32 mMethodIdx int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+2+4); - + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { _Fail("Invalid method instance"); return false; } - + int genericArgCount = 0; if (methodInstance->mMethodInfoEx != NULL) genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize; @@ -5986,14 +6012,14 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* *(int32*)(stackPtr + 4+4+4+2) = methodInstance->mMethodDef->mIdx; } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo) - { - // int32 mParamType + { + // int32 mParamType // int16 mFlags // str mName int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+2+ptrSize); int32 paramIdx = *(int32*)((uint8*)stackPtr + 4+2+ptrSize+8); - + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { @@ -6007,17 +6033,34 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } + enum ParamFlags + { + ParamFlag_None = 0, + ParamFlag_Splat = 1, + ParamFlag_Implicit = 2, + ParamFlag_AppendIdx = 4, + ParamFlag_Params = 8 + }; + + ParamFlags paramFlags = ParamFlag_None; + if (methodInstance->GetParamIsSplat(paramIdx)) + paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat); + if (methodInstance->GetParamKind(paramIdx) == BfParamKind_AppendIdx) + paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx); + if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params) + paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params); + addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx)); _FixVariables(); *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId; - *(int16*)(stackPtr + 4) = 0; // Flags - CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize); + *(int16*)(stackPtr + 4) = (int16)paramFlags; + CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize); } else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg) { int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); int32 genericArgIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8); - + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); if (methodInstance == NULL) { @@ -6030,11 +6073,19 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("genericArgIdx is out of range"); return false; } - + auto reflectType = GetReflectType(methodInstance->mMethodInfoEx->mMethodGenericArguments[genericArgIdx]->mTypeId); _FixVariables(); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); } + else if (checkFunction->mFunctionKind == CeFunctionKind_SetReturnType) + { + int32 typeId = *(int32*)((uint8*)stackPtr); + if (returnType->IsVar()) + castReturnType = GetBfType(typeId); + else + _Fail("Comptime return types can only be set on methods declared with a 'var' return type"); + } else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody) { int32 typeId = *(int32*)((uint8*)stackPtr); @@ -6053,7 +6104,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else if (checkFunction->mFunctionKind == CeFunctionKind_EmitAddInterface) { int32 typeId = *(int32*)((uint8*)stackPtr); - int32 ifaceTypeId = *(int32*)((uint8*)stackPtr + sizeof(int32)); + int32 ifaceTypeId = *(int32*)((uint8*)stackPtr + sizeof(int32)); if ((mCurEmitContext == NULL) || (mCurEmitContext->mType->mTypeId != typeId)) { _Fail("Code cannot be emitted for this type in this context"); @@ -6094,12 +6145,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return false; } } - else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin) + else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin) { SetAndRestoreValue prevMethodInstance(mCurModule->mCurMethodInstance, mCallerMethodInstance); SetAndRestoreValue prevTypeInstance(mCurModule->mCurTypeInstance, mCallerTypeInstance); -// int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0); +// int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0); // String emitStr; // if (!GetStringFromAddr(strInstAddr, emitStr)) // { @@ -6138,38 +6189,38 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetTimeStamp) { int64& result = *(int64*)((uint8*)stackPtr + 0); - result = BfpSystem_GetTimeStamp(); + result = BfpSystem_GetTimeStamp(); } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower) { int32& result = *(int32*)((uint8*)stackPtr + 0); int32 val = *(int32*)((uint8*)stackPtr + 4); - result = utf8proc_tolower(val); + result = utf8proc_tolower(val); } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper) { int32& result = *(int32*)((uint8*)stackPtr + 0); int32 val = *(int32*)((uint8*)stackPtr + 4); - result = utf8proc_toupper(val); + result = utf8proc_toupper(val); } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower) { int32& result = *(int32*)((uint8*)stackPtr + 0); int32 val = *(int32*)((uint8*)stackPtr + 1); - result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL; + result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL; } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper) { int32& result = *(int32*)((uint8*)stackPtr + 0); int32 val = *(int32*)((uint8*)stackPtr + 1); - result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU; + result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU; } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX) { int32& result = *(int32*)((uint8*)stackPtr + 0); int32 val = *(int32*)((uint8*)stackPtr + 1); auto cat = utf8proc_category(val); - result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP); + result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP); } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit) { @@ -6190,7 +6241,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* break; default: result = false; - } + } } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter) { @@ -6208,7 +6259,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* break; default: result = false; - } + } } else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber) { @@ -6224,15 +6275,15 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* break; default: result = false; - } + } } else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Strtod) { double& result = *(double*)((uint8*)stackPtr + 0); addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 8); addr_ce endAddr = *(addr_ce*)((uint8*)stackPtr + 8 + ptrSize); - - addr_ce checkAddr = strAddr; + + addr_ce checkAddr = strAddr; while (true) { if ((uintptr)checkAddr >= (uintptr)memSize) @@ -6295,7 +6346,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Create) { - addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); @@ -6323,7 +6374,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Delete) { - addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); @@ -6338,7 +6389,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); - + CE_CHECKADDR(sizeAddr, 4); int& nameSize = *(int*)(memStart + sizeAddr); CE_CHECKADDR(nameAddr, nameSize); @@ -6351,7 +6402,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_SetCurrent) { - addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); @@ -6388,7 +6439,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 4); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 4 + ptrSize + ptrSize); - + CE_CHECKADDR(sizeAddr, 4); int& nameSize = *(int*)(memStart + sizeAddr); CE_CHECKADDR(nameAddr, nameSize); @@ -6400,9 +6451,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Close) { - addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); - + CE_CHECKADDR(outResultAddr, 4); CeInternalData* internalData = NULL; @@ -6420,7 +6471,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - CE_CHECKADDR(outResultAddr, 4); + CE_CHECKADDR(outResultAddr, 4); FixRelativePath(path); auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr)); if (bfpFile != NULL) @@ -6475,7 +6526,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* while (true) { if (*cancelingPtr) - break; + break; int useTimeout = timeoutLeft; if (useTimeout < 0) @@ -6523,7 +6574,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* asyncOperation->AddRef(); asyncThread = BfpThread_Create(CeAsyncOperation::RunProc, asyncOperation); - } + } if (asyncOperation != NULL) asyncOperation->Release(); @@ -6555,9 +6606,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Truncate) { - addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); - + CE_CHECKADDR(outResultAddr, 4); CeInternalData* internalData = NULL; @@ -6605,7 +6656,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* result = BfpFile_GetAttributes(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_SetAttributes) - { + { addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); BfpFileAttributes attribs = *(BfpFileAttributes*)((uint8*)stackPtr + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); @@ -6621,7 +6672,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { addr_ce srcAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce destAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); - BfpFileCopyKind fileCopyKind = *(BfpFileCopyKind*)((uint8*)stackPtr + ptrSize + ptrSize); + BfpFileCopyKind fileCopyKind = *(BfpFileCopyKind*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); @@ -6652,7 +6703,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Delete) { - addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); + addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); @@ -6669,16 +6720,16 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixRelativePath(path); + FixRelativePath(path); AddFileRebuild(path); result = BfpFile_Exists(path.c_str()); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempPath) - { + { addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); - + CE_CHECKADDR(sizeAddr, 4); int& nameSize = *(int*)(memStart + sizeAddr); CE_CHECKADDR(nameAddr, nameSize); @@ -6693,7 +6744,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); - + CE_CHECKADDR(sizeAddr, 4); int& nameSize = *(int*)(memStart + sizeAddr); CE_CHECKADDR(nameAddr, nameSize); @@ -6709,7 +6760,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize); - + String srcPath; CE_CHECKADDR_STR(srcPath, srcAddr); @@ -6719,7 +6770,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* char* namePtr = (char*)(memStart + nameAddr); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - + FixRelativePath(srcPath); BfpFile_GetFullPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } @@ -6729,7 +6780,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize); - + String srcPath; CE_CHECKADDR_STR(srcPath, srcAddr); @@ -6766,18 +6817,18 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_CHECKADDR_STR(env, envAddr); if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - + if ((targetPath.Contains('/')) || (targetPath.Contains('\\'))) { - FixRelativePath(targetPath); + FixRelativePath(targetPath); } - auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(), + auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(), (argsAddr == 0) ? NULL : args.c_str(), (workingDirAddr == 0) ? NULL : workingDir.c_str(), (envAddr == 0) ? NULL : env.c_str(), (BfpSpawnFlags)flags, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr)); if (bfpSpawn != NULL) - { + { CeInternalData* internalData = new CeInternalData(); internalData->mKind = CeInternalData::Kind_Spawn; internalData->mSpawn = bfpSpawn; @@ -6806,12 +6857,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* BfpFile* outStdErr = NULL; CeInternalData* internalData = NULL; - CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn); + CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn); BfpSpawn_GetStdHandles(internalData->mSpawn, (outStdInAddr != 0) ? &outStdIn : NULL, (outStdOutAddr != 0) ? &outStdOut : NULL, (outStdErrAddr != 0) ? &outStdErr : NULL); - + auto _SetHandle = [&](addr_ce addr, BfpFile* file) { if (addr == 0) @@ -6825,7 +6876,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeSetAddrVal(memStart + addr, mCurHandleId, ptrSize); } }; - + if (outStdInAddr != 0) _SetHandle(outStdInAddr, outStdIn); if (outStdOutAddr != 0) @@ -6867,7 +6918,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeInternalData* internalData = NULL; CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn); - + int outExitCode = 0; int timeLeft = waitMS; do @@ -6884,12 +6935,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* waitTime = BF_MIN(timeLeft, 20); timeLeft -= waitTime; } - + result = BfpSpawn_WaitFor(internalData->mSpawn, waitTime, &outExitCode, (outResultAddr == 0) ? NULL : (BfpSpawnResult*)(memStart + outResultAddr)); if (result) break; if (waitTime == 0) - break; + break; } while (true); *(int*)(memStart + outExitCodeAddr) = outExitCode; } @@ -6897,7 +6948,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { void* resultPtr = ((uint8*)stackPtr + 0); addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); - int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize); + int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4); String path; @@ -6916,7 +6967,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeRebuildKey rebuildKey; rebuildKey.mKind = CeRebuildKey::Kind_Directory; rebuildKey.mString = dir; - CeRebuildValue rebuildValue; + CeRebuildValue rebuildValue; if (AddRebuild(rebuildKey, rebuildValue)) mCurModule->mCompiler->mRebuildFileSet.Add(dir); @@ -6943,7 +6994,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize); addr_ce sizeAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize); - + CeInternalData* internalData = NULL; CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_FindFileData); CE_CHECKADDR(sizeAddr, 4); @@ -7012,7 +7063,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* return true; } - if (!checkFunction->mFailed) + if (!checkFunction->mFailed) return true; if ((mCeMachine->mDebugger != NULL) && (!mCallStack.IsEmpty())) @@ -7044,7 +7095,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeOp op = CE_GETINST(CeOp); if (*specialCheckPtr) - { + { SpecialCheck: if (*fastFinishPtr) { @@ -7059,10 +7110,10 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Comptime evaluation canceled"); } return false; - } + } bool wantsStop = false; - + if (mCeMachine->mStepState.mKind != CeStepState::Kind_None) { int curDepth = mCallStack.mSize + 1; @@ -7107,7 +7158,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* op = CE_GETINST(CeOp); wantsStop = true; break; - } + } } else if (mCeMachine->mDbgWantBreak) { @@ -7118,13 +7169,13 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* AutoCrit autoCrit(mCeMachine->mCritSect); mCallStack.Add(_GetCurFrame()); mCeMachine->mDebugger->UpdateBreakpointFrames(); - mCallStack.pop_back(); + mCallStack.pop_back(); } else *specialCheckPtr = false; if (wantsStop) - { + { mCeMachine->mDbgWantBreak = false; mCeMachine->mStepState.mKind = CeStepState::Kind_None; _DbgPause(); @@ -7133,9 +7184,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* // We may have changed breakpoints so we need to re-read instPtr -= sizeof(CeOp); op = CE_GETINST(CeOp); - } + } } - + OpSwitch: switch (op) { @@ -7157,9 +7208,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* mCallStack.Add(_GetCurFrame()); if (mCeMachine->mDebugger->CheckConditionalBreakpoint(breakpointEntry->mBreakpoint)) - doBreak = true; + doBreak = true; mCallStack.pop_back(); - + op = breakpointEntry->mPrevOpCode; // Keep us from an infinite loop if we set a breakpoint on a manual Break skipInst = op == CeOp_DbgBreak; @@ -7171,7 +7222,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _FixVariables(); if (skipInst) break; - goto OpSwitch; + goto OpSwitch; } mCeMachine->mDebugger->mActiveBreakpoint = breakpointEntry->mBreakpoint; @@ -7281,8 +7332,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CeSetAddrVal(&result, valueAddr, ptrSize); else CeSetAddrVal(&result, 0, ptrSize); - - } + } } break; case CeOp_GetReflectType: @@ -7291,7 +7341,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* int32 typeId = CE_GETINST(int32); auto reflectType = GetReflectType(typeId); _FixVariables(); - CeSetAddrVal(framePtr + frameOfs, reflectType, ptrSize); + CeSetAddrVal(framePtr + frameOfs, reflectType, ptrSize); } break; case CeOp_GetString: @@ -7305,7 +7355,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _FixVariables(); ceStringEntry.mBindExecuteId = mExecuteId; } - CeSetAddrVal(framePtr + frameOfs, ceStringEntry.mStringAddr, ptrSize); + CeSetAddrVal(framePtr + frameOfs, ceStringEntry.mStringAddr, ptrSize); } break; case CeOp_Malloc: @@ -7475,7 +7525,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_LOAD(uint32); break; case CeOp_Load_64: - CE_LOAD(uint64); + CE_LOAD(uint64); break; case CeOp_Load_X: { @@ -7574,7 +7624,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* case CeOp_AdjustSPConst: { int32 adjust = CE_GETINST(int32); - stackPtr += adjust; + stackPtr += adjust; } break; case CeOp_GetSP: @@ -7599,7 +7649,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto& ceStaticFieldEntry = ceFunction->mStaticFieldTable[tableIdx]; if (ceStaticFieldEntry.mBindExecuteId != mExecuteId) { - if (mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) + if ((mStaticCtorExecSet.TryAdd(ceStaticFieldEntry.mTypeId, NULL)) && (!ceStaticFieldEntry.mName.StartsWith("#"))) { auto bfType = GetBfType(ceStaticFieldEntry.mTypeId); BfTypeInstance* bfTypeInstance = NULL; @@ -7645,6 +7695,74 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (ceStaticFieldEntry.mSize > 0) memset(ptr, 0, ceStaticFieldEntry.mSize); staticFieldInfo->mAddr = (addr_ce)(ptr - memStart); + + if (ceStaticFieldEntry.mName.StartsWith("#")) + { + addr_ce resultAddr = 0; + + if (ceStaticFieldEntry.mName == "#CallerLineNum") + { + *(int*)ptr = mCurModule->mCurFilePosition.mCurLine; + } + else if (ceStaticFieldEntry.mName == "#CallerFilePath") + { + String filePath; + if (mCurModule->mCurFilePosition.mFileInstance != NULL) + filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName; + resultAddr = GetString(filePath); + } + else if (ceStaticFieldEntry.mName == "#CallerFileName") + { + String filePath; + if (mCurModule->mCurFilePosition.mFileInstance != NULL) + filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName; + resultAddr = GetString(GetFileName(filePath)); + } + else if (ceStaticFieldEntry.mName == "#CallerFileDir") + { + String filePath; + if (mCurModule->mCurFilePosition.mFileInstance != NULL) + filePath = mCurModule->mCurFilePosition.mFileInstance->mParser->mFileName; + resultAddr = GetString(GetFileDir(filePath)); + } + else if (ceStaticFieldEntry.mName == "#CallerTypeName") + { + String typeName = ""; + typeName = mCeMachine->mCeModule->TypeToString(mCallerTypeInstance); + resultAddr = GetString(typeName); + } + else if (ceStaticFieldEntry.mName == "#CallerType") + { + addr_ce typeAddr = GetReflectType(mCallerTypeInstance->mTypeId); + resultAddr = typeAddr; + } + else if (ceStaticFieldEntry.mName == "#CallerMemberName") + { + String memberName = mCeMachine->mCeModule->MethodToString(mCallerMethodInstance); + resultAddr = GetString(memberName); + } + else if (ceStaticFieldEntry.mName == "#CallerProject") + { + BfProject* project = NULL; + project = mCallerTypeInstance->mTypeDef->mProject; + if (project != NULL) + resultAddr = GetString(project->mName); + } + else if (ceStaticFieldEntry.mName == "#OrigCalleeType") + { + if (mCurCallSource->mOrigCalleeType != NULL) + { + addr_ce typeAddr = GetReflectType(mCurCallSource->mOrigCalleeType->mTypeId); + resultAddr = typeAddr; + } + } + + if (resultAddr != 0) + { + _FixVariables(); + CeSetAddrVal(memStart + staticFieldInfo->mAddr, resultAddr, ptrSize); + } + } } ceStaticFieldEntry.mAddr = staticFieldInfo->mAddr; @@ -8258,7 +8376,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* case CeOp_Shr_U64: CEOP_BIN2(>> , uint64, uint8); break; - + case CeOp_Acos_F32: CEOP_UNARY_FUNC(acosf, float); break; @@ -8367,7 +8485,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* case CeOp_Tanh_F64: CEOP_UNARY_FUNC(tanh, double); break; - + case CeOp_Cmp_NE_I8: CEOP_CMP(!= , int8); break; @@ -8585,7 +8703,7 @@ CeMachine::CeMachine(BfCompiler* compiler) mCurBuilder = NULL; mPreparingFunction = NULL; - mCurEmitContext = NULL; + mCurEmitContext = NULL; mAppendAllocInfo = NULL; mTempParser = NULL; @@ -8600,7 +8718,6 @@ CeMachine::CeMachine(BfCompiler* compiler) BfLogSys(mCompiler->mSystem, "CeMachine::CeMachine %p\n", this); } - CeMachine::~CeMachine() { BF_ASSERT(mDebugger == NULL); @@ -8687,7 +8804,7 @@ void CeMachine::CompileStarted() mRevisionExecuteTime = 0; mSpecialCheck = false; mRevision++; - mMethodBindRevision++; + mMethodBindRevision++; mDbgWantBreak = false; if (mCeModule != NULL) { @@ -8716,7 +8833,7 @@ int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx) { switch (kind) { - case CEOI_FrameRef: + case CEOI_FrameRef: case CEOI_FrameRef8: case CEOI_FrameRef16: case CEOI_FrameRef32: @@ -8739,7 +8856,7 @@ int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx) break; case CEOI_IMM_VAR: { - int32 size = CE_SIZE_GET(int32); + int32 size = CE_SIZE_GET(int32); ptr += size; } break; @@ -8754,10 +8871,10 @@ int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx) auto op = CE_SIZE_GET(CeOp); if (op == CeOp_DbgBreak) - { + { CeBreakpointBind* breakpointEntry = NULL; if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry)) - op = breakpointEntry->mPrevOpCode; + op = breakpointEntry->mPrevOpCode; } CeOpInfo& opInfo = gOpInfo[op]; @@ -8768,7 +8885,7 @@ int CeMachine::GetInstSize(CeFunction* ceFunction, int instIdx) _HandleOperand(opInfo.mOperandA); _HandleOperand(opInfo.mOperandB); _HandleOperand(opInfo.mOperandC); - + return (int)(ptr - startPtr); } @@ -8791,7 +8908,7 @@ void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo) void CeMachine::RemoveFunc(CeFunction* ceFunction) { mFunctionIdMap.Remove(ceFunction->mId); - ceFunction->mId = -1; + ceFunction->mId = -1; } void CeMachine::RemoveMethod(BfMethodInstance* methodInstance) @@ -8885,7 +9002,7 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV // if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr)) // { // CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr; -// +// // int* staticFieldTableIdxPtr = NULL; // if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr)) // { @@ -8896,22 +9013,21 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV // *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size(); // mCeFunction->mStaticFieldTable.Add(staticFieldEntry); // } -// +// // auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType)); -// +// // Emit(CeOp_GetStaticField); // EmitFrameOffset(result); // Emit((int32)*staticFieldTableIdxPtr); -// +// // return result; // } // return CeErrorKind_GlobalVariable; } - BF_ASSERT(!data.mQueueFixups); CeConstStructData gvData; - + auto result = WriteConstant(gvData, globalVar->mInitializer, ceContext); if (result != CeErrorKind_None) return result; @@ -8938,10 +9054,10 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV for (int memberIdx = 0; memberIdx < (int)constStruct->mMemberValues.size(); memberIdx++) { auto& member = structType->mMembers[memberIdx]; - // Do any per-member alignment + // Do any per-member alignment int wantZeroes = member.mByteOffset - (data.mData.mSize - startOfs); - if (wantZeroes > 0) - data.mData.Insert(data.mData.size(), (uint8)0, wantZeroes); + if (wantZeroes > 0) + data.mData.Insert(data.mData.size(), (uint8)0, wantZeroes); auto result = WriteConstant(data, constStruct->mMemberValues[memberIdx], ceContext); if (result != CeErrorKind_None) @@ -8993,7 +9109,7 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV { BF_FATAL("Invalid GEP"); } - + addr_ce addr = -1; if (globalVar->mName.StartsWith("__bfStrData")) @@ -9028,7 +9144,7 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV return CeErrorKind_GlobalVariable; // auto sym = GetSymbol(globalVar); - // + // // BeMCRelocation reloc; // reloc.mKind = BeMCRelocationKind_ADDR64; // reloc.mOffset = sect.mData.GetPos(); @@ -9041,7 +9157,7 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV BF_FATAL("Invalid GEPConstant"); } } - + /*else if ((beType->IsPointer()) && (constVal->mTarget != NULL)) { auto result = WriteConstant(arr, constVal->mTarget); @@ -9070,13 +9186,13 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV if (constVal->mType->mSize > 0) { auto ptr = data.mData.GrowUninitialized(constVal->mType->mSize); - memset(ptr, 0, constVal->mType->mSize); - } + memset(ptr, 0, constVal->mType->mSize); + } } else { auto ptr = data.mData.GrowUninitialized(beType->mSize); - memcpy(ptr, &constVal->mInt64, beType->mSize); + memcpy(ptr, &constVal->mInt64, beType->mSize); } } else @@ -9177,11 +9293,15 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) } else if (owner->IsInstanceOf(mCeModule->mCompiler->mCompilerTypeDef)) { - if (methodDef->mName == "Comptime_EmitTypeBody") + if (methodDef->mName == "Comptime_SetReturnType") + { + ceFunction->mFunctionKind = CeFunctionKind_SetReturnType; + } + else if (methodDef->mName == "Comptime_EmitTypeBody") { ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody; } - if (methodDef->mName == "Comptime_EmitAddInterface") + else if (methodDef->mName == "Comptime_EmitAddInterface") { ceFunction->mFunctionKind = CeFunctionKind_EmitAddInterface; } @@ -9217,6 +9337,8 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { if (methodDef->mName == "ThrowIndexOutOfRange") ceFunction->mFunctionKind = CeFunctionKind_OOB; + else if (methodDef->mName == "ThrowObjectNotInitialized") + ceFunction->mFunctionKind = CeFunctionKind_ObjectNotInitialized; else if (methodDef->mName == "FatalError") ceFunction->mFunctionKind = CeFunctionKind_FatalError; else if (methodDef->mName == "Dbg_RawAlloc") @@ -9241,8 +9363,8 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) else if (methodDef->mName == "BfpDirectory_Exists") ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_Exists; else if (methodDef->mName == "BfpDirectory_GetSysDirectory") - ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetSysDirectory; - + ceFunction->mFunctionKind = CeFunctionKind_BfpDirectory_GetSysDirectory; + else if (methodDef->mName == "BfpFile_Close") ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Close; else if (methodDef->mName == "BfpFile_Create") @@ -9313,7 +9435,7 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileSize; else if (methodDef->mName == "BfpFindFileData_Release") ceFunction->mFunctionKind = CeFunctionKind_BfpFindFileData_Release; - + else if (methodDef->mName == "BfpSystem_GetTimeStamp") ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp; } @@ -9394,7 +9516,7 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) ceFunction->mFunctionKind = CeFunctionKind_Math_Tan; else if (methodDef->mName == "Tanh") ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh; - } + } ceFunction->mInitializeState = CeFunction::InitializeState_Initialized; return; @@ -9405,7 +9527,7 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder) { AutoTimer autoTimer(mRevisionExecuteTime); - SetAndRestoreValue prevCEFunction(mPreparingFunction, ceFunction); + SetAndRestoreValue prevCEFunction(mPreparingFunction, ceFunction); BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized); @@ -9427,13 +9549,13 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder ceFunction->mInitializeState = CeFunction::InitializeState_Initializing_ReEntry; else ceFunction->mInitializeState = CeFunction::InitializeState_Initializing; - + CeBuilder ceBuilder; SetAndRestoreValue prevBuilder(mCurBuilder, &ceBuilder); ceBuilder.mParentBuilder = parentBuilder; ceBuilder.mPtrSize = mCeModule->mCompiler->mSystem->mPtrSize; ceBuilder.mCeMachine = this; - ceBuilder.mCeFunction = ceFunction; + ceBuilder.mCeFunction = ceFunction; ceBuilder.Build(); ceFunction->mInitializeState = CeFunction::InitializeState_Initialized; @@ -9452,7 +9574,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder } void CeMachine::MapFunctionId(CeFunction* ceFunction) -{ +{ if ((mCeModule->mSystem->mPtrSize == 8) && (mDebugger == NULL)) return; ceFunction->mId = ++mCurFunctionId; @@ -9460,7 +9582,7 @@ void CeMachine::MapFunctionId(CeFunction* ceFunction) } CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added) -{ +{ if (func) { if ((func.IsConst()) || (func.IsFake())) @@ -9470,10 +9592,10 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f CeFunctionInfo** functionInfoPtr = NULL; CeFunctionInfo* ceFunctionInfo = NULL; CeFunction* ceFunction = NULL; - if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr)) + if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr)) { - ceFunctionInfo = *functionInfoPtr; - BF_ASSERT(ceFunctionInfo->mCeFunction != NULL); + ceFunctionInfo = *functionInfoPtr; + BF_ASSERT(ceFunctionInfo->mCeFunction != NULL); return ceFunctionInfo->mCeFunction; } @@ -9481,10 +9603,10 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f methodInstance->mInCEMachine = true; BfLogSys(mCeModule->mSystem, "CeMachine::GetFunction %p\n", methodInstance); - + if (!func) { - ceFunctionInfo = new CeFunctionInfo(); + ceFunctionInfo = new CeFunctionInfo(); } else { @@ -9502,6 +9624,11 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f else { ceFunctionInfo = *namedFunctionInfoPtr; + if ((ceFunctionInfo->mMethodInstance != NULL) && (ceFunctionInfo->mMethodInstance != methodInstance)) + { + // This ceFunctionInfo is already taken - probably from a name mangling conflict + ceFunctionInfo = new CeFunctionInfo(); + } } } else @@ -9517,10 +9644,10 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f { added = true; auto module = methodInstance->GetOwner()->mModule; - + BF_ASSERT(ceFunctionInfo->mCeFunction == NULL); - ceFunction = new CeFunction(); + ceFunction = new CeFunction(); ceFunction->mCeMachine = this; ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar(); ceFunction->mCeFunctionInfo = ceFunctionInfo; @@ -9528,10 +9655,9 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f if (mDebugger != NULL) ceFunction->mDbgInfo = new CeDbgFunctionInfo(); ceFunctionInfo->mMethodInstance = methodInstance; - ceFunctionInfo->mCeFunction = ceFunction; + ceFunctionInfo->mCeFunction = ceFunction; MapFunctionId(ceFunction); } - return ceFunction; } @@ -9563,7 +9689,7 @@ CeTypeInfo* CeMachine::GetTypeInfo(BfType* type) return ceTypeInfo; ceTypeInfo->mMethodInstances.Clear(); } - + mCeModule->PopulateType(typeInstance, BfPopulateType_DataAndMethods); ceTypeInfo->mRevision = typeInstance->mRevision; for (auto& methodGroup : typeInstance->mMethodInstanceGroups) @@ -9571,7 +9697,7 @@ CeTypeInfo* CeMachine::GetTypeInfo(BfType* type) if (methodGroup.mOnDemandKind == BfMethodOnDemandKind_NoDecl_AwaitingReference) { auto methodDef = typeInstance->mTypeDef->mMethods[methodGroup.mMethodIdx]; - auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None; + auto flags = ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None; flags = (BfGetMethodInstanceFlags)(flags | BfGetMethodInstanceFlag_MethodInstanceOnly); mCeModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector(), flags); } @@ -9589,7 +9715,7 @@ CeTypeInfo* CeMachine::GetTypeInfo(BfType* type) ceTypeInfo->mMethodInstances.Add(kv.mValue); } } - } + } return ceTypeInfo; } @@ -9627,11 +9753,28 @@ void CeMachine::QueueMethod(BfModuleMethodInstance moduleMethodInstance) } void CeMachine::QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName) -{ +{ if (mCurBuilder != NULL) mCurBuilder->mStaticFieldInstanceMap[mangledFieldName] = fieldInstance; } +void CeMachine::ClearTypeData(BfTypeInstance* typeInstance) +{ + if (mTypeInfoMap.Remove(typeInstance)) + { + for (auto& methodGroup : typeInstance->mMethodInstanceGroups) + { + if (methodGroup.mDefault != NULL) + mMethodInstanceSet.Remove(methodGroup.mDefault); + if (methodGroup.mMethodSpecializationMap != NULL) + { + for (auto& kv : *methodGroup.mMethodSpecializationMap) + mMethodInstanceSet.Remove(kv.mValue); + } + } + } +} + void CeMachine::SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue) { delete mAppendAllocInfo; @@ -9663,9 +9806,9 @@ CeContext* CeMachine::AllocContext() memset(ceContext->mMemory.mVals, 0, BF_CE_INITIAL_MEMORY); } - ceContext->mCurEmitContext = mCurEmitContext; - mCurEmitContext = NULL; - mExecuteId++; + ceContext->mCurEmitContext = mCurEmitContext; + mCurEmitContext = NULL; + mExecuteId++; ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE; ceContext->mMemory.ResizeRaw(ceContext->mStackSize); ceContext->mExecuteId = mExecuteId; @@ -9680,26 +9823,24 @@ void CeMachine::ReleaseContext(CeContext* ceContext) ceContext->mConstDataMap.Clear(); ceContext->mMemory.Clear(); if (ceContext->mMemory.mAllocSize > BF_CE_MAX_CARRYOVER_MEMORY) - ceContext->mMemory.Dispose(); + ceContext->mMemory.Dispose(); ceContext->mStaticCtorExecSet.Clear(); ceContext->mStaticFieldMap.Clear(); ceContext->mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP); - ceContext->mReflectTypeIdOffset = -1; - mCurEmitContext = ceContext->mCurEmitContext; - ceContext->mCurEmitContext = NULL; + ceContext->mReflectTypeIdOffset = -1; + mCurEmitContext = ceContext->mCurEmitContext; + ceContext->mCurEmitContext = NULL; mContextList.Add(ceContext); for (auto kv : ceContext->mInternalDataMap) - kv.mValue->Release(); + kv.mValue->Release(); ceContext->mInternalDataMap.Clear(); ceContext->mWorkingDir.Clear(); } BfTypedValue CeMachine::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType) -{ +{ auto ceContext = AllocContext(); auto result = ceContext->Call(callSource, module, methodInstance, args, flags, expectingType); - ReleaseContext(ceContext); + ReleaseContext(ceContext); return result; -} - - +} \ No newline at end of file diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 77b2ecbc..1277b8ff 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -80,17 +80,17 @@ enum CeOp : int16 CeOp_JmpIf, CeOp_JmpIfNot, - CeOp_Error, + CeOp_Error, CeOp_DynamicCastCheck, CeOp_GetReflectType, CeOp_GetString, CeOp_Malloc, CeOp_Free, - + CeOp_MemSet, CeOp_MemSet_Const, CeOp_MemCpy, - + CeOp_FrameAddr_32, CeOp_FrameAddr_64, CeOp_FrameAddrOfs_32, @@ -116,7 +116,7 @@ enum CeOp : int16 CeOp_GetMethod_Virt, CeOp_GetMethod_IFace, CeOp_Call, - + CeOp_Conv_I8_I16, CeOp_Conv_I8_I32, CeOp_Conv_I8_I64, @@ -128,7 +128,7 @@ enum CeOp : int16 CeOp_Conv_I16_F64, CeOp_Conv_I32_I64, CeOp_Conv_I32_F32, - CeOp_Conv_I32_F64, + CeOp_Conv_I32_F64, CeOp_Conv_I64_F32, CeOp_Conv_I64_F64, CeOp_Conv_U8_U16, @@ -168,7 +168,7 @@ enum CeOp : int16 CEOP_SIZED_NUMERIC_PLUSF(AddConst), CEOP_SIZED_NUMERIC_PLUSF(Add), CEOP_SIZED_NUMERIC_PLUSF(Sub), - CEOP_SIZED_NUMERIC_PLUSF(Mul), + CEOP_SIZED_NUMERIC_PLUSF(Mul), CEOP_SIZED_NUMERIC_PLUSF(Div), CEOP_SIZED_UNUMERIC(Div), CEOP_SIZED_NUMERIC_PLUSF(Mod), @@ -179,7 +179,7 @@ enum CeOp : int16 CEOP_SIZED_NUMERIC(Shl), CEOP_SIZED_NUMERIC(Shr), CEOP_SIZED_UNUMERIC(Shr), - + CEOP_SIZED_FLOAT(Acos), CEOP_SIZED_FLOAT(Asin), CEOP_SIZED_FLOAT(Atan), @@ -190,7 +190,7 @@ enum CeOp : int16 CEOP_SIZED_FLOAT(Exp), CEOP_SIZED_FLOAT(Floor), CEOP_SIZED_FLOAT(Log), - CEOP_SIZED_FLOAT(Log10), + CEOP_SIZED_FLOAT(Log10), CEOP_SIZED_FLOAT(Pow), CEOP_SIZED_FLOAT(Round), CEOP_SIZED_FLOAT(Sin), @@ -198,7 +198,7 @@ enum CeOp : int16 CEOP_SIZED_FLOAT(Sqrt), CEOP_SIZED_FLOAT(Tan), CEOP_SIZED_FLOAT(Tanh), - + CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ), CEOP_SIZED_NUMERIC_PLUSF(Cmp_NE), CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT), @@ -307,7 +307,7 @@ public: }; struct CeDbgInlineEntry -{ +{ int mScope; int mLine; int mColumn; @@ -331,6 +331,13 @@ public: } ~CeFunctionInfo(); + + BfTypeInstance* GetOwner() + { + if (mMethodInstance != NULL) + return mMethodInstance->GetOwner(); + return mMethodRef.mTypeInstance; + } }; class CeCallEntry @@ -415,6 +422,7 @@ enum CeFunctionKind CeFunctionKind_Normal, CeFunctionKind_Extern, CeFunctionKind_OOB, + CeFunctionKind_ObjectNotInitialized, CeFunctionKind_Malloc, CeFunctionKind_Free, CeFunctionKind_DynCheckFailed, @@ -439,13 +447,14 @@ enum CeFunctionKind CeFunctionKind_Method_GetInfo, CeFunctionKind_Method_GetParamInfo, CeFunctionKind_Method_GetGenericArg, - + + CeFunctionKind_SetReturnType, CeFunctionKind_EmitTypeBody, CeFunctionKind_EmitAddInterface, CeFunctionKind_EmitMethodEntry, CeFunctionKind_EmitMethodExit, CeFunctionKind_EmitMixin, - + CeFunctionKind_BfpDirectory_Create, CeFunctionKind_BfpDirectory_Rename, CeFunctionKind_BfpDirectory_Delete, @@ -474,7 +483,7 @@ enum CeFunctionKind CeFunctionKind_BfpFile_GetTempFileName, CeFunctionKind_BfpFile_GetFullPath, CeFunctionKind_BfpFile_GetActualPath, - + CeFunctionKind_BfpFindFileData_FindFirstFile, CeFunctionKind_BfpFindFileData_FindNextFile, CeFunctionKind_BfpFindFileData_GetFileName, @@ -512,7 +521,7 @@ enum CeFunctionKind CeFunctionKind_Math_Asin, CeFunctionKind_Math_Atan, CeFunctionKind_Math_Atan2, - CeFunctionKind_Math_Ceiling, + CeFunctionKind_Math_Ceiling, CeFunctionKind_Math_Cos, CeFunctionKind_Math_Cosh, CeFunctionKind_Math_Exp, @@ -526,7 +535,7 @@ enum CeFunctionKind CeFunctionKind_Math_Sinh, CeFunctionKind_Math_Sqrt, CeFunctionKind_Math_Tan, - CeFunctionKind_Math_Tanh, + CeFunctionKind_Math_Tanh, }; class CeConstStructFixup @@ -587,14 +596,14 @@ public: { mTypeId = -1; mSize = 0; - mAddr = 0; - mBindExecuteId = -1; + mAddr = 0; + mBindExecuteId = -1; } }; class CeDbgVariable { -public: +public: String mName; CeOperand mValue; BfType* mType; @@ -632,17 +641,17 @@ public: CeMachine* mCeMachine; CeFunctionInfo* mCeFunctionInfo; CeInnerFunctionInfo* mCeInnerFunctionInfo; - BfMethodInstance* mMethodInstance; - CeFunctionKind mFunctionKind; + BfMethodInstance* mMethodInstance; + CeFunctionKind mFunctionKind; InitializeState mInitializeState; bool mFailed; bool mIsVarReturn; - Array mCode; + Array mCode; Array mDbgScopes; Array mDbgInlineTable; Array mDbgMethodRefTable; - Array mEmitTable; - Array mCallTable; + Array mEmitTable; + Array mCallTable; Array mStringTable; Array mConstStructTable; Array mStaticFieldTable; @@ -650,7 +659,7 @@ public: Array mInnerFunctions; Dictionary mBreakpoints; String mGenError; - int mFrameSize; + int mFrameSize; int mMaxReturnSize; int mId; int mBreakpointVersion; @@ -662,7 +671,7 @@ public: mCeMachine = NULL; mCeFunctionInfo = NULL; mCeInnerFunctionInfo = NULL; - mFunctionKind = CeFunctionKind_NotSet; + mFunctionKind = CeFunctionKind_NotSet; mInitializeState = InitializeState_None; mMethodInstance = NULL; mFailed = false; @@ -672,7 +681,7 @@ public: mBreakpointVersion = 0; mId = -1; mDbgInfo = NULL; - } + } ~CeFunction(); void Print(); @@ -738,7 +747,7 @@ enum CeSizeClass class CeDumpContext { -public: +public: Dictionary mVarMap; CeFunction* mCeFunction; String mStr; @@ -756,13 +765,13 @@ public: void DumpOperandInfo(CeOperandInfoKind operandInfoKind); void Next(); - void Dump(); + void Dump(); }; struct CePhiOutgoing { BeValue* mPhiValue; - BePhiInst* mPhiInst; + BePhiInst* mPhiInst; int mPhiBlockIdx; }; @@ -775,7 +784,7 @@ public: public: CeBlock() { - mEmitOfs = -1; + mEmitOfs = -1; } }; @@ -802,7 +811,7 @@ struct CeDbgInlineLookup mDbgFile = NULL; mInlineAtIdx = -1; } - + bool operator==(const CeDbgInlineLookup& second) const { return (mDbgFile == second.mDbgFile) && (mDbgFile == second.mDbgFile); @@ -811,18 +820,18 @@ struct CeDbgInlineLookup class CeBuilder { -public: +public: CeBuilder* mParentBuilder; - CeMachine* mCeMachine; + CeMachine* mCeMachine; CeFunction* mCeFunction; - BeFunction* mBeFunction; + BeFunction* mBeFunction; CeOperand mReturnVal; BeType* mIntPtrType; - int mPtrSize; + int mPtrSize; String mError; BeDbgLoc* mCurDbgLoc; - Array mBlocks; + Array mBlocks; Array mJumpTable; Dictionary mValueToOperand; int mFrameSize; @@ -836,7 +845,7 @@ public: Dictionary mStaticFieldMap; Dictionary mStaticFieldInstanceMap; Dictionary mDbgVariableMap; - + public: CeBuilder() { @@ -848,7 +857,7 @@ public: mCurDbgLoc = NULL; mFrameSize = 0; } - + void Fail(const StringImpl& error); CeOperand FrameAlloc(BeType* type); @@ -862,7 +871,7 @@ public: int GetCodePos(); void HandleParams(); - + void Emit(uint8 val); void Emit(CeOp val); void EmitSizedOp(CeOp val, int size); @@ -872,7 +881,7 @@ public: void Emit(void* ptr, int size); void EmitZeroes(int size); void EmitJump(CeOp op, const CeOperand& block); - void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx); + void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx); void EmitFrameOffset(const CeOperand& val); void FlushPhi(CeBlock* ceBlock, int targetBlockIdx); @@ -911,7 +920,7 @@ public: class CeStaticFieldInfo { -public: +public: addr_ce mAddr; public: @@ -961,16 +970,16 @@ public: class CeEmitContext { public: - BfType* mType; + BfType* mType; BfMethodInstance* mMethodInstance; - Array mInterfaces; + Array mInterfaces; String mEmitData; String mExitEmitData; bool mFailed; CeEmitContext() { - mType = NULL; + mType = NULL; mMethodInstance = NULL; mFailed = false; } @@ -1050,6 +1059,7 @@ public: Kind mKind; BfAstNode* mRefNode; BfFieldInstance* mFieldInstance; + BfType* mOrigCalleeType; public: CeCallSource(BfAstNode* refNode) @@ -1057,6 +1067,7 @@ public: mKind = Kind_Unknown; mRefNode = refNode; mFieldInstance = NULL; + mOrigCalleeType = NULL; } CeCallSource() @@ -1064,6 +1075,7 @@ public: mKind = Kind_Unknown; mRefNode = NULL; mFieldInstance = NULL; + mOrigCalleeType = NULL; } }; @@ -1076,15 +1088,15 @@ public: int mExecuteId; CeEvalFlags mCurEvalFlags; - // These are only valid for the current execution + // These are only valid for the current execution ContiguousHeap* mHeap; Array mCallStack; Array mMemory; int mStackSize; Dictionary mStringMap; Dictionary mReflectMap; - Dictionary mConstDataMap; - HashSet mStaticCtorExecSet; + Dictionary mConstDataMap; + HashSet mStaticCtorExecSet; Dictionary mStaticFieldMap; Dictionary mInternalDataMap; int mCurHandleId; @@ -1097,16 +1109,16 @@ public: CeCallSource* mCurCallSource; BfModule* mCurModule; CeFrame* mCurFrame; - CeEmitContext* mCurEmitContext; + CeEmitContext* mCurEmitContext; String mWorkingDir; public: CeContext(); ~CeContext(); - + BfError* Fail(const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error); - + void CalcWorkingDir(); void FixRelativePath(StringImpl& path); bool AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value); @@ -1131,11 +1143,11 @@ public: bool GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeIdx, addr_ce resultAddr); BfType* GetCustomAttributeType(BfCustomAttributes* customAttributes, int attributeIdx); - bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false); - BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL); + bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false); + BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL); BfIRValue CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute, addr_ce ceAttrAddr = 0); - bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType); + bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType, BfType*& castReturnType); BfTypedValue Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType); }; @@ -1161,14 +1173,14 @@ public: Kind_Evaluate }; - Kind mKind; + Kind mKind; int mNextInstIdx; int mStartDepth; public: CeStepState() { - mKind = Kind_None; + mKind = Kind_None; mNextInstIdx = -1; mStartDepth = 0; } @@ -1182,24 +1194,24 @@ public: Dictionary mFunctionIdMap; // Only used for 32-bit and debugging Dictionary mTypeInfoMap; HashSet mMethodInstanceSet; - HashSet mFieldInstanceSet; - + HashSet mFieldInstanceSet; + Array mContextList; BfCompiler* mCompiler; BfModule* mCeModule; int mRevision; int mMethodBindRevision; - int mRevisionExecuteTime; - int mCurFunctionId; + int mRevisionExecuteTime; + int mCurFunctionId; int mExecuteId; - CeAppendAllocInfo* mAppendAllocInfo; - + CeAppendAllocInfo* mAppendAllocInfo; + CeContext* mCurContext; CeEmitContext* mCurEmitContext; CeCallSource* mCurCallSource; CeBuilder* mCurBuilder; - CeFunction* mPreparingFunction; + CeFunction* mPreparingFunction; BfParser* mTempParser; BfReducer* mTempReducer; @@ -1209,27 +1221,27 @@ public: SyncEvent mDebugEvent; CeStepState mStepState; CeDebugger* mDebugger; - bool mDbgPaused; + bool mDbgPaused; bool mSpecialCheck; bool mDbgWantBreak; public: CeMachine(BfCompiler* compiler); - ~CeMachine(); + ~CeMachine(); - void Init(); + void Init(); BeContext* GetBeContext(); BeModule* GetBeModule(); int GetInstSize(CeFunction* ceFunction, int instIdx); void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo); void RemoveFunc(CeFunction* ceFunction); - void RemoveMethod(BfMethodInstance* methodInstance); - void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction); - CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext); + void RemoveMethod(BfMethodInstance* methodInstance); + void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction); + CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext); void CheckFunctionKind(CeFunction* ceFunction); - void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder); + void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder); void MapFunctionId(CeFunction* ceFunction); void CheckFunctions(); @@ -1237,14 +1249,15 @@ public: CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance); CeTypeInfo* GetTypeInfo(BfType* type); BfMethodInstance* GetMethodInstance(int64 methodHandle); - BfFieldInstance* GetFieldInstance(int64 fieldHandle); + BfFieldInstance* GetFieldInstance(int64 fieldHandle); public: void CompileStarted(); void CompileDone(); CeFunction* QueueMethod(BfMethodInstance* methodInstance, BfIRValue func); void QueueMethod(BfModuleMethodInstance moduleMethodInstance); - void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName); + void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName); + void ClearTypeData(BfTypeInstance* typeInstance); void SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue); void ClearAppendAllocInfo(); @@ -1265,7 +1278,7 @@ namespace std { return BeefHash()(key.mString) ^ (size_t)key.mKind; } - }; + }; template <> struct hash diff --git a/IDEHelper/Compiler/MemReporter.cpp b/IDEHelper/Compiler/MemReporter.cpp index afae1de3..965d5fe8 100644 --- a/IDEHelper/Compiler/MemReporter.cpp +++ b/IDEHelper/Compiler/MemReporter.cpp @@ -16,7 +16,7 @@ MemReporter::~MemReporter() int MemReporter::GetChildSizes(Entry* entry) { int childSizes = 0; - for (auto& childPair : entry->mChildren) + for (auto& childPair : entry->mChildren) { auto child = childPair.mValue; childSizes += child->mSize + GetChildSizes(child); @@ -29,10 +29,10 @@ void MemReporter::Report(int depth, Entry* entry) String str; for (int i = 0; i < depth; i++) str += " "; - + str += entry->mName; while (str.length() < 64) - str += ' '; + str += ' '; if (entry->mChildSize == -1) entry->mChildSize = GetChildSizes(entry); @@ -45,7 +45,7 @@ void MemReporter::Report(int depth, Entry* entry) Array entries; for (auto& kv : entry->mChildren) - { + { auto* entry = kv.mValue; entry->mChildSize = GetChildSizes(entry); entries.Add(kv.mValue); @@ -63,7 +63,7 @@ void MemReporter::BeginSection(const StringView& name) { Entry** entryPtr; if (!mCurEntry->mChildren.TryAdd(StringImpl::MakeRef(name), NULL, &entryPtr)) - { + { mCurEntry = *entryPtr; mCurEntry->mCount++; return; @@ -95,6 +95,6 @@ void MemReporter::EndSection() } void MemReporter::Report() -{ +{ Report(0, &mRoot); -} +} \ No newline at end of file diff --git a/IDEHelper/Compiler/MemReporter.h b/IDEHelper/Compiler/MemReporter.h index ea0ff7ff..1ad8ef12 100644 --- a/IDEHelper/Compiler/MemReporter.h +++ b/IDEHelper/Compiler/MemReporter.h @@ -36,24 +36,24 @@ public: Entry* mCurEntry; bool mShowInKB; -public: +public: int GetChildSizes(Entry* entry); void Report(int depth, Entry* entry); -public: +public: MemReporter(); ~MemReporter(); void BeginSection(const StringView& name); void Add(int size); void Add(const StringView& name, int size); - + template void AddVec(const T& vec, bool addContainerSize = true) { Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type)); } - + template void AddVec(const StringView& name, const T& vec, bool addContainerSize = true) { @@ -61,21 +61,21 @@ public: Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type)); EndSection(); } - + template void AddVecPtr(const std::vector& vec, bool addContainerSize = true) { Add((addContainerSize ? sizeof(T) : 0) + - (int)vec.capacity() * sizeof(T) + + (int)vec.capacity() * sizeof(T) + (int)vec.size() * sizeof(typename std::remove_pointer::type)); //-V220 } - + template void AddVecPtr(const Array& vec, bool addContainerSize = true) { Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(T) + - (int)vec.size() * sizeof(typename std::remove_pointer::type)); //-V220 + (int)vec.size() * sizeof(typename std::remove_pointer::type)); //-V220 } template @@ -83,12 +83,12 @@ public: { Add(name, (addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(T) + - (int)vec.size() * sizeof(typename std::remove_pointer::type)); //-V220 + (int)vec.size() * sizeof(typename std::remove_pointer::type)); //-V220 } template void AddMap(const StringView& name, const T& map, bool addContainerSize = true) - { + { Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize))); } @@ -109,7 +109,7 @@ public: { Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize))); } - + void AddStr(const StringImpl& str, bool addContainerSize = true) { Add((addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize()); @@ -123,12 +123,11 @@ public: void EndSection(); void Report(); - template void AddBumpAlloc(const StringView& name, const T& alloc) - { + { BeginSection(name); - + int usedSize = alloc.CalcUsedSize(); #ifdef BUMPALLOC_TRACKALLOCS @@ -162,9 +161,9 @@ public: Add("Unaccounted", usedSizeLeft); #else Add("Used", usedSize); -#endif +#endif Add("Waste", alloc.GetAllocSize() - usedSize); - Add("Unused", alloc.GetTotalAllocSize() - alloc.GetAllocSize()); + Add("Unused", alloc.GetTotalAllocSize() - alloc.GetAllocSize()); EndSection(); } @@ -173,7 +172,7 @@ public: class AutoMemReporter { public: - MemReporter* mMemReporter; + MemReporter* mMemReporter; public: AutoMemReporter(MemReporter* memReporter, const StringImpl& name) diff --git a/IDEHelper/DWARFInfo.h b/IDEHelper/DWARFInfo.h index 47a0aaca..645763fa 100644 --- a/IDEHelper/DWARFInfo.h +++ b/IDEHelper/DWARFInfo.h @@ -453,7 +453,7 @@ enum DW_OP_breg12 = 0x7C, DW_OP_breg13 = 0x7D, DW_OP_breg14 = 0x7E, - DW_OP_breg15 = 0x7F, + DW_OP_breg15 = 0x7F, DW_OP_breg31 = 0x8f, DW_OP_regx = 0x90, DW_OP_fbreg = 0x91, @@ -520,7 +520,7 @@ enum DW_CFA_hi_user = 0x3f, }; -enum SymbolFlags +enum SymbolFlags { SF_TypeMask = 0x0000FFFF, SF_TypeShift = 0, @@ -576,7 +576,7 @@ enum SymbolStorageClass COFF_SYM_CLASS_CLR_TOKEN = 107 }; -enum SymbolBaseType +enum SymbolBaseType { COFF_SYM_TYPE_NULL = 0, ///< No type information or unknown base type. COFF_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions. @@ -596,7 +596,7 @@ enum SymbolBaseType COFF_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer. }; -enum SymbolComplexType +enum SymbolComplexType { COFF_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable. COFF_SYM_DTYPE_POINTER = 1, ///< A pointer to base type. @@ -642,4 +642,3 @@ enum RelocationTypeAMD64 COFF_REL_AMD64_PAIR = 0x000F, COFF_REL_AMD64_SSPAN32 = 0x0010 }; - diff --git a/IDEHelper/DbgEvalPool.cpp b/IDEHelper/DbgEvalPool.cpp index 02b87400..fe4959f7 100644 --- a/IDEHelper/DbgEvalPool.cpp +++ b/IDEHelper/DbgEvalPool.cpp @@ -12,7 +12,5 @@ DbgEvalPool::Entry* DbgEvalPool::Add(const std::string& expr, int callStackIdx, entry->mAllowCall = allowCalls; entry->mExpressionFlags = expressionFlags; - - return NULL; } \ No newline at end of file diff --git a/IDEHelper/DbgEvalPool.h b/IDEHelper/DbgEvalPool.h index 097e7847..8246b45a 100644 --- a/IDEHelper/DbgEvalPool.h +++ b/IDEHelper/DbgEvalPool.h @@ -16,7 +16,7 @@ public: int mAllowAssignment; int mAllowCall; int mExpressionFlags; - }; + }; public: std::vector mEntryList; diff --git a/IDEHelper/DbgExprEvaluator.cpp b/IDEHelper/DbgExprEvaluator.cpp index 2b2a78d3..52ff9ac0 100644 --- a/IDEHelper/DbgExprEvaluator.cpp +++ b/IDEHelper/DbgExprEvaluator.cpp @@ -21,7 +21,7 @@ using namespace llvm; DwMethodMatcher::DwMethodMatcher(BfAstNode* targetSrc, DbgExprEvaluator* exprEvaluator, const StringImpl& methodName, SizedArrayImpl& arguments, BfSizedArray* methodGenericArguments) : mArguments(arguments) -{ +{ mTargetSrc = targetSrc; mExprEvaluator = exprEvaluator; mMethodName = methodName; @@ -29,12 +29,12 @@ DwMethodMatcher::DwMethodMatcher(BfAstNode* targetSrc, DbgExprEvaluator* exprEva mBestMethodDef = NULL; mBackupMethodDef = NULL; mBestMethodTypeInstance = NULL; - mExplicitInterfaceCheck = NULL; - mHadExplicitGenericArguments = false; + mExplicitInterfaceCheck = NULL; + mHadExplicitGenericArguments = false; mTargetIsConst = false; if (methodGenericArguments != NULL) - { + { for (auto genericArg : *methodGenericArguments) { if (genericArg == NULL) @@ -46,7 +46,7 @@ DwMethodMatcher::DwMethodMatcher(BfAstNode* targetSrc, DbgExprEvaluator* exprEva //mBestMethodGenericArgumentSrcs.push_back(genericArg); } mHadExplicitGenericArguments = true; - } + } } /*bool DwMethodMatcher::InferGenericArgument(DbgType* argType, DbgType* wantType) @@ -60,15 +60,15 @@ DwMethodMatcher::DwMethodMatcher(BfAstNode* targetSrc, DbgExprEvaluator* exprEva if (wantGenericParam->mGenericParamKind == BfGenericParamKind_Method) { auto prevGenericMethodArg = mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx]; - if (prevGenericMethodArg == NULL) + if (prevGenericMethodArg == NULL) { mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] = argType; return true; - } + } // Prev is already best if (mModule->CanCast(DbgTypedValue(NULL, argType), prevGenericMethodArg)) - return true; + return true; // New best? if (mModule->CanCast(DbgTypedValue(NULL, prevGenericMethodArg), argType)) @@ -115,18 +115,18 @@ DwMethodMatcher::DwMethodMatcher(BfAstNode* targetSrc, DbgExprEvaluator* exprEva if (!argType->IsPointer()) return true; auto wantPointerType = (BfPointerType*) wantType; - auto argPointerType = (BfPointerType*) argType; + auto argPointerType = (BfPointerType*) argType; InferGenericArgument(argPointerType->mElementType, wantPointerType->mElementType); return true; } - - return true; + + return true; }*/ void DwMethodMatcher::CompareMethods(DbgSubprogram* prevMethodInstance, DwTypeVector* prevGenericArgumentsSubstitute, - DbgSubprogram* newMethodInstance, DwTypeVector* genericArgumentsSubstitute, + DbgSubprogram* newMethodInstance, DwTypeVector* genericArgumentsSubstitute, bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail) -{ +{ int numUsedParams = 0; int prevNumUsedParams = 0; bool usedExtendedForm = false; @@ -135,16 +135,16 @@ void DwMethodMatcher::CompareMethods(DbgSubprogram* prevMethodInstance, DwTypeVe bool isBetter = false; bool isWorse = false; int argIdx = 0; - + DbgSubprogram* prevMethodDef = prevMethodInstance; DbgSubprogram* newMethodDef = newMethodInstance; #define SET_BETTER_OR_WORSE(lhs, rhs) \ if ((lhs) && !(rhs)) isBetter = true; \ if (!(lhs) && (rhs)) isWorse = true; - + int newArgOffset = newMethodInstance->mHasThis ? 1 : 0; - int prevArgOffset = prevMethodInstance->mHasThis ? 1 : 0; + int prevArgOffset = prevMethodInstance->mHasThis ? 1 : 0; DbgVariable* param = newMethodInstance->mParams.mHead; if (newMethodInstance->mHasThis) @@ -267,7 +267,7 @@ void DwMethodMatcher::CompareMethods(DbgSubprogram* prevMethodInstance, DwTypeVe DbgType* paramType = param->mType; DbgType* prevParamType = prevParam->mType; - //TODO: + //TODO: //isBetter |= mModule->IsTypeMoreSpecific(paramType, prevParamType); //isWorse |= mModule->IsTypeMoreSpecific(prevParamType, paramType); @@ -293,13 +293,13 @@ void DwMethodMatcher::CompareMethods(DbgSubprogram* prevMethodInstance, DwTypeVe if ((newMethodInstance->mHasThis) && (prevMethodInstance->mHasThis)) { SET_BETTER_OR_WORSE( - newMethodInstance->mParams.mHead->mType->IsConst() == mTargetIsConst, + newMethodInstance->mParams.mHead->mType->IsConst() == mTargetIsConst, prevMethodInstance->mParams.mHead->mType->IsConst() == mTargetIsConst); } } *outNewIsBetter = isBetter; - *outNewIsWorse = isWorse; + *outNewIsWorse = isWorse; } bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMethod) @@ -308,7 +308,7 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet checkMethod->PopulateSubprogram(); - // Never consider overrides - they only get found at original method declaration + // Never consider overrides - they only get found at original method declaration /*if ((checkMethod->mVirtual) && (checkMethod->mVTableLoc == -1)) return true;*/ @@ -319,24 +319,24 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) { DwAutoComplete::MethodMatchEntry methodMatchEntry; - methodMatchEntry.mDwSubprogram = methodInstance; - autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); + methodMatchEntry.mDwSubprogram = methodInstance; + autoComplete->mMethodMatchInfo->mInstanceList.push_back(methodMatchEntry); } /*if ((mHadExplicitGenericArguments) && (checkMethod->mGenericParams.size() != mBestMethodGenericArguments.size())) goto NoMatch;*/ - + for (auto& checkGenericArgRef : mCheckMethodGenericArguments) checkGenericArgRef = NULL; - /*mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size()); + /*mCheckMethodGenericArguments.resize(checkMethod->mGenericParams.size()); for (auto& genericArgRef : mCheckMethodGenericArguments) genericArgRef = NULL;*/ - + int argIdx = 0; - int paramIdx = 0; + int paramIdx = 0; DbgType* paramsElementType = NULL; - + //bool needInferGenericParams = (checkMethod->mGenericParams.size() != 0) && (!mHadExplicitGenericArguments); DwTypeVector* genericArgumentsSubstitute = NULL; @@ -358,21 +358,21 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet goto NoMatch; } } - + for (int checkArgIdx = 0; checkArgIdx < (int) checkMethod->mGenericParams.size(); checkArgIdx++) if (mCheckMethodGenericArguments[checkArgIdx] == NULL) goto NoMatch; }*/ // Iterate through params - + int paramOffset = checkMethod->mHasThis ? 1 : 0; while (true) - { + { // Too many arguments if (paramIdx >= checkMethod->mParams.Size() - paramOffset) - { + { break; } @@ -395,7 +395,7 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet paramIdx++; break; } - + BF_ASSERT(paramsArrayType->IsArray()); auto arrayType = (BfArrayType*)paramsArrayType; paramsElementType = arrayType->mTypeGenericArguments[0]; @@ -429,10 +429,9 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet if (!mArguments[argIdx]) goto NoMatch; - if (!mExprEvaluator->CanCast(mArguments[argIdx], wantType)) goto NoMatch; - + paramIdx++; argIdx++; @@ -444,12 +443,12 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet bool isBetter = false; bool isWorse = false; int methodIdx = (int)methodMatchInfo->mInstanceList.size() - 1; - + if (methodMatchInfo->mBestIdx < (int)methodMatchInfo->mInstanceList.size()) - { + { auto prevMethodMatchEntry = &methodMatchInfo->mInstanceList[methodMatchInfo->mBestIdx]; if (checkMethod->mParams.Size() < (int)mArguments.size()) - { + { isWorse = true; } else if (prevMethodMatchEntry->mDwSubprogram->mParams.Size() < (int) mArguments.size()) @@ -464,7 +463,7 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet methodInstance, genericArgumentsSubstitute, &isBetter, &isWorse, true); } } - + if ((argIdx > methodMatchInfo->mMostParamsMatched) || ((argIdx == methodMatchInfo->mMostParamsMatched) && (isBetter)) || ((argIdx == methodMatchInfo->mMostParamsMatched) && (methodIdx == methodMatchInfo->mPrevBestIdx) && (!isWorse))) @@ -479,7 +478,7 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet //TODO: Does this ever get hit? // Not enough arguments? if (argIdx < (int)mArguments.size()) - { + { goto NoMatch; } @@ -503,11 +502,11 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet methodInstance->ToString().c_str()), mTargetSrc); } } - + if (!isBetter) goto Done; } - + if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo)) { auto methodMatchInfo = autoComplete->mMethodMatchInfo; @@ -525,10 +524,10 @@ bool DwMethodMatcher::CheckMethod(DbgType* typeInstance, DbgSubprogram* checkMet NoMatch: if (!hadMatch) - { + { if (mBestMethodDef != NULL) return true; - + //TODO: /*if ((mHadExplicitGenericArguments) && (mBestMethodGenericArguments.size() != checkMethod->mGenericParams.size())) return true;*/ @@ -536,25 +535,25 @@ NoMatch: // At least prefer a backup method that we have an address for if ((mBackupMethodDef != NULL) && (mBackupMethodDef->mBlock.mLowPC != 0)) return true; - + mBackupMethodDef = checkMethod; // Lie temporarily to store at least one candidate (but mBestMethodDef is still NULL) hadMatch = true; } - + if (hadMatch) { mBestMethodTypeInstance = typeInstance; if (!mHadExplicitGenericArguments) - { - mBestMethodGenericArguments = mCheckMethodGenericArguments; - } + { + mBestMethodGenericArguments = mCheckMethodGenericArguments; + } } Done: if ((autoComplete != NULL) && (autoComplete->mIsCapturingMethodMatchInfo) && (genericArgumentsSubstitute != NULL)) { - auto methodMatchInfo = autoComplete->mMethodMatchInfo; + auto methodMatchInfo = autoComplete->mMethodMatchInfo; methodMatchInfo->mInstanceList[methodMatchInfo->mInstanceList.size() - 1].mDwGenericArguments = *genericArgumentsSubstitute; } @@ -573,7 +572,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) bool allowPrivate = true; bool allowProtected = true; - auto curType = typeInstance; + auto curType = typeInstance; bool wantCtor = false; @@ -581,7 +580,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) auto altItr = typeInstance->mAlternates.begin(); while (true) - { + { bool foundMethodInType = false; curType->PopulateType(); @@ -593,7 +592,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) // These aren't proper TPI types so we don't have any method declarations until we PopulateTypeGlobals mExprEvaluator->mDbgModule->PopulateTypeGlobals(curType); } - + for (auto methodNameEntry : curType->mMethodNameList) { if ((methodNameEntry->mCompileUnitId != -1) && (methodNameEntry->mName == mMethodName)) @@ -602,7 +601,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) if (!curType->mCompileUnit->mDbgModule->IsObjectFile()) curType->mCompileUnit->mDbgModule->MapCompileUnitMethods(methodNameEntry->mCompileUnitId); methodNameEntry->mCompileUnitId = -1; - } + } } auto checkMethod = curType->mMethodList.mHead; @@ -641,12 +640,12 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) checkMethod = checkMethod->mNext; continue; } - + if (!curType->mHasGlobalsPopulated) - mExprEvaluator->mDbgModule->PopulateTypeGlobals(curType); + mExprEvaluator->mDbgModule->PopulateTypeGlobals(curType); /*if (!foundMethodInType) - { + { if (curType->mCompileUnit->mLanguage != DbgLanguage_Beef) { String fullMethodName = String(curType->mTypeName) + "::" + mMethodName; @@ -659,7 +658,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) return false; checkMethod = checkMethod->mNext; - } + } if (mBestMethodDef != NULL) { @@ -672,7 +671,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) else return true; } - + /*if (baseItr != typeInstance->mBaseTypes.end()) { auto baseTypeEntry = *baseItr; @@ -680,13 +679,13 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) baseItr++; continue;; }*/ - + if (altItr != typeInstance->mAlternates.end()) - { + { curType = *altItr; ++altItr; continue; - } + } /*allowPrivate = false; @@ -694,11 +693,11 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) break;*/ break; } - + if (mBestMethodDef == NULL) { // FAILED, but select the first method which will fire an actual error on param type matching - mBestMethodDef = mBackupMethodDef; + mBestMethodDef = mBackupMethodDef; for (auto subType : typeInstance->mSubTypeList) { @@ -720,7 +719,7 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) if (mBestMethodDef != NULL) break; } - } + } } return true; @@ -729,12 +728,12 @@ bool DwMethodMatcher::CheckType(DbgType* typeInstance, bool isFailurePass) ////////////////////////////////////////////////////////////////////////// DbgExprEvaluator::DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModule, BfPassInstance* passInstance, int callStackIdx, int cursorPos) -{ +{ mCountResultOverride = -1; mCapturingChildRef = true; mPassInstance = passInstance; mDebugger = winDebugger; - mLanguage = DbgLanguage_NotSet; + mLanguage = DbgLanguage_NotSet; mOrigDbgModule = dbgModule; if (dbgModule != NULL) { @@ -752,7 +751,7 @@ DbgExprEvaluator::DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModul mExpectingType = NULL; mCurMethod = NULL; mIgnoreErrors = false; - mCallStackIdx = callStackIdx; + mCallStackIdx = callStackIdx; mCursorPos = cursorPos; mAutoComplete = NULL; mIsEmptyTarget = (dbgModule == NULL) || (dbgModule->mDebugTarget->mIsEmpty); @@ -775,7 +774,7 @@ DbgExprEvaluator::DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModul } DbgExprEvaluator::~DbgExprEvaluator() -{ +{ delete mStackSearch; } @@ -784,7 +783,7 @@ DbgTypedValue DbgExprEvaluator::GetInt(int value) DbgTypedValue dbgValue; dbgValue.mType = mDbgModule->GetPrimitiveType(DbgType_i32, GetLanguage()); dbgValue.mInt32 = value; - return dbgValue; + return dbgValue; } DbgTypedValue DbgExprEvaluator::GetString(const StringImpl& str) @@ -804,7 +803,7 @@ DbgTypedValue DbgExprEvaluator::GetString(const StringImpl& str) dbgValue.mLocalPtr = resultPtr->c_str(); dbgValue.mIsLiteral = true; dbgValue.mDataLen = resultPtr->mLength; - } + } return dbgValue; } @@ -832,7 +831,7 @@ DbgType* DbgExprEvaluator::GetExpectingType() } void DbgExprEvaluator::GetNamespaceSearch() -{ +{ if (!mNamespaceSearch.empty()) return; @@ -841,13 +840,13 @@ void DbgExprEvaluator::GetNamespaceSearch() { auto parent = currentMethod->GetParent(); while (parent != NULL) - { + { parent = parent->GetPrimaryType(); - mNamespaceSearch.push_back(parent); + mNamespaceSearch.push_back(parent); parent = parent->mParent; } } - + if (!mNamespaceSearchStr.empty()) { auto language = GetLanguage(); @@ -868,7 +867,7 @@ void DbgExprEvaluator::GetNamespaceSearch() auto dbgTypeEntry = mDbgModule->mTypeMap.Find(namespaceEntry.c_str(), language); if (dbgTypeEntry != NULL) mNamespaceSearch.push_back(dbgTypeEntry->mValue); - } + } } DbgType* DbgExprEvaluator::ResolveSubTypeRef(DbgType* checkType, const StringImpl& name) @@ -900,7 +899,7 @@ DbgType* DbgExprEvaluator::FixType(DbgType* dbgType) DbgTypedValue DbgExprEvaluator::FixThis(const DbgTypedValue& thisVal) { - /*if ((thisVal.mType != NULL) && (thisVal.mType->GetLanguage() == DbgLanguage_Beef) && + /*if ((thisVal.mType != NULL) && (thisVal.mType->GetLanguage() == DbgLanguage_Beef) && (!thisVal.mType->IsBfObjectPtr()) && (thisVal.mType->IsPointer())) { // Beef structs expect 'this' as a valuetype, not a pointer @@ -952,13 +951,13 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef) else { Fail(StrFormat("Illegal array size type"), arrayTypeRef->mParams[0]); - } + } return mDbgModule->GetSizedArrayType(elementType, count); } } } - + if (auto declTypeRef = BfNodeDynCastExact(typeRef)) { mResult = DbgTypedValue(); @@ -981,7 +980,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef) typeIdx = atoi(endPtr + 1); mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule); } - + if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size())) return dbgModule->mTypes[typeIdx]; } @@ -989,7 +988,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef) auto entry = mDbgModule->mTypeMap.Find(name.c_str(), GetLanguage()); if (entry != NULL) return FixType(entry->mValue); - + if (mExplicitThis) { bool isPtr = typeRef->IsA(); @@ -1005,7 +1004,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef) checkType = checkType->mTypeParam; ResolveSubTypeRef(checkType, name); - } + } auto currentType = GetCurrentType(); if (currentType != NULL) @@ -1025,8 +1024,8 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef) } DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parentChildRef) -{ - StringT<128> name = typeRef->ToString(); +{ + StringT<128> name = typeRef->ToString(); if ((name.StartsWith("_T_")) && ((int)name.IndexOf('.') == -1)) { int endIdx = name.length(); @@ -1050,7 +1049,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent typeIdx = atoi(endPtr + 1); mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule); } - + if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size())) { if ((mExplicitThisExpr != NULL) && (parentChildRef != NULL)) @@ -1070,7 +1069,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent if ((name[i] == ':') && (name[i - 1] == ':')) { name[i] = '.'; - name.erase(name.begin() + i - 1); + name.erase(name.begin() + i - 1); i--; } }*/ @@ -1081,7 +1080,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent return entry->mValue; auto currentType = GetCurrentType(); if (currentType != NULL) - { + { GetNamespaceSearch(); for (auto usingNamespace : mNamespaceSearch) { @@ -1096,7 +1095,7 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent } DbgType* DbgExprEvaluator::ResolveTypeRef(const StringImpl& typeName) -{ +{ auto entry = mDbgModule->mTypeMap.Find(typeName.c_str(), GetLanguage()); if (entry != NULL) return entry->mValue; @@ -1121,12 +1120,12 @@ bool DbgExprEvaluator::TypeIsSubTypeOf(DbgType* srcType, DbgType* wantType, int* return false; if (srcType->Equals(wantType)) return true; - + if (srcType->mTypeCode == DbgType_TypeDef) return TypeIsSubTypeOf(srcType->mTypeParam, wantType); if (wantType->mTypeCode == DbgType_TypeDef) return TypeIsSubTypeOf(srcType, wantType->mTypeParam); - + srcType->PopulateType(); for (auto srcBaseType : srcType->mBaseTypes) { @@ -1142,7 +1141,7 @@ bool DbgExprEvaluator::TypeIsSubTypeOf(DbgType* srcType, DbgType* wantType, int* addr_target vtableAddr = 0; gDebugger->ReadMemory(*thisAddr, sizeof(addr_target), &vtableAddr); gDebugger->ReadMemory(vtableAddr + srcBaseType->mVTableOffset * sizeof(int32), sizeof(int32), &virtThisOffset); - + *thisOffset += virtThisOffset; } else if (thisOffset != NULL) @@ -1165,7 +1164,7 @@ DbgTypedValue DbgExprEvaluator::GetBeefTypeById(int typeId) mDebugTarget->mTargetBinary->ParseTypeData(); auto typeTypeEntry = mDebugTarget->mTargetBinary->FindType("System.Type", DbgLanguage_Beef); - if ((typeTypeEntry != NULL) && (typeTypeEntry->mValue != NULL)) + if ((typeTypeEntry != NULL) && (typeTypeEntry->mValue != NULL)) { auto typeType = typeTypeEntry->mValue; mDebugTarget->mTargetBinary->mBfTypeType = typeType; @@ -1178,13 +1177,13 @@ DbgTypedValue DbgExprEvaluator::GetBeefTypeById(int typeId) { auto stackFrame = GetStackFrame(); DbgAddrType addrType; - mDebugTarget->mTargetBinary->mBfTypesInfoAddr = member->mCompileUnit->mDbgModule->EvaluateLocation(NULL, member->mLocationData, member->mLocationLen, stackFrame, &addrType); + mDebugTarget->mTargetBinary->mBfTypesInfoAddr = member->mCompileUnit->mDbgModule->EvaluateLocation(NULL, member->mLocationData, member->mLocationLen, stackFrame, &addrType); } } - + if (mDebugTarget->mTargetBinary->mBfTypesInfoAddr <= 0) { - mDebugTarget->mTargetBinary->ParseSymbolData(); + mDebugTarget->mTargetBinary->ParseSymbolData(); auto entry = mDebugTarget->mTargetBinary->mSymbolNameMap.Find( #ifdef BF_DBG_64 "?sTypes@Type@System@bf@@2PEAPEAV123@A" @@ -1192,7 +1191,7 @@ DbgTypedValue DbgExprEvaluator::GetBeefTypeById(int typeId) "?sTypes@Type@System@bf@@2PAPAV123@A" #endif ); - + if (entry) mDebugTarget->mTargetBinary->mBfTypesInfoAddr = entry->mValue->mAddress; } @@ -1283,7 +1282,7 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr _TypeId mTypeId; _TypeId mBoxedType; _TypeFlags mTypeFlags; - int32 mMemberDataOffset; + int32 mMemberDataOffset; _TypeCode mTypeCode; uint8 mAlign; }; @@ -1303,19 +1302,15 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr struct _String { - }; struct _MethodData { - }; struct _FieldData { - }; struct _ClassVData { - }; struct _TypeInstance : public _Type @@ -1325,7 +1320,7 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr #else int16 mPadding0; #endif - + addr_target mTypeClassVData; addr_target mName; addr_target mNamespace; @@ -1336,14 +1331,14 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr _TypeId mUnderlyingType; _TypeId mOuterType; int32 mInheritanceId; - int32 mInheritanceCount; + int32 mInheritanceCount; uint8 mInterfaceSlot; uint8 mInterfaceCount; int16 mInterfaceMethodCount; int16 mMethodDataCount; int16 mPropertyDataCount; - int16 mFieldDataCount; + int16 mFieldDataCount; #ifdef BF_DBG_32 int16 mPadding1; @@ -1373,16 +1368,16 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr int32 mElementSize; uint8 mRank; uint8 mElemensDataOffset; - }; + }; #pragma pack(pop) - + int typeIdSize = sizeof(_TypeId); int ptrSize = (int)sizeof(addr_target); int objectSize = mDebugTarget->mBfObjectSize; int typeSize = sizeof(_Type); int typeInstanceSize = objectSize + sizeof(_TypeInstance); - + auto addr = useVal.mSrcAddress; auto typeAddr = addr + objectSize; @@ -1495,7 +1490,7 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr } else { - BfTypeCode typeCode = (BfTypeCode)mDebugger->ReadMemory(typeAddr + (int)offsetof(_Type, mTypeCode)); + BfTypeCode typeCode = (BfTypeCode)mDebugger->ReadMemory(typeAddr + (int)offsetof(_Type, mTypeCode)); if (typeCode == BfTypeCode_Pointer) { _TypeId elementType = mDebugger->ReadMemory<_TypeId>(typeAddr + offsetof(_PointerType, mElementType)); @@ -1531,7 +1526,7 @@ void DbgExprEvaluator::BeefTypeToString(const DbgTypedValue& val, String& outStr case BfTypeCode_Float: outStr += "float"; break; case BfTypeCode_Double: outStr += "double"; break; } - } + } } CPUStackFrame* DbgExprEvaluator::GetStackFrame() @@ -1577,10 +1572,10 @@ DbgTypedValue DbgExprEvaluator::GetRegister(const StringImpl& regName) if (mCallStackIdx < (int)mDebugger->mCallStack.size()) regForms = &mDebugger->mCallStack[mCallStackIdx]->mRegForms; } - DbgTypedValue result = mDebugger->GetRegister(regName, GetLanguage(), GetRegisters(), regForms); + DbgTypedValue result = mDebugger->GetRegister(regName, GetLanguage(), GetRegisters(), regForms); if ((result) && (mReferenceId != NULL)) { - int regNum = CPURegisters::GetCompositeRegister(result.mRegNum); + int regNum = CPURegisters::GetCompositeRegister(result.mRegNum); const char* regName = CPURegisters::GetRegisterName(regNum); if (regName != NULL) *mReferenceId = String("$") + regName; @@ -1602,11 +1597,11 @@ DbgSubprogram* DbgExprEvaluator::GetCurrentMethod() mDebugger->UpdateCallStackMethod(mCallStackIdx); if (mCallStackIdx >= (int)mDebugger->mCallStack.size()) return NULL; - auto callStack = mDebugger->mCallStack[mCallStackIdx]; + auto callStack = mDebugger->mCallStack[mCallStackIdx]; auto subProgram = callStack->mSubProgram; if (subProgram != NULL) subProgram->PopulateSubprogram(); - return subProgram; + return subProgram; } DbgType* DbgExprEvaluator::GetCurrentType() @@ -1720,7 +1715,7 @@ bool DbgExprEvaluator::CanCast(DbgTypedValue typedVal, DbgType* toType, BfCastFl } if ((fromType->IsPrimitiveType()) && (toType->IsPrimitiveType())) - { + { DbgTypeCode fromTypeCode = fromType->mTypeCode; DbgTypeCode toTypeCode = toType->mTypeCode; if ((fromTypeCode == toTypeCode)) @@ -1728,10 +1723,10 @@ bool DbgExprEvaluator::CanCast(DbgTypedValue typedVal, DbgType* toType, BfCastFl // Must be from a default int to do an implicit constant cast, not casted by user, ie: (ushort)123 if ((toType->IsInteger()) /*&& (typedVal.mValue != NULL) && (fromTypeCode == DbgType_i32)*/) - { + { // Allow constant ints to be implicitly downcasted if they fit if (typedVal.mIsLiteral) - { + { int64 srcVal = typedVal.GetInt64(); if (toType->IsSigned()) { @@ -1783,10 +1778,10 @@ bool DbgExprEvaluator::CanCast(DbgTypedValue typedVal, DbgType* toType, BfCastFl break; case DbgType_u16: switch (fromTypeCode) - { + { case DbgType_i8: return true; - case DbgType_u8: + case DbgType_u8: case DbgType_UChar: case DbgType_UChar16: return true; @@ -1910,14 +1905,14 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty { if (!typedVal) return typedVal; - + DbgType* fromType = typedVal.mType; fromType = fromType->RemoveModifiers(); toType = toType->RemoveModifiers(); fromType = fromType->GetPrimaryType(); toType = toType->GetPrimaryType(); - + if ((toType->IsBfObject()) && (fromType->IsPointer())) toType = toType->GetDbgModule()->GetPointerType(toType); @@ -1938,7 +1933,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } } } - + if (fromType == toType) return typedVal; @@ -1947,7 +1942,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty { DbgTypedValue val; val.mPtr = typedVal.mPtr; - val.mType = toType; + val.mType = toType; return val; } @@ -1975,7 +1970,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty if (fromType->IsBfPayloadEnum()) { if (!allowCast) - { + { for (auto member : fromType->mMemberList) { if (member->mType->Equals(toType)) @@ -2006,7 +2001,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty { intptr valAddr; DbgType* valType; - DbgAddrType addrType = DbgAddrType_Value; + DbgAddrType addrType = DbgAddrType_Value; String findName = "$"; //BF_ASSERT(typedVal.mVariable != NULL); if (typedVal.mVariable != NULL) @@ -2014,8 +2009,8 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty findName += "$d"; if (mDebugTarget->GetValueByName(GetCurrentMethod(), findName, GetStackFrame(), &valAddr, &valType, &addrType)) { - return ReadTypedValue(srcNode, valType, valAddr, addrType); - } + return ReadTypedValue(srcNode, valType, valAddr, addrType); + } } // Optimized composite - probably stored in register @@ -2058,7 +2053,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } } - if ((fromType->IsPointer()) && (fromType->mTypeParam->IsCompositeType()) && + if ((fromType->IsPointer()) && (fromType->mTypeParam->IsCompositeType()) && (toType->IsPointer()) && (toType->mTypeParam->IsCompositeType())) { auto fromInnerType = fromType->mTypeParam->RemoveModifiers(); @@ -2105,7 +2100,6 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } } - // IFace -> object|IFace if ((fromType->IsInterface()) || ((fromType->IsPointer()) && (fromType->mTypeParam->IsInterface()))) @@ -2134,13 +2128,13 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty val.mPtr = typedVal.GetPointer(); val.mType = toType; return val; - } + } } - + // Enum -> Int if ((((fromType->IsBfEnum()) || (fromType->IsEnum())) && (toType->IsInteger())) && ((explicitCast) || (fromType == curTypeInstance))) - { + { DbgTypedValue result = typedVal; result.mType = toType; return result; @@ -2150,14 +2144,14 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty if (((fromType->IsInteger()) && ((toType->IsBfEnum()) || (toType->IsEnum()))) && ((explicitCast) || (toType == curTypeInstance))) { - DbgTypedValue result = typedVal; + DbgTypedValue result = typedVal; result.mType = toType; return result; } // TypedPrimitive -> Primitive if ((fromType->IsTypedPrimitive()) && (toType->IsPrimitiveType())) - { + { DbgTypedValue fromValue = typedVal; fromValue.mType = fromType->GetBaseType(); return Cast(srcNode, fromValue, toType, explicitCast); @@ -2178,7 +2172,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty // Primitive -> TypedPrimitive if ((fromType->IsPrimitiveType()) && (toType->IsTypedPrimitive())) - { + { DbgTypedValue primTypedVal = Cast(srcNode, typedVal, toType->GetBaseType(), true); if (primTypedVal) { @@ -2186,10 +2180,9 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty return primTypedVal; } } - if ((fromType->IsPrimitiveType()) && (toType->IsPrimitiveType())) - { + { DbgTypeCode fromTypeCode = fromType->mTypeCode; DbgTypeCode toTypeCode = toType->mTypeCode; @@ -2200,7 +2193,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty { int64 srcVal = typedVal.GetInt64(); /*if (toType->IsSigned()) - { + { int64 minVal = -(1LL << (8 * toType->mSize - 1)); int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1; if ((srcVal >= minVal) && (srcVal <= maxVal)) @@ -2212,7 +2205,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty explicitCast = true; } else - { + { int64 minVal = 0; int64 maxVal = (1LL << (8 * toType->mSize)) - 1; if ((srcVal >= minVal) && (srcVal <= maxVal)) @@ -2253,7 +2246,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } } } - + DbgTypedValue result; result.mType = toType; if (((fromType->IsInteger()) || (fromType->IsChar())) && @@ -2265,11 +2258,11 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } switch (toTypeCode) - { + { case DbgType_u8: case DbgType_UChar: switch (fromTypeCode) - { + { case DbgType_u8: case DbgType_UChar: return result; @@ -2293,7 +2286,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty case DbgType_u16: case DbgType_UChar16: switch (fromTypeCode) - { + { case DbgType_i8: case DbgType_SChar: return result; @@ -2323,11 +2316,11 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty case DbgType_UChar32: case DbgType_u32: switch (fromTypeCode) - { + { case DbgType_i8: - case DbgType_i16: + case DbgType_i16: case DbgType_SChar: - case DbgType_SChar16: + case DbgType_SChar16: return result; case DbgType_u8: case DbgType_u16: @@ -2378,7 +2371,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty case DbgType_Single: switch (fromTypeCode) { - case DbgType_i8: + case DbgType_i8: case DbgType_i16: case DbgType_i32: case DbgType_i64: @@ -2387,7 +2380,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty case DbgType_SChar32: result.mSingle = typedVal.GetInt64(); return result; - case DbgType_u8: + case DbgType_u8: case DbgType_u16: case DbgType_u32: case DbgType_u64: @@ -2400,7 +2393,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty break; case DbgType_Double: switch (fromTypeCode) - { + { case DbgType_i8: case DbgType_i16: case DbgType_i32: @@ -2416,7 +2409,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty case DbgType_u64: case DbgType_UChar: case DbgType_UChar16: - case DbgType_UChar32: + case DbgType_UChar32: result.mDouble = typedVal.GetInt64(); return result; case DbgType_Single: @@ -2445,7 +2438,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty } switch (toTypeCode) - { + { case DbgType_Single: switch (fromTypeCode) { @@ -2469,7 +2462,7 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty result.mSingle = (float)typedVal.mDouble; return result; } - break; + break; } } } @@ -2478,11 +2471,11 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty { DbgTypedValue realTypedVal = typedVal; realTypedVal.mType = fromType->mTypeParam; - return Cast(srcNode, realTypedVal, toType, explicitCast, silentFail); + return Cast(srcNode, realTypedVal, toType, explicitCast, silentFail); } - if (toType->mTypeCode == DbgType_TypeDef) - return Cast(srcNode, typedVal, toType->mTypeParam, explicitCast, silentFail); + if (toType->mTypeCode == DbgType_TypeDef) + return Cast(srcNode, typedVal, toType->mTypeParam, explicitCast, silentFail); if (!silentFail) { @@ -2498,17 +2491,17 @@ DbgTypedValue DbgExprEvaluator::Cast(BfAstNode* srcNode, const DbgTypedValue& ty bool DbgExprEvaluator::HasField(DbgType* curCheckType, const StringImpl& fieldName) { - curCheckType = curCheckType->RemoveModifiers(); - curCheckType = curCheckType->GetPrimaryType(); + curCheckType = curCheckType->RemoveModifiers(); + curCheckType = curCheckType->GetPrimaryType(); curCheckType->PopulateType(); for (auto checkMember : curCheckType->mMemberList) { if (checkMember->mName == NULL) - { + { auto checkResult = HasField(checkMember->mType, fieldName); - if (checkResult) - return checkResult; + if (checkResult) + return checkResult; } else if (checkMember->mName == fieldName) return true; @@ -2516,10 +2509,10 @@ bool DbgExprEvaluator::HasField(DbgType* curCheckType, const StringImpl& fieldNa for (auto baseTypeEntry : curCheckType->mBaseTypes) { - auto baseType = baseTypeEntry->mBaseType; + auto baseType = baseTypeEntry->mBaseType; auto result = HasField(baseType, fieldName); if (result) - return result; + return result; } //if (wantsStatic) @@ -2536,7 +2529,7 @@ bool DbgExprEvaluator::HasField(DbgType* curCheckType, const StringImpl& fieldNa } for (auto altType : curCheckType->mAlternates) - { + { auto result = HasField(altType, fieldName); if (result) return result; @@ -2547,7 +2540,7 @@ bool DbgExprEvaluator::HasField(DbgType* curCheckType, const StringImpl& fieldNa } DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValue target, DbgType* curCheckType, const StringImpl& fieldName, CPUStackFrame* stackFrame, bool allowImplicitThis) -{ +{ if (mStackSearch != NULL) { if (mStackSearch->mIdentifier == targetSrc) @@ -2566,8 +2559,8 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu wantsStatic = true; } - curCheckType = curCheckType->RemoveModifiers(); - curCheckType = curCheckType->GetPrimaryType(); + curCheckType = curCheckType->RemoveModifiers(); + curCheckType = curCheckType->GetPrimaryType(); curCheckType->PopulateType(); //BfLogDbgExpr("DoLookupField %s %s Priority=%d\n", fieldName.c_str(), curCheckType->mName, curCheckType->mPriority); @@ -2575,20 +2568,20 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu if ((curCheckType->mNeedsGlobalsPopulated) && ((curCheckType->IsNamespace()) || (curCheckType->IsRoot()))) { // Global variables don't show up in any type declaration like static fields do, so we need to populate here - mDbgModule->PopulateTypeGlobals(curCheckType); + mDbgModule->PopulateTypeGlobals(curCheckType); } /*auto checkMember = curCheckType->mMemberList.mHead; while (checkMember != NULL)*/ - String findFieldName = fieldName; + String findFieldName = fieldName; if ((language == DbgLanguage_Beef) && (flavor == DbgFlavor_MS) && (target.mHasNoValue)) { //if ((curCheckType->IsRoot()) || (curCheckType->IsNamespace())) //findFieldName.insert(0, "bf__"); } - - //for (auto checkMember : curCheckType->mMemberList) + + //for (auto checkMember : curCheckType->mMemberList) auto nextMember = curCheckType->mMemberList.mHead; while (nextMember != NULL) { @@ -2596,7 +2589,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu nextMember = checkMember->mNext; if (checkMember->mName == NULL) - { + { //TODO: Check inside anonymous type DbgTypedValue innerTarget; @@ -2609,30 +2602,29 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu innerTarget.mType = checkMember->mType; auto checkResult = LookupField(targetSrc, innerTarget, fieldName); - if (checkResult) - return checkResult; + if (checkResult) + return checkResult; } else if (checkMember->mName == findFieldName) - { + { //BfLogDbgExpr(" Got Match\n"); //TODO: /*if (field->mIsConst) { - if (fieldInstance->mStaticValue == NULL) mModule->ResolveConstField(curCheckType, field); return DbgTypedValue(fieldInstance->mStaticValue, fieldInstance->mType); }*/ - //checkMember->mMemberOffset + //checkMember->mMemberOffset if (mReferenceId != NULL) { if (curCheckType->IsRoot()) *mReferenceId = fieldName; else if (curCheckType->IsEnum()) - *mReferenceId = curCheckType->ToString(); + *mReferenceId = curCheckType->ToString(); else *mReferenceId = curCheckType->ToString() + "." + fieldName; } @@ -2646,7 +2638,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu mDbgModule->PopulateTypeGlobals(curCheckType); return DoLookupField(targetSrc, target, curCheckType, fieldName, stackFrame, allowImplicitThis); } - + /*String memberName = curCheckType->ToString() + "::" + checkMember->mName; mDbgModule->ParseSymbolData(); auto entry = mDbgModule->mSymbolNameMap.Find(memberName.c_str()); @@ -2665,8 +2657,8 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu BF_ASSERT("Static field not found" == 0); }*/ } - else - { + else + { continue; //BF_FATAL("Unhandled"); @@ -2734,10 +2726,10 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu Fail("Static variable not found, may have be optimized out", targetSrc); //BfLogDbgExpr(" Static variable optimized out\n"); } - else + else { if ((allowImplicitThis) && (target.mPtr == 0)) - target = GetThis(); + target = GetThis(); if (!target) { @@ -2766,7 +2758,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu } if (checkMember->mBitSize != 0) - { + { int expectedShift = (checkMember->mType->mSize * 8) - checkMember->mBitSize; int shift = expectedShift - checkMember->mBitOffset; @@ -2808,11 +2800,11 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu methodNameEntry->mCompileUnitId = -1; } } - } + } } for (int pass = 0; pass < 2; pass++) - { + { for (auto method : curCheckType->mMethodList) { if (method->mName != NULL) @@ -2836,7 +2828,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu continue; } - DbgSubprogram*& subprogramRef = isGetter ? mPropGet : mPropSet; + DbgSubprogram*& subprogramRef = isGetter ? mPropGet : mPropSet; if ((subprogramRef == NULL) || ((!method->mHasThis) && (wantsStatic)) || @@ -2846,11 +2838,11 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu { target = GetThis(); } - + if (subprogramRef == NULL) subprogramRef = method; else if ((method->mVTableLoc != -1) || (subprogramRef->mVTableLoc == -1)) - subprogramRef = method; + subprogramRef = method; } } } @@ -2865,9 +2857,9 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu continue; if (method->mBlock.mLowPC == 0) - { + { if (!curCheckType->mHasGlobalsPopulated) - mDbgModule->PopulateTypeGlobals(curCheckType); + mDbgModule->PopulateTypeGlobals(curCheckType); for (auto methodNameEntry : curCheckType->mMethodNameList) { const char* methodName = methodNameEntry->mName; @@ -2902,8 +2894,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu } }*/ - - //curCheckType = curCheckType->GetBaseType(); + //curCheckType = curCheckType->GetBaseType(); for (auto baseTypeEntry : curCheckType->mBaseTypes) { @@ -2919,7 +2910,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu if (ptrRef != NULL) { if (baseTypeEntry->mVTableOffset != -1) - { + { addr_target vtableAddr = mDebugger->ReadMemory(target.mPtr); int32 virtThisOffset = mDebugger->ReadMemory(vtableAddr + baseTypeEntry->mVTableOffset * sizeof(int32)); *ptrRef += virtThisOffset; @@ -2931,9 +2922,9 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu //BF_ASSERT(baseTypeEntry->mVTableOffset == -1); auto result = DoLookupField(targetSrc, baseTarget, baseType, fieldName, stackFrame, allowImplicitThis); if (result) - return result; + return result; } - + if (wantsStatic) { // Look for statics in anonymous inner classes @@ -2946,7 +2937,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu { if ((checkSubType->IsGlobalsContainer()) && (checkSubType->mPriority <= DbgTypePriority_Normal)) continue; - auto rawCheckSubType = checkSubType->RemoveModifiers(); + auto rawCheckSubType = checkSubType->RemoveModifiers(); auto result = DoLookupField(targetSrc, DbgTypedValue(), rawCheckSubType, fieldName, stackFrame, false); if (result) return result; @@ -2955,7 +2946,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu //Turn alternates back on! /*for (auto altType : curCheckType->mAlternates) - { + { auto result = DoLookupField(targetSrc, DbgTypedValue(), altType, fieldName, stackFrame, false); if (result) return result; @@ -2966,10 +2957,10 @@ DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValu } DbgTypedValue DbgExprEvaluator::LookupField(BfAstNode* targetSrc, DbgTypedValue target, const StringImpl& fieldName) -{ +{ CPUStackFrame* stackFrame = GetStackFrame(); - - DbgType* curCheckType = NULL; + + DbgType* curCheckType = NULL; /*if (currentMethod != NULL) curCheckType = currentMethod->mParentType;*/ DbgType* curMethodType = curCheckType; @@ -2984,13 +2975,13 @@ DbgTypedValue DbgExprEvaluator::LookupField(BfAstNode* targetSrc, DbgTypedValue } else { - curCheckType = target.mType; + curCheckType = target.mType; } BF_ASSERT(curCheckType != NULL); } else if (target.mType != NULL) curCheckType = target.mType; - + if (curCheckType != NULL) { curCheckType = curCheckType->RemoveModifiers(); @@ -3005,9 +2996,9 @@ DbgTypedValue DbgExprEvaluator::LookupField(BfAstNode* targetSrc, DbgTypedValue if (currentMethod != NULL) { curCheckType = currentMethod->GetTargetType(); - allowImplicitThis = currentMethod->mHasThis; + allowImplicitThis = currentMethod->mHasThis; } - } + } //SetAndRestoreValue prevTypeInstance(curMethodType, curCheckType); @@ -3029,7 +3020,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db if (addrType == DbgAddrType_Alias) { String findName = (const char*)valAddr; - + if (targetSrc == NULL) return DbgTypedValue(); @@ -3042,12 +3033,12 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db int srcStart = bfParser->AllocChars(findName.length()); memcpy((char*)source->mSrc + srcStart, findName.c_str(), findName.length()); identifierNode->Init(srcStart, srcStart, srcStart + findName.length()); - + SetAndRestoreValue prevIgnoreErrors(mIgnoreErrors, true); auto result = LookupIdentifier(identifierNode); if (result) return result; - + // Allow lookup in calling method if we are inlined (for mixin references) auto currentMethod = GetCurrentMethod(); if ((currentMethod != NULL) && (currentMethod->mInlineeInfo != NULL)) @@ -3082,12 +3073,12 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db } if (addrType == DbgAddrType_NoValue) - { + { mPassInstance->Fail(StrFormat("No value", valAddr)); return DbgTypedValue(); } else if (addrType == DbgAddrType_OptimizedOut) - { + { mPassInstance->Fail(StrFormat("Optimized out", valAddr)); return DbgTypedValue(); } @@ -3097,7 +3088,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db while (true) { if (dbgType->mTypeCode == DbgType_Const) - { + { dbgType = mDbgModule->GetInnerTypeOrVoid(dbgType); } else if ((dbgType->mTypeCode == DbgType_TypeDef) || (dbgType->mTypeCode == DbgType_Volatile)) @@ -3115,7 +3106,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db if (addrType == DbgAddrType_Register) { auto registers = GetRegisters(); - valAddr = registers->mIntRegsArray[valAddr]; + valAddr = registers->mIntRegsArray[valAddr]; } //valIsAddr = true; @@ -3129,27 +3120,27 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db if (addrType == DbgAddrType_Register) { auto registers = GetRegisters(); - valAddr = registers->mIntRegsArray[valAddr]; + valAddr = registers->mIntRegsArray[valAddr]; } addrType = DbgAddrType_Target; } - dbgType = dbgType->mTypeParam; + dbgType = dbgType->mTypeParam; } else break; } dbgType = dbgType->GetPrimaryType(); - + if (dbgType->GetByteCount() == 0) - { + { DbgTypedValue result; result.mType = dbgType; return result; } if (dbgType->mTypeCode == DbgType_Bitfield) - { + { DbgType* underlyingType = dbgType->mTypeParam; DbgTypedValue result = ReadTypedValue(targetSrc, dbgType->mTypeParam, valAddr, addrType); result.mType = dbgType; @@ -3174,7 +3165,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db bool valIsAddr = (addrType == DbgAddrType_Local) || (addrType == DbgAddrType_Target); DbgTypedValue result; - result.mType = origDwType; + result.mType = origDwType; if (addrType == DbgAddrType_Register) { @@ -3182,7 +3173,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db auto registers = GetRegisters(); if (result.mRegNum < CPURegisters::kNumIntRegs) - result.mUInt64 = registers->mIntRegsArray[result.mRegNum]; + result.mUInt64 = registers->mIntRegsArray[result.mRegNum]; else if ((result.mRegNum >= CPUReg_XMMREG_FIRST) && (result.mRegNum <= CPUReg_XMMREG_LAST)) { auto dwType = origDwType->RemoveModifiers(); @@ -3213,11 +3204,11 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db dbgType = dbgType->mTypeParam; switch (dbgType->mTypeCode) - { + { case DbgType_Void: break; - case DbgType_Bool: + case DbgType_Bool: case DbgType_i8: case DbgType_u8: case DbgType_SChar: @@ -3263,7 +3254,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db case DbgType_Struct: case DbgType_Class: case DbgType_Union: - case DbgType_SizedArray: + case DbgType_SizedArray: if (((dbgType->IsTypedPrimitive()) || (local)) && (dbgType->GetByteCount() <= 8)) { mDebugger->ReadMemory(valAddr, dbgType->GetByteCount(), &result.mInt64, local); @@ -3278,7 +3269,7 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db result.mSrcAddress = (addr_target)valAddr; } //result.mPtr = (addr_target)valAddr; - break; + break; //TODO: Why was it treated as a pointer //case DbgType_SizedArray: @@ -3289,10 +3280,10 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db result.mPtr = valAddr; break; - case DbgType_Enum: + case DbgType_Enum: result = ReadTypedValue(targetSrc, dbgType->mTypeParam, valAddr, addrType); if (result) - result.mType = dbgType; + result.mType = dbgType; break; case DbgType_Subroutine: @@ -3307,12 +3298,12 @@ DbgTypedValue DbgExprEvaluator::ReadTypedValue(BfAstNode* targetSrc, DbgType* db #ifdef BF_DBG_32 if ((symbolName.length() > 0) && (symbolName[0] == '_')) symbolName = symbolName.Substring(1); -#endif +#endif static String demangledName; demangledName = BfDemangler::Demangle(symbolName, dbgType->GetLanguage()); - DbgTypedValue result; - result.mCharPtr = demangledName.c_str(); + DbgTypedValue result; + result.mCharPtr = demangledName.c_str(); } else { @@ -3411,16 +3402,16 @@ DbgTypedValue DbgExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, DbgType* Fail("Address for enum cannot be inferred", targetSrc); return DbgTypedValue(); } - + enumType = enumType->RemoveModifiers(); enumType = enumType->GetPrimaryType(); - int caseNum = -1; + int caseNum = -1; DbgVariable* matchedMember = NULL; for (auto member : enumType->mMemberList) { if ((member->mName[0] == '_') && (member->mName[1] >= '0') && (member->mName[1] <= '9')) - { + { for (int i = 1; true; i++) { if (member->mName[i] == '_') @@ -3477,11 +3468,11 @@ void DbgExprEvaluator::AutocompleteCheckType(BfTypeReference* typeReference) else if (auto qualifiedTypeRef = BfNodeDynCast(typeReference)) { if (IsAutoCompleteNode(qualifiedTypeRef->mLeft)) - { + { AutocompleteCheckType(qualifiedTypeRef->mLeft); return; } - + auto dbgType = ResolveTypeRef(qualifiedTypeRef->mLeft); if (dbgType != NULL) { @@ -3499,7 +3490,7 @@ void DbgExprEvaluator::AutocompleteCheckType(BfTypeReference* typeReference) } AutocompleteAddMembers(dbgType, false, false, filter); } - } + } else if (auto elementedTypeRef = BfNodeDynCast(typeReference)) { AutocompleteCheckType(elementedTypeRef->mElementType); @@ -3580,22 +3571,22 @@ void DbgExprEvaluator::AutocompleteAddTopLevelTypes(const StringImpl& filter) } DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError) -{ +{ if (!mDebugger->mIsRunning) return DbgTypedValue(); - + auto qualifiedNameNode = BfNodeDynCast(identifierNode); if (qualifiedNameNode != NULL) { LookupQualifiedName(qualifiedNameNode, ignoreInitialError, hadError); - auto qualifiedResult = mResult; + auto qualifiedResult = mResult; mResult = DbgTypedValue(); return qualifiedResult; - } + } - String findName = identifierNode->ToString(); + String findName = identifierNode->ToString(); if ((findName.StartsWith('$')) && (findName != "$prim")) - { + { if (IsAutoCompleteNode(identifierNode)) { String filter = identifierNode->ToString(); @@ -3620,8 +3611,8 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo return GetString(mDebugger->mActiveThread->mName); else if (findName == "$TargetName") return GetString(GetFileName(mDebugTarget->mTargetPath)); - else if (findName == "LaunchName") - return GetString(GetFileName(mDebugTarget->mLaunchBinary->mFilePath)); + else if (findName == "LaunchName") + return GetString(GetFileName(mDebugTarget->mLaunchBinary->mFilePath)); else if (findName == "$TargetPath") return GetString(mDebugTarget->mTargetPath); else if (findName == "$ModuleName") @@ -3659,7 +3650,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo if (mExplicitThis) { if ((mExplicitThis.mSrcAddress == -1) && ((DbgVariable*)mExplicitThis.mVariable != NULL)) - { + { mResult = DbgTypedValue(); LookupSplatMember(mExplicitThis, findName); result = mResult; @@ -3668,11 +3659,11 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo else if (!result) { mExplicitThis.mType = mExplicitThis.mType->RemoveModifiers(); - result = LookupField(identifierNode, mExplicitThis, findName); + result = LookupField(identifierNode, mExplicitThis, findName); } if (result) - { + { if (mExplicitThisExpr != NULL) mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(identifierNode, mCurChildRef)); return result; @@ -3681,14 +3672,14 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo CPUStackFrame* stackFrame = GetStackFrame(); auto language = GetLanguage(); - + intptr valAddr; DbgType* valType; - DbgAddrType addrType = DbgAddrType_None; + DbgAddrType addrType = DbgAddrType_None; if (IsAutoCompleteNode(identifierNode)) - { - String filter = identifierNode->ToString(); + { + String filter = identifierNode->ToString(); DbgType* dbgType = NULL; @@ -3702,19 +3693,19 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo else if (!thisVal) dbgType = currentMethod->GetTargetType(); } - + Array capturedNames; Array capturedTypes; mDebugTarget->mCapturedNamesPtr = &capturedNames; mDebugTarget->mCapturedTypesPtr = &capturedTypes; - { + { mDebugTarget->GetValueByName(GetCurrentMethod(), "*", stackFrame, &valAddr, &valType, &addrType); } mDebugTarget->mCapturedNamesPtr = NULL; mDebugTarget->mCapturedTypesPtr = NULL; auto language = GetLanguage(); BF_ASSERT(capturedTypes.size() == capturedNames.size()); - { + { //for (auto capturedName : capturedNames) for (int i = 0; i < (int)capturedNames.size(); i++) { @@ -3736,7 +3727,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } if (dbgType != NULL) - { + { dbgType = dbgType->RemoveModifiers(); if (dbgType->IsPointerOrRef()) { @@ -3745,7 +3736,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } if (dbgType->mIsDeclaration) dbgType = dbgType->GetPrimaryType(); - + bool wantsStatic = true; bool wantsNonStatic = currentMethod->mHasThis; // In Beef, we can only access statics by class name @@ -3761,7 +3752,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo if (currentMethod != NULL) { if (strstr(currentMethod->mName, "operator()") != NULL) - { + { if (mDebugTarget->GetValueByName(currentMethod, "this", stackFrame, &valAddr, &valType, &addrType)) { valType = valType->RemoveModifiers(); @@ -3769,7 +3760,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo valType = valType->mTypeParam; valType = valType->RemoveModifiers(); AutocompleteAddMembers(valType, true, true, filter, true); - } + } } } } @@ -3795,13 +3786,13 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo mAutoComplete->mInsertStartIdx = identifierNode->GetSrcStart(); mAutoComplete->mInsertEndIdx = identifierNode->GetSrcEnd(); - - AutocompleteAddTopLevelTypes(filter); + + AutocompleteAddTopLevelTypes(filter); } - + if (language == DbgLanguage_C) { - // For C++ lambdas, captured a "this" is named "__this", so allow lookups into that + // For C++ lambdas, captured a "this" is named "__this", so allow lookups into that auto currentMethod = GetCurrentMethod(); if (currentMethod != NULL) { @@ -3829,7 +3820,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo return GetThis(); if (findName == "_") { - if (mSubjectValue) + if (mSubjectValue) { if (mSubjectValue.mSrcAddress != 0) { @@ -3839,7 +3830,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } return mSubjectValue; } - + if (!mSubjectExpr.IsEmpty()) { DwFormatInfo formatInfo; @@ -3857,7 +3848,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } if (stackFrame != NULL) - { + { if (mDebugTarget->GetValueByName(GetCurrentMethod(), findName, stackFrame, &valAddr, &valType, &addrType)) { //BF_ASSERT(valType != NULL); @@ -3883,10 +3874,10 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } } - bool isClosure = false; + bool isClosure = false; if (language == DbgLanguage_Beef) - { + { intptr valAddr; DbgType* valType; //bool valIsAddr = false; @@ -3929,23 +3920,23 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo } }*/ - if (!isClosure) + if (!isClosure) { // This uses an incorrect 'this' in the case of a closure result = LookupField(identifierNode, DbgTypedValue(), findName); if ((result) || (HasPropResult())) - return result; + return result; } - - result = GetRegister(findName); + + result = GetRegister(findName); if ((result) || (HasPropResult())) - { + { return result; } mDbgModule->ParseGlobalsData(); for (auto compileUnit : mDbgModule->mCompileUnits) - { + { if (mDbgCompileUnit == NULL) continue; if ((compileUnit->mLanguage != DbgLanguage_Unknown) && (compileUnit->mLanguage != mDbgCompileUnit->mLanguage)) @@ -3967,28 +3958,28 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo auto dbgType = currentMethod->mParentType; if (dbgType->IsPointerOrRef()) dbgType = dbgType->mTypeParam; - - auto curAlloc = &dbgType->mCompileUnit->mDbgModule->mAlloc; + + auto curAlloc = &dbgType->mCompileUnit->mDbgModule->mAlloc; result = DoLookupField(identifierNode, DbgTypedValue(), dbgType, findName, NULL, false); if ((result) || (HasPropResult())) return result; - + GetNamespaceSearch(); for (auto usingNamespace : mNamespaceSearch) - { + { usingNamespace = usingNamespace->GetPrimaryType(); result = DoLookupField(identifierNode, DbgTypedValue(), usingNamespace, findName, NULL, false); if ((result) || (HasPropResult())) return result; for (auto checkNamespace : usingNamespace->mAlternates) - { + { result = DoLookupField(identifierNode, DbgTypedValue(), checkNamespace, findName, NULL, false); - if ((result) || (HasPropResult())) - return result; + if ((result) || (HasPropResult())) + return result; } - } + } } return DbgTypedValue(); @@ -3997,7 +3988,7 @@ DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bo DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError) { if ((mStackSearch != NULL) && (mStackSearch->mIdentifier == NULL)) - { + { mStackSearch->mIdentifier = identifierNode; mStackSearch->mStartingStackIdx = mCallStackIdx; @@ -4005,7 +3996,7 @@ DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool StringT<256> findStr; for (int i = 0; i < mStackSearch->mSearchStr.mLength; i++) - { + { char c = mStackSearch->mSearchStr[i]; if (c == '^') @@ -4032,7 +4023,7 @@ DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool { mDebugger->UpdateCallStackMethod(mCallStackIdx); if (stackFrame->mSubProgram != NULL) - { + { int strLen = strlen(stackFrame->mSubProgram->mName); if (strLen >= findStr.mLength) { @@ -4086,11 +4077,11 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) auto binaryOp = BfAssignOpToBinaryOp(assignExpr->mOp); - //auto ptr = mModule->GetOrCreateVarAddr(assignExpr->mLeft); + //auto ptr = mModule->GetOrCreateVarAddr(assignExpr->mLeft); VisitChild(assignExpr->mLeft); if ((!mResult) && (!HasPropResult())) return; - + if (HasPropResult()) { if (mPropSet == NULL) @@ -4103,7 +4094,7 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) auto propSet = mPropSet; auto propTarget = mPropTarget; auto indexerValues = mIndexerValues; - + auto indexerExprValues = mIndexerExprValues; mPropGet = NULL; mPropSet = NULL; @@ -4125,15 +4116,14 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, true); if (!mResult) return; - convVal = mResult; + convVal = mResult; } else { - convVal = CreateValueFromExpression(assignExpr->mRight, valueParam->mType); + convVal = CreateValueFromExpression(assignExpr->mRight, valueParam->mType); } if (!convVal) return; - // SizedArray argPushQueue; // if (propSet->mHasThis) @@ -4142,12 +4132,12 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) // argPushQueue.push_back(indexer); // argPushQueue.push_back(convVal); // if (propSet->mParams.Size() == argPushQueue.size()) -// { +// { // mResult = CreateCall(propSet, argPushQueue, false); -// +// // } - indexerExprValues.push_back(assignExpr->mRight); + indexerExprValues.push_back(assignExpr->mRight); indexerValues.push_back(convVal); mResult = CreateCall(propSrc, propTarget, propSet, false, indexerExprValues, indexerValues); @@ -4155,13 +4145,13 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) } GetResult(); - auto ptr = mResult; + auto ptr = mResult; mResult = DbgTypedValue(); - + if (binaryOp != NULL) { PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, true); - } + } else { SetAndRestoreValue prevReceiveValue(mReceivingValue, &ptr); @@ -4178,7 +4168,7 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) } if (!mResult) return; - + if ((ptr.mType->mTypeCode == DbgType_Ref) || (ptr.mType->mTypeCode == DbgType_RValueReference)) ptr.mType = ptr.mType->mTypeParam; @@ -4197,14 +4187,14 @@ void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr) mResult = Cast(assignExpr->mRight, mResult, ptr.mType, true); if (!mResult) return; - + if ((mExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) == 0) - { + { mBlockedSideEffects = true; return; } - StoreValue(ptr, mResult, assignExpr->mLeft); + StoreValue(ptr, mResult, assignExpr->mLeft); } bool DbgExprEvaluator::StoreValue(DbgTypedValue& ptr, DbgTypedValue& value, BfAstNode* refNode) @@ -4272,7 +4262,7 @@ bool DbgExprEvaluator::StoreValue(DbgTypedValue& ptr, BfExpression* expr) return true; // Already written if (!result) return false; - + return StoreValue(ptr, result, expr);; } @@ -4301,22 +4291,22 @@ DbgTypedValue DbgExprEvaluator::GetResult() { if (mPropGet == NULL) { - Fail("Property has no getter", mPropSrc); + Fail("Property has no getter", mPropSrc); } else { // SizedArray argPushQueue; // auto curParam = mPropGet->mParams.mHead; // if (mPropGet->mHasThis) -// { +// { // argPushQueue.push_back(mPropTarget); // if (curParam != NULL) // curParam = curParam->mNext; // } // bool failed = false; -// for (int indexerIdx = 0; indexerIdx < (int)mIndexerValues.size(); indexerIdx++) +// for (int indexerIdx = 0; indexerIdx < (int)mIndexerValues.size(); indexerIdx++) // { -// auto val = mIndexerValues[indexerIdx]; +// auto val = mIndexerValues[indexerIdx]; // if (curParam != NULL) // { // val = Cast(mPropSrc, val, curParam->mType); @@ -4327,7 +4317,7 @@ DbgTypedValue DbgExprEvaluator::GetResult() // } // } // argPushQueue.push_back(val); -// +// // if (curParam != NULL) // curParam = curParam->mNext; // } @@ -4342,7 +4332,7 @@ DbgTypedValue DbgExprEvaluator::GetResult() // Fail("Indexer parameter count mismatch", mPropSrc); // } // } - + SetAndRestoreValue prevFlags(mExpressionFlags); if ((mExpressionFlags & DwEvalExpressionFlag_AllowPropertyEval) != 0) mExpressionFlags = (DwEvalExpressionFlags)(mExpressionFlags | DwEvalExpressionFlag_AllowCalls); @@ -4430,7 +4420,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic // Don't get primary type for namespace, causes mAlternates infinite loop if (!dbgType->IsNamespace()) dbgType = dbgType->GetPrimaryType(); - + // false/false means just add subtypes if ((wantsStatic) || (!wantsNonStatic)) { @@ -4439,7 +4429,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic { if (subType->mLanguage != language) { - // Ignore + // Ignore } else if (subType->mTypeName == NULL) { @@ -4473,7 +4463,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic if (subType->IsBfObject()) entry->mEntryType = "class"; else if (subType->IsNamespace()) - entry->mEntryType = "namespace"; + entry->mEntryType = "namespace"; else entry->mEntryType = "valuetype"; } @@ -4508,7 +4498,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic return; for (auto member : dbgType->mMemberList) - { + { if (((member->mIsStatic) && (wantsStatic)) || ((!member->mIsStatic) && (wantsNonStatic))) { @@ -4517,7 +4507,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic { if (member->mName[0] == '?') continue; - + mAutoComplete->AddEntry(AutoCompleteEntry(GetTypeName(member->mType), name), filter); if ((isCapture) && (strcmp(member->mName, "__this") == 0)) @@ -4554,12 +4544,12 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic } for (auto method : dbgType->mMethodList) - { + { if (((!method->mHasThis) && (wantsStatic)) || ((method->mHasThis) && (wantsNonStatic))) - { + { if ((method->mName != NULL) && (strcmp(method->mName, "this") != 0)) - { + { mDbgModule->FindTemplateStr(method->mName, method->mTemplateNameIdx); if (method->mTemplateNameIdx == -1) { @@ -4573,7 +4563,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic { BF_ASSERT(!dbgType->mMethodList.IsEmpty()); }*/ - + /* for (auto methodNameEntry : dbgType->mMethodNameList) { @@ -4584,7 +4574,7 @@ void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic for (auto baseTypeEntry : dbgType->mBaseTypes) { AutocompleteAddMembers(baseTypeEntry->mBaseType, wantsStatic, wantsNonStatic, filter); - } + } } void DbgExprEvaluator::AutocompleteCheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName) @@ -4685,7 +4675,6 @@ void DbgExprEvaluator::AutocompleteCheckMemberReference(BfAstNode* target, BfAst //return AutocompleteAddMembersFromNamespace(memberRefExpr->mTarget->ToString(), filter, isCType); } } - } void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) @@ -4699,12 +4688,12 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) }*/ auto flavor = GetFlavor(); - + String findName; BfAstNode* nameRefNode = memberRefExpr->mMemberName; if (auto attrIdentifierExpr = BfNodeDynCast(memberRefExpr->mMemberName)) { - nameRefNode = attrIdentifierExpr->mIdentifier; + nameRefNode = attrIdentifierExpr->mIdentifier; if (nameRefNode != NULL) findName = attrIdentifierExpr->mIdentifier->ToString(); } @@ -4715,7 +4704,7 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) // { - SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); + SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); mResult.mType = ResolveTypeRef(memberRefExpr); if (mResult.mType != NULL) { @@ -4735,7 +4724,7 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) if (expectingType != NULL) { DbgTypedValue expectingVal; - expectingVal.mType = expectingType; + expectingVal.mType = expectingType; mResult = LookupField(memberRefExpr->mMemberName, expectingVal, findName); if ((mResult) || (HasPropResult())) return; @@ -4748,8 +4737,8 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) thisValue.mType = mExpectingType; else thisValue.mType = ResolveTypeRef(memberRefExpr->mTarget, (BfAstNode**)&(memberRefExpr->mTarget)); - if (thisValue.mType != NULL) - thisValue.mHasNoValue = true; + if (thisValue.mType != NULL) + thisValue.mHasNoValue = true; } if (thisValue.mType == NULL) @@ -4778,7 +4767,7 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) // Look up static field thisValue.mType = ResolveTypeRef(typeRef); }*/ - + if (thisValue.mSrcAddress == -1) { LookupSplatMember(memberRefExpr->mTarget, memberRefExpr, thisValue, findName); @@ -4788,7 +4777,7 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) /*if (mResult) { if (mReferenceId != NULL) - *mReferenceId = thisValue.mType->ToString() + "." + findName; + *mReferenceId = thisValue.mType->ToString() + "." + findName; }*/ if ((!mResult) && (!HasPropResult())) @@ -4805,14 +4794,14 @@ void DbgExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr) if (thisValue.mHasNoValue) { for (auto altDwType : thisValue.mType->mAlternates) - { + { auto altThisValue = thisValue; altThisValue.mType = altDwType; mResult = LookupField(memberRefExpr->mMemberName, altThisValue, findName); if (mResult) return; } - } + } Fail("Unable to find member", memberRefExpr->mMemberName); } @@ -4828,7 +4817,7 @@ DbgTypedValue DbgExprEvaluator::RemoveRef(DbgTypedValue typedValue) } void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) -{ +{ VisitChild(indexerExpr->mTarget); GetResult(); if (!mResult) @@ -4849,7 +4838,7 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) if (!mResult) indexerFailed = true; indexerValues.push_back(mResult); - mResult = DbgTypedValue(); + mResult = DbgTypedValue(); } if (indexerFailed) @@ -4870,12 +4859,12 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) isBfArrayIndex = true; } } - + if (!isBfArrayIndex) { mIndexerExprValues = indexerExprValues; mIndexerValues = indexerValues; - mResult = LookupField(indexerExpr->mTarget, collection, ""); + mResult = LookupField(indexerExpr->mTarget, collection, ""); if (HasPropResult()) { // Only use this if we actually have the method. Otherwise fall through so we can try a debug visualizer or something @@ -4896,14 +4885,14 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) Fail("Expected single index", indexerExpr->mOpenBracket); return; } - DbgTypedValue indexArgument = indexerValues[0]; + DbgTypedValue indexArgument = indexerValues[0]; indexArgument.mType = indexArgument.mType->RemoveModifiers(); if (!indexArgument.mType->IsInteger()) { mResult = DbgTypedValue(); Fail("Expected integer index", indexerExpr->mArguments[0]); return; - } + } if (mReferenceId != NULL) *mReferenceId += "[]"; @@ -4971,11 +4960,11 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) } } } - + addr_target target = collection.mPtr; if (collection.mType->mTypeCode == DbgType_SizedArray) target = collection.mSrcAddress; - + if ((!collection.mType->IsPointer()) && (collection.mType->mTypeCode != DbgType_SizedArray)) { mResult = DbgTypedValue(); @@ -4988,8 +4977,8 @@ void DbgExprEvaluator::Visit(BfIndexerExpression* indexerExpr) { int innerSize = collection.mType->mTypeParam->GetStride(); int len = 0; - if (innerSize > 0) - len = collection.mType->GetStride() / innerSize; + if (innerSize > 0) + len = collection.mType->GetStride() / innerSize; int idx = (int)indexArgument.GetInt64(); if ((idx < 0) || (idx >= len)) { @@ -5019,7 +5008,7 @@ void DbgExprEvaluator::Visit(BfThisExpression* thisExpr) if (mExplicitThisExpr != NULL) mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(thisExpr, mCurChildRef)); mResult = mExplicitThis; - + /*if (mReferenceId != NULL) { auto checkType = mExplicitThis.mType; @@ -5043,7 +5032,7 @@ void DbgExprEvaluator::Visit(BfThisExpression* thisExpr) } void DbgExprEvaluator::Visit(BfIdentifierNode* identifierNode) -{ +{ //BfLogDbgExpr("Visit BfIdentifierNode %s\n", identifierNode->ToString().c_str()); mResult = LookupIdentifier(identifierNode, false, NULL); @@ -5055,7 +5044,7 @@ void DbgExprEvaluator::Visit(BfIdentifierNode* identifierNode) } if ((mResult) || (HasPropResult())) - return; + return; { SetAndRestoreValue prevIgnoreError(mIgnoreErrors, true); @@ -5114,7 +5103,7 @@ void DbgExprEvaluator::LookupSplatMember(const DbgTypedValue& target, const Stri } } }*/ - + bool found = false; while (checkType != NULL) { @@ -5177,13 +5166,13 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku SplatLookupEntry* splatLookupEntry = NULL; if (lookupNode != NULL) - { + { if (mSplatLookupMap.TryAdd(lookupNode, NULL, &splatLookupEntry)) { // } else if (forceName == NULL) - { + { if (outFindName != NULL) *outFindName = splatLookupEntry->mFindName; if (outIsConst != NULL) @@ -5191,7 +5180,6 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku mResult = splatLookupEntry->mResult; return; } - } String findName; @@ -5241,18 +5229,18 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku if (forceName != NULL) findName = *forceName; - + CPUStackFrame* stackFrame = GetStackFrame(); intptr valAddr; DbgType* valType = NULL; DbgAddrType addrType = DbgAddrType_Value; - + bool foundWantType = true; DbgType* wantType = target.mType; auto checkType = target.mType; checkType = checkType->RemoveModifiers(); bool valWasConst = false; - + bool foundParent = false; if (target.mSrcAddress == -1) { @@ -5270,20 +5258,20 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku { foundParent = true; findName = parentFindName; - valType = mResult.mType; + valType = mResult.mType; valWasConst = parentIsConst; } } } - + if (!foundParent) - { + { if (!mDebugTarget->GetValueByName(curMethod, findName, stackFrame, &valAddr, &valType, &addrType)) return; if (addrType == DbgAddrType_Alias) { - findName = (const char*)valAddr; + findName = (const char*)valAddr; if (!mDebugTarget->GetValueByName(curMethod, findName, stackFrame, &valAddr, &valType, &addrType)) { @@ -5297,18 +5285,18 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku return; } - } - + } + if (addrType == DbgAddrType_LocalSplat) { DbgVariable* dbgVariable = (DbgVariable*)valAddr; // Use real name, in case of aliases findName = dbgVariable->mName; - } + } } if ((wasCast) && (valType != NULL)) - { + { checkType = valType->RemoveModifiers(); foundWantType = false; @@ -5342,7 +5330,7 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku if (member->mName == fieldName) { wasUnion = checkType->IsBfUnion(); - memberType = member->mType; + memberType = member->mType; found = true; break; } @@ -5364,7 +5352,7 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku findName += "$u"; else findName += "$m$" + fieldName; - + if (outFindName != NULL) *outFindName = findName; if (outIsConst != NULL) @@ -5381,14 +5369,14 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku /*if ((valType->IsConst()) && (!memberType->IsConst())) { // Set readonly if the original value was const - memberType = mDbgModule->GetConstType(valType); + memberType = mDbgModule->GetConstType(valType); }*/ - mResult = ReadTypedValue(targetNode, memberType, valAddr, addrType); + mResult = ReadTypedValue(targetNode, memberType, valAddr, addrType); if (wantConst) { // Set readonly if the original value was const mResult.mIsReadOnly = true; - } + } } } else @@ -5412,7 +5400,7 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku //BF_ASSERT((target.mVariable != NULL) || (target.mType->GetByteCount() == 0)); mResult = target; mResult.mType = memberType; - } + } } if (splatLookupEntry != NULL) @@ -5427,10 +5415,10 @@ void DbgExprEvaluator::LookupSplatMember(BfAstNode* targetNode, BfAstNode* looku void DbgExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError, bool* hadError) { String fieldName = nameNode->mRight->ToString(); - + mResult = LookupIdentifier(nameNode->mLeft, ignoreInitialError, hadError); mResult = GetResult(); - + if (!mResult) { if (!ignoreInitialError) @@ -5451,7 +5439,7 @@ void DbgExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool i { auto target = mResult; mResult = DbgTypedValue(); - LookupSplatMember(nameNode->mLeft, nameNode, target, fieldName); + LookupSplatMember(nameNode->mLeft, nameNode, target, fieldName); } else { @@ -5465,7 +5453,7 @@ void DbgExprEvaluator::LookupQualifiedName(BfQualifiedNameNode* nameNode, bool i } } if ((mResult) || (mPropSrc != NULL)) - return; + return; if (hadError != NULL) *hadError = true; @@ -5480,7 +5468,7 @@ DbgType* DbgExprEvaluator::FindSubtype(DbgType* type, const StringImpl& name) return subType; } for (auto baseType : type->mBaseTypes) - { + { auto subType = FindSubtype(baseType->mBaseType->GetPrimaryType(), name); if (subType != NULL) return subType; @@ -5575,7 +5563,7 @@ bool DbgExprEvaluator::EnsureRunning(BfAstNode* astNode) } void DbgExprEvaluator::Visit(BfQualifiedNameNode* nameNode) -{ +{ AutocompleteCheckMemberReference(nameNode->mLeft, nameNode->mDot, nameNode->mRight); bool hadError = false; @@ -5599,7 +5587,7 @@ void DbgExprEvaluator::Visit(BfDefaultExpression* defaultExpr) } void DbgExprEvaluator::Visit(BfLiteralExpression* literalExpr) -{ +{ mIsComplexExpression = true; mResult.mIsLiteral = true; @@ -5608,17 +5596,17 @@ void DbgExprEvaluator::Visit(BfLiteralExpression* literalExpr) switch (literalExpr->mValue.mTypeCode) { case BfTypeCode_NullPtr: - { + { mResult.mPtr = 0; mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Null, GetLanguage()); } break; - case BfTypeCode_CharPtr: - mResult = GetString(*literalExpr->mValue.mString); - break; + case BfTypeCode_CharPtr: + mResult = GetString(*literalExpr->mValue.mString); + break; case BfTypeCode_Boolean: mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage()); - mResult.mBool = literalExpr->mValue.mBool; + mResult.mBool = literalExpr->mValue.mBool; break; case BfTypeCode_Char8: mResult.mType = mDbgModule->GetPrimitiveType((language == DbgLanguage_Beef) ? DbgType_UChar : DbgType_SChar, language); @@ -5722,11 +5710,11 @@ void DbgExprEvaluator::Visit(BfCastExpression* castExpr) mResult = CreateValueFromExpression(castExpr->mExpression); if (!mResult) return; - mResult = Cast(castExpr, mResult, resolvedType, true); + mResult = Cast(castExpr, mResult, resolvedType, true); } // We pass by reference to support "RAW" debug expression simplification -DbgTypedValue DbgExprEvaluator::CreateValueFromExpression(ASTREF(BfExpression*)& expr, DbgType* castToType, DbgEvalExprFlags flags) +DbgTypedValue DbgExprEvaluator::CreateValueFromExpression(ASTREF(BfExpression*)& expr, DbgType* castToType, DbgEvalExprFlags flags) { // { @@ -5763,18 +5751,18 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress { DbgTypedValue leftValue; if (leftExpression != NULL) - leftValue = CreateValueFromExpression(leftExpression, mExpectingType, DbgEvalExprFlags_NoCast); + leftValue = CreateValueFromExpression(leftExpression, mExpectingType, DbgEvalExprFlags_NoCast); DbgTypedValue rightValue; if (rightExpression == NULL) - { + { return; - } + } if (!leftValue) - { + { VisitChild(rightExpression); return; } - + leftValue.mType = leftValue.mType->RemoveModifiers(); /*if (leftValue.mType->IsRef()) @@ -5790,7 +5778,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress return; } - auto boolType = leftValue.mType; + auto boolType = leftValue.mType; if (isAnd) { @@ -5799,14 +5787,14 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress mResult = leftValue; return; } - + rightValue = CreateValueFromExpression(rightExpression); - if (rightValue) + if (rightValue) rightValue = Cast(rightExpression, rightValue, boolType); mResult = rightValue; } else - { + { if (leftValue.mBool) { mResult = leftValue; @@ -5814,29 +5802,29 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress } rightValue = CreateValueFromExpression(rightExpression); - if (rightValue) + if (rightValue) rightValue = Cast(rightExpression, rightValue, boolType); mResult = rightValue; } return; } - + if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsBfObject()))) - { + { if (leftValue.mPtr != 0) { mResult = leftValue; return; } - + CreateValueFromExpression(rightExpression, leftValue.mType); return; } - rightValue = CreateValueFromExpression(rightExpression, mExpectingType, DbgEvalExprFlags_NoCast); + rightValue = CreateValueFromExpression(rightExpression, mExpectingType, DbgEvalExprFlags_NoCast); if ((!leftValue) || (!rightValue)) return; - + rightValue.mType = rightValue.mType->RemoveModifiers(); if (leftValue.mType->IsTypedPrimitive()) @@ -5860,7 +5848,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress rightCompareSize += 0x100; if ((rightValue.mIsLiteral) && (rightValue.mType->IsPointer())) rightCompareSize += 0x200; - + /*if ((leftValue.mType->IsTypedPrimitive()) && (rightValue.mType->IsTypedPrimitive())) { int leftInheritDepth = leftValue.mType->ToTypeInstance()->mInheritDepth; @@ -5873,7 +5861,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress } }*/ - auto resultType = leftValue.mType; + auto resultType = leftValue.mType; if (!forceLeftType) { if ((resultType->IsNull()) || @@ -5896,7 +5884,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress DbgTypedValue* otherTypedValue; DbgType* otherType; BfAstNode* resultTypeSrc; - BfAstNode* otherTypeSrc; + BfAstNode* otherTypeSrc; if (resultType == leftValue.mType) { @@ -5906,7 +5894,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress otherTypeSrc = rightExpression; otherType = otherTypedValue->mType; } - else + else { resultTypedValue = &rightValue; resultTypeSrc = rightExpression; @@ -5914,9 +5902,9 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress otherTypeSrc = leftExpression; otherType = otherTypedValue->mType; } - + if ((resultTypedValue->mIsLiteral) && (resultType->IsPointer())) - { + { // If we're comparing against a string literal like 'str == "Hey!"', handle that if (BfBinOpEqualityCheck(binaryOp)) { @@ -5966,9 +5954,9 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress } } } - + Fail("Cannot perform operation with a literal value", resultTypeSrc); - return; + return; } DbgTypedValue convLeftValue; @@ -5989,17 +5977,17 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress /*if (!mModule->IsInSpecializedGeneric()) { //CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type '' - mModule->mCompiler->mPassInstance->Warn(BfWarning_CS0472_ValueTypeNullCompare, - StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null", + mModule->mCompiler->mPassInstance->Warn(BfWarning_CS0472_ValueTypeNullCompare, + StrFormat("The result of the expression is always '%s' since a value of type '%s' can never be null", isEquality ? "false" : "true", mModule->TypeToString(resultType).c_str()), otherTypeSrc); }*/ // Valuetypes never equal null auto boolType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage()); mResult.mType = boolType; - mResult.mBool = !isEquality; + mResult.mBool = !isEquality; return; - } + } } //TODO: Use operator methods? @@ -6039,10 +6027,10 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress } if (methodMatcher.mBestMethodDef != NULL) { - SetElementType(opToken, BfSourceElementType_Method); + SetElementType(opToken, BfSourceElementType_Method); mResult = CreateCall(&methodMatcher, DbgTypedValue()); - if ((invertResult) && (mResult.mType == mModule->GetPrimitiveType(BfTypeCode_Boolean))) - mResult.mValue = mModule->mIRBuilder->CreateNot(mResult.mValue); + if ((invertResult) && (mResult.mType == mModule->GetPrimitiveType(BfTypeCode_Boolean))) + mResult.mValue = mModule->mIRBuilder->CreateNot(mResult.mValue); return; } }*/ @@ -6054,13 +6042,13 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress { if (!resultType->Equals(otherType)) { - Fail(StrFormat("Operands must be the same type, '%s' doesn't match '%s'", + Fail(StrFormat("Operands must be the same type, '%s' doesn't match '%s'", leftValue.mType->ToString().c_str(), rightValue.mType->ToString().c_str()), opToken); return; } - - DbgType* intPtrType = mDbgModule->GetPrimitiveType(DbgType_IntPtr_Alias, GetLanguage()); + + DbgType* intPtrType = mDbgModule->GetPrimitiveType(DbgType_IntPtr_Alias, GetLanguage()); long ptrDiff = leftValue.mPtr - rightValue.mPtr; int elemSize = resultType->mTypeParam->GetStride(); if (elemSize == 0) @@ -6080,7 +6068,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress { Fail("Invalid operation on pointers", opToken); return; - } + } // Compare them as ints resultType = mDbgModule->GetPrimitiveType(DbgType_UIntPtr_Alias, GetLanguage()); @@ -6133,13 +6121,13 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress } if (innerType->GetByteCount() == 0) - { + { Warn("Adding to a pointer to a zero-sized element has no effect", opToken); } return; } - } + } if ((resultType->IsPointer()) || (resultType->IsBfObject()) || (resultType->IsInterface()) /*|| (resultType->IsGenericParam())*/) { @@ -6174,24 +6162,24 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_StrictEquality)) mResult.mBool = resultTypedValue->mPtr == convertedValue.mPtr; else - mResult.mBool = resultTypedValue->mPtr != convertedValue.mPtr; + mResult.mBool = resultTypedValue->mPtr != convertedValue.mPtr; } return; - } + } /*else if (resultType->IsTypedPrimitive()) { bool needsOtherCast = true; if (otherType != resultType) - { + { if (otherType->IsPrimitiveType()) - { + { // Allow zero comparisons to match all typed primitives if ((binaryOp == BfBinaryOp_Equality) || (binaryOp == BfBinaryOp_InEquality)) { auto intConstant = dyn_cast(otherTypedValue->mValue); if (intConstant != NULL) - { + { if (intConstant->getSExtValue() == 0) { needsOtherCast = false; @@ -6215,14 +6203,14 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress Value* convOtherValue = mModule->CastToValue(otherTypeSrc, *otherTypedValue, underlyingType, true); if ((!underlyingType->IsValuelessType()) && ((convResultValue == NULL) || (convOtherValue == NULL))) - return; + return; if (resultTypedValue == &leftValue) PerformBinaryOperation(underlyingType, convResultValue, convOtherValue, binaryOp, opToken); else PerformBinaryOperation(underlyingType, convOtherValue, convResultValue, binaryOp, opToken); if (mResult.mType == underlyingType) - mResult.mType = resultType; + mResult.mType = resultType; return; }*/ else if (((leftValue.mType->IsStruct()) || (leftValue.mType->IsBfObject())) && (!resultType->IsEnum())) @@ -6241,7 +6229,7 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress TypeToString(rightValue.mType).c_str()), opToken); } return; - } + } if ((resultType->IsInteger()) && (!forceLeftType)) { @@ -6257,7 +6245,6 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress { if (binaryOp == BfBinaryOp_Subtract) { - } else if (resultType->GetByteCount() < 4) { @@ -6290,8 +6277,8 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress explicitCast = true; } } - } - } + } + } if (convLeftValue == NULL) convLeftValue = Cast(leftExpression, leftValue, resultType, explicitCast); @@ -6304,13 +6291,13 @@ void DbgExprEvaluator::PerformBinaryOperation(ASTREF(BfExpression*)& leftExpress void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue convLeftValue, DbgTypedValue convRightValue, BfBinaryOp binaryOp, BfTokenNode* opToken) { if (resultType->IsValuelessType()) - { + { switch (binaryOp) { case BfBinaryOp_Equality: case BfBinaryOp_StrictEquality: mResult.mType = mDbgModule->GetPrimitiveType(DbgType_Bool, GetLanguage()); - mResult.mBool = true; + mResult.mBool = true; break; case BfBinaryOp_InEquality: case BfBinaryOp_StrictInEquality: @@ -6321,14 +6308,14 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue Fail("Invalid operation for void", opToken); break; } - return; + return; } if ((convLeftValue == NULL) || (convRightValue == NULL)) return; - if ((resultType->IsEnum()) || (resultType->IsTypedPrimitive())) - resultType = resultType->GetUnderlyingType(); + if ((resultType->IsEnum()) || (resultType->IsTypedPrimitive())) + resultType = resultType->GetUnderlyingType(); if (resultType->IsPrimitiveType()) { @@ -6361,7 +6348,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue } return; } - } + } if ((!resultType->IsIntegral()) && (!resultType->IsFloat())) { @@ -6371,7 +6358,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue mResult.mType = resultType; if (resultType->IsInteger()) - { + { switch (binaryOp) { case BfBinaryOp_BitwiseAnd: @@ -6386,7 +6373,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue case BfBinaryOp_LeftShift: mResult.mInt64 = convLeftValue.GetInt64() << convRightValue.GetInt64(); return; - case BfBinaryOp_RightShift: + case BfBinaryOp_RightShift: mResult.mInt64 = convLeftValue.GetInt64() >> convRightValue.GetInt64(); return; } @@ -6401,7 +6388,7 @@ void DbgExprEvaluator::PerformBinaryOperation(DbgType* resultType, DbgTypedValue else if (resultType->mTypeCode == DbgType_Double) mResult.mDouble = convLeftValue.mDouble + convRightValue.mDouble; else - mResult.mInt64 = convLeftValue.GetInt64() + convRightValue.GetInt64(); + mResult.mInt64 = convLeftValue.GetInt64() + convRightValue.GetInt64(); break; case BfBinaryOp_Subtract: case BfBinaryOp_OverflowSubtract: @@ -6529,7 +6516,7 @@ void DbgExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) //PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, false); // Check for "(double)-1.0" style cast, misidentified as a binary operation - if ((binOpExpr->mOp == BfBinaryOp_Add) || (binOpExpr->mOp == BfBinaryOp_Subtract) || + if ((binOpExpr->mOp == BfBinaryOp_Add) || (binOpExpr->mOp == BfBinaryOp_Subtract) || (binOpExpr->mOp == BfBinaryOp_BitwiseAnd) || (binOpExpr->mOp == BfBinaryOp_Multiply)) { if (auto parenExpr = BfNodeDynCast(binOpExpr->mLeft)) @@ -6557,7 +6544,7 @@ void DbgExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) { VisitChild(binOpExpr->mRight); if (!mResult) - return; + return; } if ((mResult) && (binOpExpr->mOp == BfBinaryOp_Subtract)) @@ -6570,7 +6557,7 @@ void DbgExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) mResult.mInt64 = -mResult.GetInt64(); } - mResult = Cast(binOpExpr, mResult, resolvedType, true); + mResult = Cast(binOpExpr, mResult, resolvedType, true); return; } } @@ -6586,7 +6573,7 @@ void DbgExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) VisitChild(binOpExpr->mLeft); if (mResult) - { + { //if (mAutoComplete != NULL) //mAutoComplete->CheckEmptyStart(binOpExpr->mOpToken, mResult.mType); } @@ -6599,7 +6586,6 @@ void DbgExprEvaluator::Visit(BfBinaryOperatorExpression* binOpExpr) PerformBinaryOperation(binOpExpr->mLeft, binOpExpr->mRight, binOpExpr->mOp, binOpExpr->mOpToken, false); } - void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unaryOp, ASTREF(BfExpression*)& expr) { if (unaryOp != BfUnaryOp_Dereference) @@ -6624,7 +6610,7 @@ void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unar if (ptr.mType->IsEnum()) ptr.mType = ptr.mType->mTypeParam; - + auto val = mResult; int add = ((unaryOp == BfUnaryOp_Decrement) || (unaryOp == BfUnaryOp_PostDecrement)) ? -1 : 1; switch (ptr.mType->mTypeCode) @@ -6690,7 +6676,7 @@ void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unar { Fail("Operator can only be used on pointer values", opToken); return; - } + } mResult = ReadTypedValue(opToken, type->mTypeParam, mResult.mPtr, DbgAddrType_Target); } break; @@ -6722,7 +6708,7 @@ void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unar { Fail("Operator can only be used on boolean values", opToken); return; - } + } mResult.mIsLiteral = wasLiteral; mResult.mBool = !mResult.mBool; } @@ -6737,7 +6723,7 @@ void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unar if (wasLiteral) { // This is a special case where the user entered -0x80000000 (maxint) but we thought "0x80000000" was a uint in the parser - // which would get expanded to an int64 for this negate. Properly bring back down to an int32 + // which would get expanded to an int64 for this negate. Properly bring back down to an int32 if ((primType->mTypeCode == DbgType_u32) && (mResult.GetInt64() == -0x80000000LL)) { //mResult = DbgTypedValue(mModule->GetConstValue((int) i64Val), mModule->GetPrimitiveType(DwTypeCode_Int32)); @@ -6763,7 +6749,7 @@ void DbgExprEvaluator::PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unar } mResult.mIsLiteral = wasLiteral; - if (mResult.mType->mTypeCode == DbgType_Single) + if (mResult.mType->mTypeCode == DbgType_Single) mResult.mSingle = -mResult.mSingle; else if (mResult.mType->mTypeCode == DbgType_Double) mResult.mDouble = -mResult.mDouble; @@ -6814,9 +6800,9 @@ void DbgExprEvaluator::Visit(BfUnaryOperatorExpression* unaryOpExpr) bool DbgExprEvaluator::ResolveArgValues(const BfSizedArray& arguments, SizedArrayImpl& outArgValues) { for (int argIdx = 0; argIdx < (int) arguments.size(); argIdx++) - { + { //BfExprEvaluator exprEvaluator(mModule); - //exprEvaluator.Evaluate(arguments[argIdx]); + //exprEvaluator.Evaluate(arguments[argIdx]); auto arg = arguments[argIdx]; DbgTypedValue argValue; if (arg != NULL) @@ -6844,7 +6830,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue mPassInstance->Fail("Not running"); return DbgTypedValue(); }*/ - + #ifdef BF_WANTS_LOG_DBGEXPR auto _GetResultString = [&](DbgTypedValue val) { @@ -6852,7 +6838,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue if (val.mSrcAddress != 0) { result += StrFormat("0x%p ", val.mSrcAddress); - + int64 vals[4] = { 0 }; mDebugger->ReadMemory(val.mSrcAddress, 4 * 8, vals); @@ -6864,18 +6850,18 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue } return result; }; -#endif - +#endif + int curCallResultIdx = mCallResultIdx++; if (((mExpressionFlags & DwEvalExpressionFlag_AllowCalls) == 0) || (mCreatedPendingCall)) { BfLogDbgExpr(" BlockedSideEffects\n"); - mBlockedSideEffects = true; + mBlockedSideEffects = true; return GetDefaultTypedValue(method->mReturnType); } - mHadSideEffects = true; - + mHadSideEffects = true; + // Our strategy is to create "pending results" for each call in a debug expression, and then we continually re-evaluate the // entire expression using the actual returned results for each of those calls until we can finally evaluate it as a whole if (curCallResultIdx < (int)mCallResults->size() - 1) @@ -6909,7 +6895,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue returnVal = mDebugger->ReadReturnValue(&newPhysRegisters, method->mReturnType); bool hadRef = false; auto returnType = method->mReturnType->RemoveModifiers(&hadRef); - if (hadRef) + if (hadRef) { returnVal = ReadTypedValue(NULL, returnType, returnVal.mPtr, DbgAddrType_Target); returnVal.mType = returnType; @@ -6919,17 +6905,17 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue { returnVal.mType = mDbgModule->GetPrimitiveType(DbgType_Void, GetLanguage()); } - + BfLogDbgExpr(" using new results %s\n", _GetResultString(returnVal).c_str()); mDebugger->RestoreAllRegisters(); - + if ((method->mReturnType->IsCompositeType()) && (mDebugger->CheckNeedsSRetArgument(method->mReturnType))) { callResult.mSRetData.Resize(method->mReturnType->GetByteCount()); mDebugger->ReadMemory(returnVal.mSrcAddress, method->mReturnType->GetByteCount(), &callResult.mSRetData[0]); } - callResult.mResult = returnVal; + callResult.mResult = returnVal; return returnVal; } @@ -6990,14 +6976,14 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue } mDebugger->SaveAllRegisters(); - + BfLogDbg("Starting RunState_DebugEval on thread %d\n", mDebugger->mActiveThread->mThreadId); - addr_target prevSP = registers->GetSP(); - + addr_target prevSP = registers->GetSP(); + //registers->mIntRegs.efl = 0x244; - //mDebugger->PushValue(registers, 0); + //mDebugger->PushValue(registers, 0); mDebugger->PushValue(registers, 42); *(registers->GetPCRegisterRef()) = startAddr; @@ -7007,12 +6993,12 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue // If we step ONTO the PC we set, then that means we have returned from kernel mode // so we need to set the registers again (they would have been clobbered due to SetThreadContext bugs). // If we step past the PC then we're all good - registers->mIntRegs.efl |= 0x100; - mDebugger->SetRegisters(registers); + registers->mIntRegs.efl |= 0x100; + mDebugger->SetRegisters(registers); //::ResumeThread(mDebugger->mActiveThread->mHThread); //TODO: For debugging stepping: - + if ((mExpressionFlags & DwEvalExpressionFlag_StepIntoCalls) != 0) { mDebugger->mDebugManager->mOutMessages.push_back("rehupLoc"); @@ -7031,7 +7017,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue mDebugger->mRequestedStackFrameIdx = -1; BfLogDbg("DbgExprEvaluator::CreateCall %p in thread %d\n", startAddr, mDebugger->mActiveThread->mThreadId); - + DbgCallResult callResult; callResult.mSubProgram = method; callResult.mStructRetVal = structRetVal; @@ -7044,8 +7030,8 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, DbgTypedValue DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue target, DbgSubprogram* method, bool bypassVirtual, const BfSizedArray& arguments, SizedArrayImpl& argValues) { HashSet splatParams; - SizedArray argPushQueue; - + SizedArray argPushQueue; + // { for (auto variable : method->mBlock.mVariables) @@ -7064,7 +7050,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t int argIdx = 0; int paramIdx = 0; - + auto _PushArg = [&](const DbgTypedValue& typedValue, DbgVariable* param) { if (typedValue.mType->GetByteCount() == 0) @@ -7087,7 +7073,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t { auto elemTypedValue = ReadTypedValue(targetSrc, type, typedVal.mSrcAddress, DbgAddrType_Target); DbgMethodArgument methodArg; - methodArg.mTypedValue = elemTypedValue; + methodArg.mTypedValue = elemTypedValue; argPushQueue.push_back(methodArg); return; } @@ -7117,7 +7103,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t return; } } - + DbgMethodArgument methodArg; methodArg.mTypedValue = typedValue; methodArg.mWantsRef = param->mType->IsRef(); @@ -7133,7 +7119,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t if (method->mHasThis) { - auto param = method->mParams[paramIdx]; + auto param = method->mParams[paramIdx]; if ((param->mType != NULL) && (param->mType->IsValueType())) thisByValue = true; @@ -7142,12 +7128,12 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t Fail(StrFormat("An object reference is required to invoke the non-static method '%s'", method->ToString().c_str()), targetSrc); return DbgTypedValue(); } - + _PushArg(target, param); - methodParamCount--; + methodParamCount--; } else - { + { if (target.mPtr != 0) { Fail(StrFormat("Method '%s' cannot be accessed with an instance reference; qualify it with a type name instead", method->ToString().c_str()), targetSrc); @@ -7157,8 +7143,8 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t DbgTypedValue expandedParamsArray; DbgType* expandedParamsElementType = NULL; - int extendedParamIdx = 0; - + int extendedParamIdx = 0; + int paramOffset = method->mHasThis ? 1 : 0; while (true) { @@ -7180,18 +7166,18 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t } break; } - + DbgVariable* param = NULL; DbgType* wantType = NULL; - if (expandedParamsElementType != NULL) + if (expandedParamsElementType != NULL) { - wantType = expandedParamsElementType; + wantType = expandedParamsElementType; } else { param = method->mParams[paramIdx + paramOffset]; wantType = param->mType; - + //TODO: /*if (method->mParams[paramIdx]->mParamType == BfParamType_Params) { @@ -7199,7 +7185,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t bool isDirectPass = false; if (argIdx < (int)arguments.size()) - { + { if (argValues[argIdx].mValue == NULL) return DbgTypedValue(); if (mModule->CanCast(argValues[argIdx], wantType)) @@ -7268,7 +7254,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t BfAstNode* refNode = targetSrc; if (arguments.size() > 0) refNode = arguments.back(); - mModule->Fail(StrFormat("Not enough parameters specified. Got %d, expected %d.", arguments.size(), methodInstance->mParamTypes.size()), refNode); + mModule->Fail(StrFormat("Not enough parameters specified. Got %d, expected %d.", arguments.size(), methodInstance->mParamTypes.size()), refNode); return DbgTypedValue(); } llvmArgs.push_back(methodInstance->mDefaultValues[argIdx]);*/ @@ -7283,7 +7269,6 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t continue; } - if (argValue.mType == NULL) return DbgTypedValue(); @@ -7319,7 +7304,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t wantType = mDbgModule->GetPointerType(wantType->mTypeParam); argValue.mPtr = argValue.mSrcAddress; argValue.mSrcAddress = 0; - argValue.mType = wantType; + argValue.mType = wantType; }*/ argValue = Cast(arg, argValue, wantType); @@ -7348,7 +7333,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t Fail("Invalid expression type", arg); return DbgTypedValue(); } - + //TODO: /*if (expandedParamsArray) { @@ -7360,18 +7345,18 @@ DbgTypedValue DbgExprEvaluator::CreateCall(BfAstNode* targetSrc, DbgTypedValue t else*/ { //llvmArgs.push_back(argValue.mValue); - _PushArg(argValue, param); + _PushArg(argValue, param); paramIdx++; - } + } argIdx++; } return CreateCall(method, argPushQueue, bypassVirtual); } - + DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl& argPushQueue, bool bypassVirtual) { - BfLogDbgExpr("CreateCall #%d %s", mCallResultIdx, method->mName); + BfLogDbgExpr("CreateCall #%d %s", mCallResultIdx, method->mName); if (mDebugger->IsMiniDumpDebugger()) { @@ -7384,7 +7369,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl mBlockedSideEffects = true; return GetDefaultTypedValue(method->mReturnType); } - mHadSideEffects = true; + mHadSideEffects = true; // We need current physical registers to make sure we push params in correct stack frame CPURegisters registers; @@ -7408,18 +7393,18 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl if ((param->mType != NULL) && (param->mType->IsValueType())) thisByValue = true; } - + DbgTypedValue structRetVal; if (mDebugger->CheckNeedsSRetArgument(method->mReturnType)) { int retSize = BF_ALIGN(method->mReturnType->GetByteCount(), 16); - *regSP -= retSize; + *regSP -= retSize; structRetVal.mType = method->mReturnType; structRetVal.mSrcAddress = *regSP; // For chained calls we need to leave the sret form the previous calls intact mCallStackPreservePos = *regSP; - } + } for (int i = (int)argPushQueue.size() - 1; i >= 0; i--) { @@ -7429,19 +7414,19 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl // on the stack and pass that address if (arg.mWantsRef) { - auto& typedValue = arg.mTypedValue; + auto& typedValue = arg.mTypedValue; auto rootType = typedValue.mType->RemoveModifiers(); if (arg.mTypedValue.mSrcAddress != 0) { typedValue.mPtr = typedValue.mSrcAddress; } else - { + { int rootSize = rootType->GetByteCount(); - *regSP -= BF_ALIGN(rootSize, 16); + *regSP -= BF_ALIGN(rootSize, 16); mDebugger->WriteMemory(*regSP, &arg.mTypedValue.mInt64, rootSize); // Write from debugger memory to target typedValue.mPtr = *regSP; - } + } typedValue.mType = mDbgModule->GetPointerType(rootType); typedValue.mSrcAddress = 0; @@ -7449,11 +7434,11 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl } if (structRetVal.mSrcAddress != 0) - { + { BfLogDbgExpr(" SRet:0x%p", structRetVal.mSrcAddress); mDebugger->AddParamValue(0, method->mHasThis && !thisByValue, ®isters, structRetVal); paramIdx++; - } + } DbgTypedValue thisVal; for (int padCount = 0; true; padCount++) @@ -7462,12 +7447,12 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl int paramIdxSave = paramIdx; *regSP -= padCount * sizeof(addr_target); - + for (int i = (int)argPushQueue.size() - 1; i >= 0; i--) { auto& arg = argPushQueue[i]; if ((i == 0) && (method->mHasThis) && (!method->ThisIsSplat())) - { + { thisVal = arg.mTypedValue; addr_target thisAddr; if (thisVal.mType->IsCompositeType()) @@ -7496,15 +7481,15 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl registers = regSave; paramIdx = paramIdxSave; - + BF_ASSERT(padCount < 3); } return CreateCall(method, thisVal, structRetVal, bypassVirtual, ®isters); } -DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName, - const BfSizedArray& arguments, BfSizedArray* methodGenericArguments) +DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName, + const BfSizedArray& arguments, BfSizedArray* methodGenericArguments, bool& failed) { SetAndRestoreValue prevReferenceId(mReferenceId, NULL); @@ -7516,7 +7501,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue SizedArray argValues; if (!ResolveArgValues(arguments, argValues)) return DbgTypedValue(); - + if ((methodName == "__cast") || (methodName == "__bitcast")) { if (argValues.size() > 0) @@ -7547,7 +7532,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue BeefTypeToString(arg, typeName); } } - + auto castedType = mDbgModule->FindType(typeName, NULL, GetLanguage(), true); if (castedType == NULL) { @@ -7565,27 +7550,26 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue Fail(StrFormat("Unable to find type: '%s'", typeName.c_str()), targetSrc); return argValues[targetArgIdx]; } - + if (methodName == "__bitcast") { DbgTypedValue result = argValues[targetArgIdx]; result.mType = castedType; return result; } - - return Cast(arguments[targetArgIdx], argValues[targetArgIdx], castedType, true); - } - } + + return Cast(arguments[targetArgIdx], argValues[targetArgIdx], castedType, true); + } + } else if (methodName == "__hasField") { if (argValues.size() == 2) { - auto checkType = argValues[0].mType; + auto checkType = argValues[0].mType; if ((checkType != NULL) && (checkType->IsPointer())) checkType = checkType->mTypeParam; if (checkType != NULL) { - //TODO: Protect String findFieldName = argValues[1].mCharPtr; @@ -7784,7 +7768,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue else if (methodName == "__stringView") { if (argValues.size() >= 2) - { + { if ((argValues[1].mType != NULL) && (argValues[1].mType->IsInteger())) mCountResultOverride = (intptr)argValues[1].GetInt64(); return argValues[0]; @@ -7812,7 +7796,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue if (bitCount <= 0) return argValues[0]; - + int64 andBits = (0x8000000000000000LL) >> ((argValues[0].mType->GetByteCount() - 8) * 8 + bitCount - 1); DbgTypedValue result; result.mType = argValues[0].mType; @@ -7823,7 +7807,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue else if (methodName == "__parseCompileUnits") { for (auto dbgModule : mDebugTarget->mDbgModules) - { + { dbgModule->ParseCompileUnits(); } } @@ -7832,7 +7816,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue DbgType* targetTypeInst = NULL; bool checkNonStatic = true; if (target) - { + { targetTypeInst = target.mType; curTypeDef = targetTypeInst; } @@ -7842,7 +7826,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue { //TODO ; //targetTypeInst = mModule->GetPrimitiveStructType(target.mType); - } + } else targetTypeInst = target.mType; if (targetTypeInst == NULL) @@ -7854,15 +7838,15 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue checkNonStatic = false; } else // Current scope - { + { curTypeDef = GetCurrentType(); targetTypeInst = GetCurrentType(); auto currentMethod = GetCurrentMethod(); - + checkNonStatic = (currentMethod != NULL) && (currentMethod->mHasThis); } - DbgSubprogram* methodDef = NULL; + DbgSubprogram* methodDef = NULL; BfTypeVector checkMethodGenericArguments; bool isFailurePass = false; @@ -7872,7 +7856,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue methodMatcher.mTargetIsConst = targetTypeInst->IsConst(); if (targetTypeInst != NULL) { - methodMatcher.CheckType(targetTypeInst, false); + methodMatcher.CheckType(targetTypeInst, false); if (methodMatcher.mBestMethodDef == NULL) { isFailurePass = true; @@ -7904,8 +7888,8 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue if (allowImplicitThis) { //auto thisValue = mModule->GetThis(); - //LookupField(targetSrc, thisValue, methodName); - fieldVal = LookupIdentifier(BfNodeDynCast(targetSrc)); + //LookupField(targetSrc, thisValue, methodName); + fieldVal = LookupIdentifier(BfNodeDynCast(targetSrc)); } else { @@ -7924,9 +7908,9 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue if (fieldTypeInst->mTypeDef->mIsDelegate) return MatchMethod(targetSrc, fieldVal, false, false, "Invoke", arguments, methodGenericArguments); } - fieldVal.mType = mModule->ResolveGenericParam(fieldVal.mType); - if (fieldVal.mType->IsVar()) - return DbgTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType); + fieldVal.mType = mModule->ResolveGenericParam(fieldVal.mType); + if (fieldVal.mType->IsVar()) + return DbgTypedValue(mModule->GetDefaultValue(fieldVal.mType), fieldVal.mType); mModule->Fail(StrFormat("Cannot perform invocation on type '%s'", mModule->TypeToString(fieldVal.mType).c_str()), targetSrc); return DbgTypedValue(); }*/ @@ -7960,7 +7944,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue mModule->Fail("Objects must be allocated through 'new' or 'stack'", targetSrc); return DbgTypedValue(); } - + DbgTypedValue structInst = DbgTypedValue(mModule->mIRBuilder->CreateAlloca(resolvedType->mLLVMType), resolvedType, false); MatchConstructor(targetSrc, structInst, resolvedType, arguments, false); @@ -7970,11 +7954,11 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue }*/ if ((methodDef == NULL) && (!target)) - { + { for (int compileUnitIdx = 0; compileUnitIdx < (int)mDbgModule->mCompileUnits.size(); compileUnitIdx++) { auto compileUnit = mDbgModule->mCompileUnits[compileUnitIdx]; - methodMatcher.CheckType(compileUnit->mGlobalType, isFailurePass); + methodMatcher.CheckType(compileUnit->mGlobalType, isFailurePass); if (methodMatcher.mBestMethodDef != NULL) { isFailurePass = false; @@ -7982,7 +7966,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue methodDef = methodMatcher.mBestMethodDef; break; } - } + } } if ((methodDef == NULL) && ((methodGenericArguments == NULL) || (methodGenericArguments->IsEmpty()))) @@ -7998,11 +7982,81 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue } if (methodDef == NULL) - { - Fail("Method does not exist", targetSrc); + { + if (target) + { + std::function _CheckUsingFields = [&](DbgTypedValue checkTarget) + { + auto curCheckType = checkTarget.mType->RemoveModifiers(); + curCheckType = curCheckType->GetPrimaryType(); + curCheckType->PopulateType(); + + auto nextMember = curCheckType->mMemberList.mHead; + while (nextMember != NULL) + { + auto checkMember = nextMember; + nextMember = checkMember->mNext; + + if (checkMember->mName == NULL) + { + //TODO: Check inside anonymous type + DbgTypedValue innerTarget; + + addr_target targetPtr = checkTarget.mSrcAddress; + if ((checkTarget.mType != NULL) && (checkTarget.mType->HasPointer())) + targetPtr = checkTarget.mPtr; + innerTarget.mSrcAddress = targetPtr + checkMember->mMemberOffset; + innerTarget.mType = checkMember->mType; + + failed = false; + auto result = MatchMethod(targetSrc, innerTarget, false, bypassVirtual, methodName, arguments, methodGenericArguments, failed); + if (!failed) + return result; + } + } + + for (auto baseTypeEntry : curCheckType->mBaseTypes) + { + auto baseType = baseTypeEntry->mBaseType; + + DbgTypedValue baseTarget = target; + addr_target* ptrRef = NULL; + if ((baseTarget.mPtr != 0) && (checkTarget.mType->HasPointer())) + ptrRef = &baseTarget.mPtr; + else if (baseTarget.mSrcAddress != 0) + ptrRef = &baseTarget.mSrcAddress; + + if (ptrRef != NULL) + { + if (baseTypeEntry->mVTableOffset != -1) + { + addr_target vtableAddr = mDebugger->ReadMemory(checkTarget.mPtr); + int32 virtThisOffset = mDebugger->ReadMemory(vtableAddr + baseTypeEntry->mVTableOffset * sizeof(int32)); + *ptrRef += virtThisOffset; + } + else + *ptrRef += baseTypeEntry->mThisOffset; + } + + baseTarget.mType = baseType; + auto result = _CheckUsingFields(baseTarget); + if (!failed) + return result; + } + + failed = true; + return DbgTypedValue(); + }; + + auto result = _CheckUsingFields(target); + if (!failed) + return result; + } + + failed = true; return DbgTypedValue(); - } - + } + // Don't execute the method if we've had a failure (like an ambiguous lookup) if ((mPassInstance != NULL) && (mPassInstance->HasFailed())) return DbgTypedValue(); @@ -8013,7 +8067,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue callTarget = target; } else if (target) - { + { bool handled = false; if (target.mType->IsCompositeType()) { @@ -8022,7 +8076,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue /*if (curTypeInst->IsObject()) { // Box it - callTarget = mModule->Cast(targetSrc, target, curTypeInst, true); + callTarget = mModule->Cast(targetSrc, target, curTypeInst, true); handled = true; }*/ } @@ -8034,7 +8088,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue callTarget = DbgTypedValue(mModule->mIRBuilder->CreateBitCast(targetValue, curTypeInst->mPtrLLVMType), curTypeInst);*/ callTarget = target; } - } + } if (prevReferenceId.mPrevVal != NULL) { @@ -8043,10 +8097,10 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue *prevReferenceId.mPrevVal += methodDef->ToString(); } - return CreateCall(targetSrc, callTarget, methodDef, bypassVirtual, arguments, argValues); + return CreateCall(targetSrc, callTarget, methodDef, bypassVirtual, arguments, argValues); } -void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray& args, BfSizedArray* methodGenericArguments) +void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray& args, BfSizedArray* methodGenericArguments, bool& failed) { bool allowImplicitThis = false; BfAstNode* methodNodeSrc = target; @@ -8056,11 +8110,11 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray(target)) - { + { //GetAutoComplete()->CheckMemberReference(memberRefExpression->mTarget, memberRefExpression->mDotToken, memberRefExpression->mMemberName); if (memberRefExpression->mMemberName == NULL) - return; + return; if (memberRefExpression->IsA()) bypassVirtual = true; @@ -8069,13 +8123,13 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray(memberRefExpression->mMemberName)) { - methodNodeSrc = attrIdentifier->mIdentifier; + methodNodeSrc = attrIdentifier->mIdentifier; if (attrIdentifier->mIdentifier != NULL) targetFunctionName = attrIdentifier->mIdentifier->ToString(); } else targetFunctionName = memberRefExpression->mMemberName->ToString(); - + if (memberRefExpression->mTarget == NULL) { // Dot-qualified @@ -8102,22 +8156,22 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray(target)) - { + { /*if (GetAutoComplete() != NULL) GetAutoComplete()->CheckMemberReference(qualifiedName->mLeft, qualifiedName->mDot, qualifiedName->mRight);*/ - - String leftName = qualifiedName->mLeft->ToString(); - if (leftName == "base") - bypassVirtual = true; - methodNodeSrc = qualifiedName->mRight; + String leftName = qualifiedName->mLeft->ToString(); + if (leftName == "base") + bypassVirtual = true; + + methodNodeSrc = qualifiedName->mRight; if (auto attrIdentifier = BfNodeDynCast(qualifiedName->mRight)) { - methodNodeSrc = attrIdentifier->mIdentifier; + methodNodeSrc = attrIdentifier->mIdentifier; targetFunctionName = attrIdentifier->mIdentifier->ToString(); } else - targetFunctionName = qualifiedName->mRight->ToString(); + targetFunctionName = qualifiedName->mRight->ToString(); bool hadError = false; thisValue = LookupIdentifier(qualifiedName->mLeft, true, &hadError); @@ -8132,12 +8186,12 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray prevIgnoreErrors(mIgnoreErrors, true); type = ResolveTypeRef(qualifiedName->mLeft); - } + } /*if (type->IsGenericParam()) { auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)type); - type = genericParamInstance->mTypeConstraint; + type = genericParamInstance->mTypeConstraint; }*/ if (type != NULL) @@ -8156,13 +8210,12 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray(target)) { allowImplicitThis = true; targetFunctionName = target->ToString(); - } else if (auto invocationExpr = BfNodeDynCast(target)) { @@ -8173,7 +8226,7 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArrayIsTypeInstance()) { auto invocationTypeInst = innerInvocationResult.mType->ToTypeInstance(); @@ -8188,7 +8241,7 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArrayToString().c_str()), invocationExpr->mTarget); return; - } + } } else { @@ -8197,16 +8250,16 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArrayIsPointer()) { - //BF_ASSERT(thisValue.mIsAddr); + //BF_ASSERT(thisValue.mIsAddr); thisValue.mType = thisValue.mType->mTypeParam; thisValue.mSrcAddress = thisValue.mPtr; } if (thisValue.mType->IsPrimitiveType()) - { + { //TODO: /*auto primStructType = GetPrimitiveStructType(thisValue.mType); //thisValue = mModule->Cast(target, thisValue, primStructType); @@ -8215,19 +8268,19 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArraysetAlignment(primStructType->mAlign); auto primPtr = mModule->mIRBuilder->CreateConstInBoundsGEP2_32(srcAlloca, 0, 0); mModule->mIRBuilder->CreateStore(thisValue.mValue, primPtr); - + thisValue = DbgTypedValue(srcAlloca, primStructType, true);*/ } if (thisValue.mType->IsEnum()) - { + { //auto enumStructType = thisValue.mType->ToTypeInstance(); /*auto srcAlloca = mModule->GetHeadIRBuilder()->CreateAlloca(enumStructType->mInstLLVMType, 0); srcAlloca->setAlignment(enumStructType->mAlign); auto enumPtr = mModule->mIRBuilder->CreateConstInBoundsGEP2_32(srcAlloca, 0, 0); mModule->mIRBuilder->CreateStore(thisValue.mValue, enumPtr);*/ - + //thisValue = DbgTypedValue(mModule->mIRBuilder->CreateBitCast(srcAlloca, enumStructType->mBaseType->mPtrLLVMType), enumStructType->mBaseType, true); } @@ -8238,29 +8291,33 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArraymIsCapturingMethodMatchInfo); /*if (mAutoComplete != NULL) mAutoComplete->CheckInvocation(invocationExpr, invocationExpr->mOpenParen, invocationExpr->mCloseParen, invocationExpr->mCommas);*/ - + BfSizedArray* methodGenericArguments = NULL; if (invocationExpr->mGenericArgs != NULL) methodGenericArguments = &invocationExpr->mGenericArgs->mGenericArgs; - DoInvocation(invocationExpr->mTarget, invocationExpr->mArguments, methodGenericArguments); - + bool failed = false; + DoInvocation(invocationExpr->mTarget, invocationExpr->mArguments, methodGenericArguments, failed); + if (failed) + Fail("Method does not exist", invocationExpr->mTarget); + if ((wasCapturingMethodInfo) && (!mAutoComplete->mIsCapturingMethodMatchInfo)) - { + { mAutoComplete->mIsCapturingMethodMatchInfo = true; BF_ASSERT(mAutoComplete->mMethodMatchInfo != NULL); } else if (mAutoComplete != NULL) - mAutoComplete->mIsCapturingMethodMatchInfo = false; + mAutoComplete->mIsCapturingMethodMatchInfo = false; } void DbgExprEvaluator::Visit(BfConditionalExpression* condExpr) @@ -8294,7 +8351,7 @@ void DbgExprEvaluator::Visit(BfTypeAttrExpression* typeAttrExpr) { if (typeAttrExpr->mTypeRef == NULL) return; - + AutocompleteCheckType(typeAttrExpr->mTypeRef); auto dbgType = ResolveTypeRef(typeAttrExpr->mTypeRef); if (dbgType == NULL) @@ -8337,13 +8394,13 @@ void DbgExprEvaluator::Visit(BfTupleExpression* tupleExpr) Fail(StrFormat("Tuple expressions cannot be used for type '%s'", mReceivingValue->mType->ToString().c_str()), tupleExpr); return; } - + CheckTupleCreation(mReceivingValue->mSrcAddress, tupleExpr, mReceivingValue->mType, tupleExpr->mValues, &tupleExpr->mNames); mReceivingValue = NULL; } DbgTypedValue DbgExprEvaluator::Resolve(BfExpression* expr, DbgType* wantType) -{ +{ //BfLogDbgExpr("Dbg Evaluate %s\n", expr->ToString().c_str()); BF_ASSERT(!HasPropResult()); @@ -8368,12 +8425,12 @@ DbgTypedValue DbgExprEvaluator::Resolve(BfExpression* expr, DbgType* wantType) { if (!mResult) break; - if (//(mResult.mType->mTypeCode == DbgType_Const) || + if (//(mResult.mType->mTypeCode == DbgType_Const) || (mResult.mType->mTypeCode == DbgType_Volatile)) mResult.mType = mResult.mType->mTypeParam; else break; - } + } if ((mResult) && (wantType != NULL)) mResult = Cast(expr, mResult, wantType); @@ -8407,7 +8464,7 @@ BfAstNode* DbgExprEvaluator::FinalizeExplicitThisReferences(BfAstNode* headNode) if ((unaryOpExpr->mOp != BfUnaryOp_AddressOf) && (unaryOpExpr->mOp != BfUnaryOp_Dereference)) doWrap = true; } - if ((explicitThisExpr->IsA()) || + if ((explicitThisExpr->IsA()) || (explicitThisExpr->IsA()) || (explicitThisExpr->IsA())) doWrap = true; @@ -8421,14 +8478,14 @@ BfAstNode* DbgExprEvaluator::FinalizeExplicitThisReferences(BfAstNode* headNode) auto source = headNode->GetSourceData(); for (auto& replaceNodeRecord : mDeferredInsertExplicitThisVector) - { + { auto replaceNode = replaceNodeRecord.mNode; DbgType* castType = NULL; auto typeRef = BfNodeDynCast(replaceNode); if ((typeRef != NULL) || (replaceNodeRecord.mForceTypeRef)) - { + { castType = ResolveTypeRef(replaceNode); if (castType == NULL) continue; @@ -8438,14 +8495,14 @@ BfAstNode* DbgExprEvaluator::FinalizeExplicitThisReferences(BfAstNode* headNode) // We must do this because we can't insert the actual 'this' node into multiple parents auto thisExprNode = source->mAlloc.Alloc(); BfAstNode* newNode = NULL; - + if (castType != NULL) { bfReducer.ReplaceNode(replaceNode, thisExprNode); newNode = thisExprNode; } else if (auto thisNode = BfNodeDynCast(replaceNode)) - { + { bfReducer.ReplaceNode(replaceNode, thisExprNode); newNode = thisExprNode; } @@ -8463,7 +8520,7 @@ BfAstNode* DbgExprEvaluator::FinalizeExplicitThisReferences(BfAstNode* headNode) bfReducer.MoveNode(thisExprNode, memberRefNode); memberRefNode->mTarget = thisExprNode; - newNode = memberRefNode; + newNode = memberRefNode; } if (newNode != NULL) @@ -8484,9 +8541,9 @@ BfAstNode* DbgExprEvaluator::FinalizeExplicitThisReferences(BfAstNode* headNode) int thisLen = (int)replaceString.length(); int srcStart = bfParser->AllocChars(thisLen); - memcpy((char*)source->mSrc + srcStart, replaceString.c_str(), thisLen); + memcpy((char*)source->mSrc + srcStart, replaceString.c_str(), thisLen); thisExprNode->Init(srcStart, srcStart, srcStart + thisLen); } return headNode; -} +} \ No newline at end of file diff --git a/IDEHelper/DbgExprEvaluator.h b/IDEHelper/DbgExprEvaluator.h index 81c80889..ecfa164f 100644 --- a/IDEHelper/DbgExprEvaluator.h +++ b/IDEHelper/DbgExprEvaluator.h @@ -48,14 +48,14 @@ public: intptr mLocalIntPtr; DbgVariable* mVariable; }; - bool mIsLiteral; + bool mIsLiteral; bool mHasNoValue; bool mIsReadOnly; - union + union { int mRegNum; int mDataLen; - }; + }; addr_target mSrcAddress; public: @@ -63,13 +63,13 @@ public: { mType = NULL; mUInt64 = 0; - mIsLiteral = false; + mIsLiteral = false; mSrcAddress = 0; mHasNoValue = false; mIsReadOnly = false; mRegNum = -1; } - + DbgType* ResolveTypeDef() const { auto typeDef = mType; @@ -79,7 +79,7 @@ public: } int64 GetSExtInt() const - { + { auto resolvedType = mType->RemoveModifiers(); switch (resolvedType->mTypeCode) { @@ -139,7 +139,7 @@ public: case DbgType_u32: return (int64) mUInt32; case DbgType_u64: - return (int64) mUInt64; + return (int64) mUInt64; case DbgType_Ptr: return (int64) mUInt64; default: @@ -265,7 +265,7 @@ public: SizedArray mBestMethodGenericArgumentSrcs; DwTypeVector mBestMethodGenericArguments; -public: +public: void CompareMethods(DbgSubprogram* prevMethodInstance, DwTypeVector* prevGenericArgumentsSubstitute, DbgSubprogram* newMethodInstance, DwTypeVector* genericArgumentsSubstitute, bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail); @@ -332,13 +332,13 @@ public: }; public: - DebugTarget* mDebugTarget; + DebugTarget* mDebugTarget; DbgModule* mOrigDbgModule; DbgModule* mDbgModule; - DbgCompileUnit* mDbgCompileUnit; + DbgCompileUnit* mDbgCompileUnit; DbgLanguage mLanguage; - BfPassInstance* mPassInstance; + BfPassInstance* mPassInstance; WinDebugger* mDebugger; String mExpectingTypeName; String mSubjectExpr; @@ -348,9 +348,9 @@ public: DbgTypedValue mResult; DbgTypedValue* mReceivingValue; intptr mCountResultOverride; - DbgTypedValue mExplicitThis; + DbgTypedValue mExplicitThis; BfExpression* mExplicitThisExpr; - Array* mCallResults; + Array* mCallResults; addr_target mCallStackPreservePos; int mCallResultIdx; String mNamespaceSearchStr; @@ -367,12 +367,12 @@ public: bool mIsEmptyTarget; DwEvalExpressionFlags mExpressionFlags; bool mHadSideEffects; - bool mBlockedSideEffects; + bool mBlockedSideEffects; bool mIgnoreErrors; bool mCreatedPendingCall; - bool mValidateOnly; + bool mValidateOnly; int mCallStackIdx; - int mCursorPos; + int mCursorPos; DwAutoComplete* mAutoComplete; DbgStackSearch* mStackSearch; @@ -388,18 +388,18 @@ public: DbgTypedValue ReadTypedValue(BfAstNode* targetSrc, DbgType* type, uint64 valAddr, DbgAddrType addrType); bool CheckTupleCreation(addr_target receiveAddr, BfAstNode* targetSrc, DbgType* tupleType, const BfSizedArray& argValues, BfSizedArray* names); DbgTypedValue CheckEnumCreation(BfAstNode* targetSrc, DbgType* enumType, const StringImpl& caseName, const BfSizedArray& argValues); - void DoInvocation(BfAstNode* target, BfSizedArray& args, BfSizedArray* methodGenericArguments); - bool ResolveArgValues(const BfSizedArray& arguments, SizedArrayImpl& outArgValues); + void DoInvocation(BfAstNode* target, BfSizedArray& args, BfSizedArray* methodGenericArguments, bool& failed); + bool ResolveArgValues(const BfSizedArray& arguments, SizedArrayImpl& outArgValues); DbgTypedValue CreateCall(DbgSubprogram* method, DbgTypedValue thisVal, DbgTypedValue structRetVal, bool bypassVirtual, CPURegisters* registers); DbgTypedValue CreateCall(DbgSubprogram* method, SizedArrayImpl& argPushQueue, bool bypassVirtual); DbgTypedValue CreateCall(BfAstNode* targetSrc, DbgTypedValue target, DbgSubprogram* methodDef, bool bypassVirtual, const BfSizedArray& arguments, SizedArrayImpl& argValues); DbgTypedValue MatchMethod(BfAstNode* targetSrc, DbgTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName, - const BfSizedArray& arguments, BfSizedArray* methodGenericArguments); + const BfSizedArray& arguments, BfSizedArray* methodGenericArguments, bool& failed); DbgType* ResolveSubTypeRef(DbgType* checkType, const StringImpl& name); void PerformBinaryOperation(ASTREF(BfExpression*)& leftExpression, ASTREF(BfExpression*)& rightExpression, BfBinaryOp binaryOp, BfTokenNode* opToken, bool forceLeftType); void PerformBinaryOperation(DbgType* resultType, DbgTypedValue convLeftValue, DbgTypedValue convRightValue, BfBinaryOp binaryOp, BfTokenNode* opToken); void PerformUnaryExpression(BfAstNode* opToken, BfUnaryOp unaryOp, ASTREF(BfExpression*)& expr); - DbgTypedValue CreateValueFromExpression(ASTREF(BfExpression*)& expr, DbgType* castToType = NULL, DbgEvalExprFlags flags = DbgEvalExprFlags_None); + DbgTypedValue CreateValueFromExpression(ASTREF(BfExpression*)& expr, DbgType* castToType = NULL, DbgEvalExprFlags flags = DbgEvalExprFlags_None); const char* GetTypeName(DbgType* type); DbgTypedValue GetResult(); bool HasPropResult(); @@ -409,11 +409,11 @@ public: public: DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModule, BfPassInstance* passInstance, int callStackIdx, int cursorPos); ~DbgExprEvaluator(); - + DbgTypedValue GetInt(int value); DbgTypedValue GetString(const StringImpl& str); - void Fail(const StringImpl& error, BfAstNode* node); + void Fail(const StringImpl& error, BfAstNode* node); void Warn(const StringImpl& error, BfAstNode* node); DbgType* GetExpectingType(); void GetNamespaceSearch(); @@ -422,11 +422,11 @@ public: DbgType* ResolveTypeRef(BfTypeReference* typeRef); DbgType* ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parentChildRef = NULL); DbgType* ResolveTypeRef(const StringImpl& typeRef); - static bool TypeIsSubTypeOf(DbgType* srcType, DbgType* wantType, int* thisOffset = NULL, addr_target* thisAddr = NULL); + static bool TypeIsSubTypeOf(DbgType* srcType, DbgType* wantType, int* thisOffset = NULL, addr_target* thisAddr = NULL); DbgTypedValue GetBeefTypeById(int typeId); void BeefStringToString(addr_target addr, String& outStr); void BeefStringToString(const DbgTypedValue& val, String& outStr); - void BeefTypeToString(const DbgTypedValue& val, String& outStr); + void BeefTypeToString(const DbgTypedValue& val, String& outStr); CPUStackFrame* GetStackFrame(); CPURegisters* GetRegisters(); DbgTypedValue GetRegister(const StringImpl& regName); @@ -438,9 +438,9 @@ public: void AutocompleteCheckType(BfTypeReference* typeReference); void AutocompleteAddTopLevelTypes(const StringImpl& filter); void AutocompleteAddMethod(const char* methodName, const StringImpl& filter); - void AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic, bool wantsNonStatic, const StringImpl& filter, bool isCapture = false); + void AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic, bool wantsNonStatic, const StringImpl& filter, bool isCapture = false); void AutocompleteCheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName); - DbgTypedValue RemoveRef(DbgTypedValue typedValue); + DbgTypedValue RemoveRef(DbgTypedValue typedValue); bool StoreValue(DbgTypedValue& ptr, DbgTypedValue& value, BfAstNode* refNode); bool StoreValue(DbgTypedValue& ptr, BfExpression* expr); @@ -449,16 +449,16 @@ public: bool CanCast(DbgTypedValue typedVal, DbgType* toType, BfCastFlags castFlags = BfCastFlags_None); DbgTypedValue Cast(BfAstNode* srcNode, const DbgTypedValue& val, DbgType* toType, bool explicitCast = false, bool silentFail = false); bool HasField(DbgType* type, const StringImpl& fieldName); - DbgTypedValue DoLookupField(BfAstNode* targetSrc, DbgTypedValue target, DbgType* curCheckType, const StringImpl& fieldName, CPUStackFrame* stackFrame, bool allowImplicitThis); - DbgTypedValue LookupField(BfAstNode* targetSrc, DbgTypedValue target, const StringImpl& fieldName); + DbgTypedValue DoLookupField(BfAstNode* targetSrc, DbgTypedValue target, DbgType* curCheckType, const StringImpl& fieldName, CPUStackFrame* stackFrame, bool allowImplicitThis); + DbgTypedValue LookupField(BfAstNode* targetSrc, DbgTypedValue target, const StringImpl& fieldName); DbgTypedValue DoLookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError); DbgTypedValue LookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL); void LookupSplatMember(const DbgTypedValue& target, const StringImpl& fieldName); void LookupSplatMember(BfAstNode* srcNode, BfAstNode* lookupNode, const DbgTypedValue& target, const StringImpl& fieldName, String* outFindName = NULL, bool* outIsConst = NULL, StringImpl* forceName = NULL); void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL); DbgType* FindSubtype(DbgType* type, const StringImpl& name); - void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError = false); - bool EnsureRunning(BfAstNode* astNode); + void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError = false); + bool EnsureRunning(BfAstNode* astNode); virtual void Visit(BfAssignmentExpression* assignExpr) override; virtual void Visit(BfParenthesizedExpression* parenExpr) override; @@ -477,10 +477,10 @@ public: virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override; virtual void Visit(BfInvocationExpression* invocationExpr) override; virtual void Visit(BfConditionalExpression* condExpr) override; - virtual void Visit(BfTypeAttrExpression* typeAttrExpr) override; + virtual void Visit(BfTypeAttrExpression* typeAttrExpr) override; virtual void Visit(BfTupleExpression* tupleExpr) override; - DbgTypedValue Resolve(BfExpression* expr, DbgType* wantType = NULL); + DbgTypedValue Resolve(BfExpression* expr, DbgType* wantType = NULL); BfAstNode* FinalizeExplicitThisReferences(BfAstNode* headNode); }; diff --git a/IDEHelper/DbgMiniDump.cpp b/IDEHelper/DbgMiniDump.cpp index 8a0a9d31..49c5b24b 100644 --- a/IDEHelper/DbgMiniDump.cpp +++ b/IDEHelper/DbgMiniDump.cpp @@ -3,7 +3,7 @@ USING_NS_BF; -enum DbgMiniDumpFlags +enum DbgMiniDumpFlags { DbgMiniDumpFlag_MiniDumpNormal = 0x00000000, DbgMiniDumpFlag_MiniDumpWithDataSegs = 0x00000001, @@ -41,18 +41,18 @@ bool DbgMiniDump::StartLoad(const StringImpl& path) uint32 mVersion; uint32 mNumberOfStreams; uint32 mStreamDirectoryRVA; - uint32 mCheckSum; - uint32 TimeDateStamp; + uint32 mCheckSum; + uint32 TimeDateStamp; uint64 Flags; }; - _Header& header = *(_Header*)((uint8*)mMF.mData); + _Header& header = *(_Header*)((uint8*)mMF.mData); if (header.mSignature != 'PMDM') return false; - + mDirectory.mVals = (StreamDirectoryEntry*)((uint8*)mMF.mData + header.mStreamDirectoryRVA); mDirectory.mSize = header.mNumberOfStreams; - + return true; } @@ -72,4 +72,4 @@ int DbgMiniDump::GetTargetBitCount() } return 0; -} +} \ No newline at end of file diff --git a/IDEHelper/DbgMiniDump.h b/IDEHelper/DbgMiniDump.h index 3534e0ec..070272f2 100644 --- a/IDEHelper/DbgMiniDump.h +++ b/IDEHelper/DbgMiniDump.h @@ -46,7 +46,7 @@ public: bool StartLoad(const StringImpl& path); int GetTargetBitCount(); - template + template T& GetStreamData(const StreamDirectoryEntry& entry) { return *(T*)((uint8*)mMF.mData + entry.mDataRVA); diff --git a/IDEHelper/DbgModule.cpp b/IDEHelper/DbgModule.cpp index 29ffb0ae..7898d073 100644 --- a/IDEHelper/DbgModule.cpp +++ b/IDEHelper/DbgModule.cpp @@ -95,7 +95,7 @@ DbgSubprogram* DbgSubprogram::GetLineInlinee(const DbgLineData& lineData) DbgSrcFile* DbgSubprogram::GetLineSrcFile(const DbgLineData& lineData) { - auto inlineRoot = GetRootInlineParent(); + auto inlineRoot = GetRootInlineParent(); return inlineRoot->mLineInfo->mContexts[lineData.mCtxIdx].mSrcFile; } @@ -132,19 +132,19 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l addr_target address = (addr_target)(lineData.mRelAddress + mDbgModule->mImageBase); if ((compileUnit->mLowPC != (addr_target)-1) && ((address < (addr_target)compileUnit->mLowPC) || (address >= (addr_target)compileUnit->mHighPC))) return NULL; - + if ((mCurSubprogram == NULL) || (address < mCurSubprogram->mBlock.mLowPC) || (address >= mCurSubprogram->mBlock.mHighPC)) { DbgSubprogramMapEntry* mapEntry = mDbgModule->mDebugTarget->mSubprogramMap.Get(address, DBG_MAX_LOOKBACK); if (mapEntry != NULL) { mCurSubprogram = mapEntry->mEntry; - + if (address > mCurSubprogram->mBlock.mHighPC) mCurSubprogram = NULL; if (mCurSubprogram != NULL) - { + { SubprogramRecord** recordPtr = NULL; if (mRecords.TryAdd(mCurSubprogram, NULL, &recordPtr)) { @@ -154,7 +154,7 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l *recordPtr = mCurRecord; mCurRecord->mContexts.mAlloc = &mAlloc; mCurRecord->mContexts.Reserve(16); - mCurRecord->mLines.mAlloc = &mAlloc; + mCurRecord->mLines.mAlloc = &mAlloc; mCurRecord->mLines.Reserve(128); mCurRecord->mCurContext = -1; mCurRecord->mHasInlinees = false; @@ -169,7 +169,7 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l if (mCurSubprogram == NULL) return NULL; - + bool needsNewCtx = false; if (mCurRecord->mCurContext == -1) { @@ -181,7 +181,7 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l if ((curContext.mInlinee != inlinee) || (curContext.mSrcFile != srcFile)) { needsNewCtx = true; - for (int ctxIdx = 0; ctxIdx < (int)mCurRecord->mContexts.size(); ctxIdx++) + for (int ctxIdx = 0; ctxIdx < (int)mCurRecord->mContexts.size(); ctxIdx++) { auto& ctx = mCurRecord->mContexts[ctxIdx]; if ((ctx.mInlinee == inlinee) && (ctx.mSrcFile == srcFile)) @@ -193,15 +193,15 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l } } } - + if (needsNewCtx) - { + { DbgLineInfoCtx ctx; ctx.mInlinee = inlinee; ctx.mSrcFile = srcFile; if (inlinee != NULL) mCurRecord->mHasInlinees = true; - mCurRecord->mContexts.Add(ctx); + mCurRecord->mContexts.Add(ctx); mCurRecord->mCurContext = (int)mCurRecord->mContexts.size() - 1; } @@ -209,7 +209,7 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l if ((mCurSubprogram->mPrologueSize > 0) && (mCurRecord->mLines.size() == 1) && (inlinee == NULL)) { - auto& firstLine = mCurRecord->mLines[0]; + auto& firstLine = mCurRecord->mLines[0]; auto dbgStartAddr = firstLine.mRelAddress + mCurSubprogram->mPrologueSize; if (lineData.mRelAddress != dbgStartAddr) { @@ -225,7 +225,7 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l { if (inlinee->mInlineeInfo->mFirstLineData.mRelAddress == 0) inlinee->mInlineeInfo->mFirstLineData = lineData; - inlinee->mInlineeInfo->mLastLineData = lineData; + inlinee->mInlineeInfo->mLastLineData = lineData; } mCurRecord->mLines.Add(lineData); @@ -235,9 +235,9 @@ DbgLineData* DbgLineDataBuilder::Add(DbgCompileUnit* compileUnit, DbgLineData& l void DbgLineDataBuilder::Commit() { HashSet usedSrcFiles; - + for (auto& recordKV : mRecords) - { + { auto dbgSubprogram = recordKV.mKey; auto record = recordKV.mValue; @@ -249,8 +249,8 @@ void DbgLineDataBuilder::Commit() ctx.mSrcFile->mLineDataRefs.Add(dbgSubprogram); } } - - for (int lineIdx = 0; lineIdx < (int)record->mLines.size() - 1; lineIdx++) + + for (int lineIdx = 0; lineIdx < (int)record->mLines.size() - 1; lineIdx++) { auto& lineData = record->mLines[lineIdx]; auto& nextLineData = record->mLines[lineIdx + 1]; @@ -267,7 +267,7 @@ void DbgLineDataBuilder::Commit() auto nextCtx = record->mContexts[lineData.mCtxIdx]; sameInliner = ctx.mInlinee == nextCtx.mInlinee; } - if ((sameInliner) && (lineData.mRelAddress + lineData.mContribSize < nextLineData.mRelAddress)) + if ((sameInliner) && (lineData.mRelAddress + lineData.mContribSize < nextLineData.mRelAddress)) { auto ctx = record->mContexts[lineData.mCtxIdx]; if (ctx.mInlinee != NULL) @@ -276,7 +276,7 @@ void DbgLineDataBuilder::Commit() } DbgLineData* lastLine = NULL; - for (int lineIdx = 0; lineIdx < (int)record->mLines.size(); lineIdx++) + for (int lineIdx = 0; lineIdx < (int)record->mLines.size(); lineIdx++) { auto& lineData = record->mLines[lineIdx]; if (lineData.mContribSize == 0) @@ -297,7 +297,7 @@ void DbgLineDataBuilder::Commit() contexts.CopyFrom(&record->mContexts[0], (int)record->mContexts.size(), mDbgModule->mAlloc); dbgSubprogram->mLineInfo->mContexts = contexts.mVals; - dbgSubprogram->mLineInfo->mHasInlinees = record->mHasInlinees; + dbgSubprogram->mLineInfo->mHasInlinees = record->mHasInlinees; } } @@ -317,18 +317,18 @@ struct AbstractOriginEntry public: int mClassType; DbgDebugData* mDestination; - DbgDebugData* mAbstractOrigin; + DbgDebugData* mAbstractOrigin; private: AbstractOriginEntry() - { + { } public: static AbstractOriginEntry Create(int classType, DbgDebugData* destination, DbgDebugData* abstractOrigin) { AbstractOriginEntry abstractOriginEntry; - abstractOriginEntry.mClassType = classType; + abstractOriginEntry.mClassType = classType; abstractOriginEntry.mDestination = destination; abstractOriginEntry.mAbstractOrigin = abstractOrigin; return abstractOriginEntry; @@ -351,7 +351,7 @@ public: { destSubprogram->mFrameBaseData = originSubprogram->mFrameBaseData; destSubprogram->mFrameBaseLen = originSubprogram->mFrameBaseLen; - } + } destSubprogram->mReturnType = originSubprogram->mReturnType; auto originItr = originSubprogram->mParams.begin(); @@ -363,8 +363,8 @@ public: if (destParam->mName == NULL) destParam->mName = originParam->mName; if (destParam->mType == NULL) - destParam->mType = originParam->mType; - } + destParam->mType = originParam->mType; + } ++originItr; } //BF_ASSERT(originItr == originSubprogram->mParams.end()); @@ -376,7 +376,7 @@ public: if (destVariable->mName == NULL) destVariable->mName = originVariable->mName; if (destVariable->mType == NULL) - destVariable->mType = originVariable->mType; + destVariable->mType = originVariable->mType; } else { @@ -395,7 +395,7 @@ void DbgSubprogram::ToString(StringImpl& str, bool internalName) mCompileUnit->mDbgModule->FixupInlinee(this); PopulateSubprogram(); - + if (mCheckedKind == BfCheckedKind_Checked) str += "[Checked] "; else if (mCheckedKind == BfCheckedKind_Unchecked) @@ -403,14 +403,14 @@ void DbgSubprogram::ToString(StringImpl& str, bool internalName) auto language = GetLanguage(); if (mName == NULL) - { + { if (mLinkName[0] == '<') { str += mLinkName; return; } str = BfDemangler::Demangle(StringImpl::MakeRef(mLinkName), language); - // Strip off the params since we need to generate those ourselves + // Strip off the params since we need to generate those ourselves int parenPos = (int)str.IndexOf('('); if (parenPos != -1) str = str.Substring(0, parenPos); @@ -469,7 +469,7 @@ void DbgSubprogram::ToString(StringImpl& str, bool internalName) str += "."; else str += "::"; - } + } } const char* name = mName; @@ -480,11 +480,11 @@ void DbgSubprogram::ToString(StringImpl& str, bool internalName) { char c = *cPtr; if (c == 0) - break; + break; if ((c == ':') && (cPtr[1] == ':')) { name = cPtr + 2; - } + } } } @@ -564,7 +564,7 @@ void DbgSubprogram::ToString(StringImpl& str, bool internalName) showedParam = true; i++; } - str += ")"; + str += ")"; } String DbgSubprogram::ToString() @@ -575,22 +575,22 @@ String DbgSubprogram::ToString() } // For inlined subprograms, the "root" inliner means the bottom-most non-inlined function. This subprogram contains -// all the line data for it's own non-inlined instructions, PLUS line data for all inlined functions that it calls. +// all the line data for it's own non-inlined instructions, PLUS line data for all inlined functions that it calls. // The inlined functions has empty mLineInfo structures. -// +// // When we pass a non-NULL value into inlinedSubprogram, we are requesting to ONLY return lines that were emitted from -// that subprogram (inlined or not). +// that subprogram (inlined or not). // // If we call FindClosestLine on an inlined subprogram, we only want results of functions that are inside or inlined by // the 'this' subprogram. Thus, we do a "get any line" call on the root inliner and then filter the results based // on whether they are relevant. DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram, DbgSrcFile** srcFile, int* outLineIdx) -{ +{ if (mLineInfo == NULL) { if (mInlineeInfo == NULL) return NULL; - + if ((inlinedSubprogram != NULL) && (*inlinedSubprogram != NULL)) { // Keep explicit inlinee requirement @@ -619,7 +619,7 @@ DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** in } return NULL; - } + } } // Binary search - lineData is sorted @@ -637,7 +637,7 @@ DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** in else if (midAddr == addr) { useIdx = middle; - break; + break; } else last = middle - 1; @@ -650,7 +650,7 @@ DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** in if (last == -1) return NULL; - + // If we have lines with the same addr, take the more inner one while (true) { @@ -679,7 +679,7 @@ DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** in *srcFile = ctx.mSrcFile; if (inlinedSubprogram != NULL) - { + { auto subprogram = (ctx.mInlinee != NULL) ? ctx.mInlinee : this; if (*inlinedSubprogram != NULL) { @@ -716,7 +716,7 @@ DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** in } DbgType* DbgSubprogram::GetParent() -{ +{ if ((mParentType == NULL) && (mCompileUnit != NULL)) mCompileUnit->mDbgModule->MapCompileUnitMethods(mCompileUnit); return mParentType; @@ -725,7 +725,7 @@ DbgType* DbgSubprogram::GetParent() DbgType* DbgSubprogram::GetTargetType() { if (!mHasThis) - return mParentType; + return mParentType; auto thisType = mParams.mHead->mType; if (thisType == NULL) return mParentType; @@ -735,7 +735,7 @@ DbgType* DbgSubprogram::GetTargetType() } DbgLanguage DbgSubprogram::GetLanguage() -{ +{ if (mParentType != NULL) return mParentType->GetLanguage(); if (mCompileUnit->mLanguage != DbgLanguage_Unknown) @@ -749,7 +749,7 @@ bool DbgSubprogram::Equals(DbgSubprogram* checkMethod, bool allowThisMismatch) { return strcmp(mLinkName, checkMethod->mLinkName) == 0; } - + if (strcmp(mName, checkMethod->mName) != 0) return false; @@ -822,7 +822,7 @@ bool DbgSubprogram::IsGenericMethod() bool DbgSubprogram::ThisIsSplat() { if (mBlock.mVariables.mHead == NULL) - return false; + return false; return strncmp(mBlock.mVariables.mHead->mName, "$this$", 6) == 0; } @@ -854,8 +854,8 @@ bool DbgSrcFile::IsBeef() DbgSrcFile::~DbgSrcFile() { - for (auto replacedLineInfo : mHotReplacedDbgLineInfo) - delete replacedLineInfo; + for (auto replacedLineInfo : mHotReplacedDbgLineInfo) + delete replacedLineInfo; } void DbgSrcFile::RemoveDeferredRefs(DbgModule* debugModule) @@ -863,17 +863,16 @@ void DbgSrcFile::RemoveDeferredRefs(DbgModule* debugModule) for (int deferredIdx = 0; deferredIdx < (int)mDeferredRefs.size(); ) { if (mDeferredRefs[deferredIdx].mDbgModule == debugModule) - { + { // Fast remove mDeferredRefs[deferredIdx] = mDeferredRefs.back(); - mDeferredRefs.pop_back(); + mDeferredRefs.pop_back(); } else deferredIdx++; } } - void DbgSrcFile::RemoveLines(DbgModule* debugModule) { if (!mHasLineDataFromMultipleModules) @@ -896,7 +895,7 @@ void DbgSrcFile::RemoveLines(DbgModule* debugModule) } void DbgSrcFile::RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced) -{ +{ debugModule->mDebugTarget->mPendingSrcFileRehup.Add(this); if (isHotReplaced) @@ -955,16 +954,16 @@ void DbgSrcFile::GetHash(String& outStr) DbgType::DbgType() { - mTypeIdx = -1; - mIsDeclaration = false; - mParent = NULL; + mTypeIdx = -1; + mIsDeclaration = false; + mParent = NULL; mTypeName = NULL; mTypeCode = DbgType_Null; - mSize = 0; + mSize = 0; mPtrType = NULL; mTypeParam = NULL; mBlockParam = NULL; - mNext = NULL; + mNext = NULL; mPriority = DbgTypePriority_Normal; } @@ -1009,7 +1008,7 @@ bool DbgType::Equals(DbgType* dbgType) } if ((mTypeParam != NULL) && (!mTypeParam->Equals(dbgType->mTypeParam))) return false; - + // Did mName already include the parent name? if (mCompileUnit->mDbgModule->mDbgFlavor == DbgFlavor_MS) return true; @@ -1027,7 +1026,7 @@ bool DbgType::IsStruct() } bool DbgType::IsPrimitiveType() -{ +{ return (mTypeCode >= DbgType_i8) && (mTypeCode <= DbgType_Bool); } @@ -1056,7 +1055,7 @@ bool DbgType::IsTypedPrimitive() PopulateType(); if (mTypeCode != DbgType_Struct) - return false; + return false; if (mTypeParam != NULL) return true; @@ -1067,7 +1066,7 @@ bool DbgType::IsTypedPrimitive() if (!baseType->IsTypedPrimitive()) return false; - + mTypeParam = baseType->mTypeParam; return true; } @@ -1130,7 +1129,7 @@ DbgExtType DbgType::CalcExtType() auto language = GetLanguage(); if ((!mFixedName) && (language == DbgLanguage_Beef)) { - FixName(); + FixName(); } auto primaryType = GetPrimaryType(); @@ -1173,7 +1172,7 @@ DbgExtType DbgType::CalcExtType() { for (auto member : mMemberList) { - if (strcmp(member->mName, "__bftag") == 0) + if ((member->mName != NULL) && (strcmp(member->mName, "__bftag") == 0)) return DbgExtType_BfPayloadEnum; } return DbgExtType_Normal; @@ -1182,7 +1181,7 @@ DbgExtType DbgType::CalcExtType() { for (auto member : mMemberList) { - if (strcmp(member->mName, "$bfunion") == 0) + if ((member->mName != NULL) && (strcmp(member->mName, "$bfunion") == 0)) return DbgExtType_BfUnion; } } @@ -1195,7 +1194,7 @@ DbgExtType DbgType::CalcExtType() } DbgLanguage DbgType::GetLanguage() -{ +{ return mLanguage; } @@ -1203,7 +1202,7 @@ void DbgType::FixName() { if (mFixedName) return; - + int depthCount = 0; auto dbgModule = mCompileUnit->mDbgModule; @@ -1260,14 +1259,14 @@ void DbgType::FixName() } bool DbgType::IsBfObject() -{ +{ if (mExtType == DbgExtType_Unknown) mExtType = CalcExtType(); return (mExtType == DbgExtType_BfObject) || (mExtType == DbgExtType_Interface); } bool DbgType::IsBfPayloadEnum() -{ +{ if (mExtType == DbgExtType_Unknown) mExtType = CalcExtType(); return mExtType == DbgExtType_BfPayloadEnum; @@ -1326,7 +1325,7 @@ bool DbgType::HasCPPVTable() }*/ if (mHasVTable) return true; - + if (GetLanguage() == DbgLanguage_Beef) return false; @@ -1368,7 +1367,7 @@ bool DbgType::IsRoot() bool DbgType::IsRef() { - return + return (mTypeCode == DbgType_Ref) || (mTypeCode == DbgType_RValueReference); } @@ -1449,46 +1448,46 @@ void DbgType::PopulateType() DbgModule* DbgType::GetDbgModule() { if (mCompileUnit == NULL) - return NULL; + return NULL; return mCompileUnit->mDbgModule; } DbgType* DbgType::GetPrimaryType() -{ +{ if (mPrimaryType != NULL) return mPrimaryType; mPrimaryType = this; if (mPriority <= DbgTypePriority_Normal) - { - if ((mCompileUnit != NULL) && - ((mCompileUnit->mLanguage == DbgLanguage_Beef)|| (mLanguage == DbgLanguage_Beef) || + { + if ((mCompileUnit != NULL) && + ((mCompileUnit->mLanguage == DbgLanguage_Beef)|| (mLanguage == DbgLanguage_Beef) || (mTypeCode == DbgType_Namespace) || (mIsDeclaration))) - { - mPrimaryType = mCompileUnit->mDbgModule->GetPrimaryType(this); + { + mPrimaryType = mCompileUnit->mDbgModule->GetPrimaryType(this); mPrimaryType->PopulateType(); mTypeCode = mPrimaryType->mTypeCode; mTypeParam = mPrimaryType->mTypeParam; } } - + return mPrimaryType; } DbgType* DbgType::GetBaseType() { auto primaryType = GetPrimaryType(); - if (primaryType != this) + if (primaryType != this) return primaryType->GetBaseType(); PopulateType(); if (mBaseTypes.mHead == NULL) - return NULL; + return NULL; if (GetLanguage() != DbgLanguage_Beef) return NULL; auto baseType = mBaseTypes.mHead->mBaseType; BF_ASSERT(!baseType->IsInterface()); - + if ((baseType == NULL) || (baseType->mPriority > DbgTypePriority_Normal)) return baseType; baseType = mCompileUnit->mDbgModule->GetPrimaryType(baseType); @@ -1504,7 +1503,7 @@ DbgType* DbgType::GetBaseType() if (baseType->ToString() == "System.Function") { DbgBaseTypeEntry* baseTypeEntry = mCompileUnit->mDbgModule->mAlloc.Alloc(); - baseTypeEntry->mBaseType = mCompileUnit->mDbgModule->GetPrimitiveType(DbgType_IntPtr_Alias, DbgLanguage_Beef); + baseTypeEntry->mBaseType = mCompileUnit->mDbgModule->GetPrimitiveType(DbgType_IntPtr_Alias, DbgLanguage_Beef); baseType->mBaseTypes.PushBack(baseTypeEntry); } } @@ -1526,7 +1525,7 @@ DbgType* DbgType::RemoveModifiers(bool* hadRef) { DbgType* dbgType = this; while (dbgType != NULL) - { + { bool curHadRef = (dbgType->mTypeCode == DbgType_Ref) || (dbgType->mTypeCode == DbgType_RValueReference); if ((curHadRef) && (hadRef != NULL)) *hadRef = true; @@ -1547,12 +1546,12 @@ DbgType* DbgType::RemoveModifiers(bool* hadRef) String DbgType::ToStringRaw(DbgLanguage language) { if (mTypeIdx != -1) - return StrFormat("_T_%d_%d", mCompileUnit->mDbgModule->GetLinkedModule()->mId, mTypeIdx); + return StrFormat("_T_%d_%d", mCompileUnit->mDbgModule->GetLinkedModule()->mId, mTypeIdx); return ToString(language); } void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName) -{ +{ if (language == DbgLanguage_Unknown) language = GetLanguage(); @@ -1673,7 +1672,7 @@ void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBf } return; } - + //String combName; /*if (mTemplateParams != NULL) { @@ -1685,7 +1684,7 @@ void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBf if ((!mFixedName) /*&& (language == DbgLanguage_Beef)*/) { FixName(); - } + } char* nameP = (char*)mTypeName; if (parent == NULL) @@ -1708,20 +1707,20 @@ void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBf if ((internalName) && (parent->mTypeCode != DbgType_Namespace)) str += "+"; else - str += "."; + str += "."; str += nameP; } else - { + { parent->ToString(str, language, allowDirectBfObject, internalName); if ((internalName) && (parent->mTypeCode != DbgType_Namespace)) str += "+"; else - str += "::"; + str += "::"; str += nameP; } return; - } + } switch (mTypeCode) { @@ -1900,7 +1899,7 @@ void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBf str += "void"; return; case DbgType_Subroutine: - { + { mTypeParam->ToString(str, language, allowDirectBfObject, internalName); str += " ("; int paramIdx = 0; @@ -1951,9 +1950,8 @@ String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject) return str; } - intptr DbgType::GetByteCount() -{ +{ if (!mSizeCalculated) { PopulateType(); @@ -1970,7 +1968,7 @@ intptr DbgType::GetByteCount() { mSize = primaryType->GetByteCount(); mAlign = primaryType->mAlign; - } + } } } else if ((mTypeCode == DbgType_Ref) || (mTypeCode == DbgType_Ptr) || (mTypeCode == DbgType_PtrToMember)) @@ -2019,7 +2017,7 @@ intptr DbgType::GetStride() } int DbgType::GetAlign() -{ +{ if (mAlign == 0) { auto primaryType = GetPrimaryType(); @@ -2033,8 +2031,8 @@ int DbgType::GetAlign() } if (mAlign != 0) - return mAlign; - return 1; + return mAlign; + return 1; } void DbgType::EnsureMethodsMapped() @@ -2086,7 +2084,7 @@ void DbgType::EnsureMethodsMapped() DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) { - mMemReporter = NULL; + mMemReporter = NULL; mLoadState = DbgModuleLoadState_NotLoaded; mMappedImageFile = NULL; @@ -2130,12 +2128,12 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) CREATE_PRIMITIVE(DbgType_SChar16, "wchar_t", "wchar", "System.Char16", wchar_t); CREATE_PRIMITIVE(DbgType_i8, "int8_t", "int8", "System.SByte", int8); CREATE_PRIMITIVE(DbgType_i16, "short", "int16", "System.Int16", int16); - CREATE_PRIMITIVE(DbgType_i32, "int", "int32", "System.Int32", int32); - CREATE_PRIMITIVE(DbgType_i64, "int64_t", "int64", "System.Int64", int64); + CREATE_PRIMITIVE(DbgType_i32, "int", "int32", "System.Int32", int32); + CREATE_PRIMITIVE(DbgType_i64, "int64_t", "int64", "System.Int64", int64); CREATE_PRIMITIVE(DbgType_u8, "uint8_t", "uint8", "System.UInt8", uint8); CREATE_PRIMITIVE(DbgType_u16, "uint16_t", "uint16", "System.UInt16", uint16); - CREATE_PRIMITIVE(DbgType_u32, "uint32_t", "uint32", "System.UInt32", uint32); + CREATE_PRIMITIVE(DbgType_u32, "uint32_t", "uint32", "System.UInt32", uint32); CREATE_PRIMITIVE(DbgType_u64, "uint64_t", "uint64", "System.UInt64", uint64); CREATE_PRIMITIVE(DbgType_Single, "float", "float", "System.Single", float); @@ -2150,7 +2148,7 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) CREATE_PRIMITIVE(DbgType_RawText, "@RawText", "@RawText", "@RawText", bool); CREATE_PRIMITIVE(DbgType_RegGroup, "@RegGroup", "@RegGroup", "@RegGroup", void*); - + CREATE_PRIMITIVE_C(DbgType_i16, "int16_t", int16_t); CREATE_PRIMITIVE_C(DbgType_i32, "int32_t", int32_t); CREATE_PRIMITIVE_C(DbgType_i64, "__int64", int64); @@ -2161,7 +2159,7 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) CREATE_PRIMITIVE_C(DbgType_u32, "unsigned int", uint32); CREATE_PRIMITIVE_C(DbgType_u32, "unsigned int32_t", uint32_t); CREATE_PRIMITIVE_C(DbgType_u32, "unsigned long", uint32); - CREATE_PRIMITIVE_C(DbgType_u64, "unsigned int64_t", uint64); + CREATE_PRIMITIVE_C(DbgType_u64, "unsigned int64_t", uint64); } mIsDwarf64 = false; @@ -2173,15 +2171,15 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) mDebugLineData = NULL; mDebugInfoData = NULL; mDebugPubNames = NULL; - mDebugFrameAddress = 0; + mDebugFrameAddress = 0; mDebugFrameData = NULL; mDebugLocationData = NULL; mDebugRangesData = NULL; mDebugAbbrevData = NULL; - mDebugStrData = NULL; - mDebugAbbrevPtrData = NULL; + mDebugStrData = NULL; + mDebugAbbrevPtrData = NULL; mEHFrameData = NULL; - mEHFrameAddress = 0; + mEHFrameAddress = 0; mStringTable = NULL; mSymbolData = NULL; mCheckedBfObject = false; @@ -2192,17 +2190,17 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) mHotIdx = 0; mId = 0; mStartSubprogramIdx = 0; - mEndSubprogramIdx = 0; + mEndSubprogramIdx = 0; mCodeAddress = NULL; - mMayBeOld = false; + mMayBeOld = false; mTimeStamp = 0; mExpectedFileSize = 0; mBfTypeType = NULL; mBfTypesInfoAddr = 0; - + mImageBase = 0; mPreferredImageBase = 0; - mImageSize = 0; + mImageSize = 0; mOrigImageData = NULL; mDeleting = false; @@ -2224,14 +2222,14 @@ DbgModule::DbgModule(DebugTarget* debugTarget) : mDefaultCompileUnit(this) } DbgModule::~DbgModule() -{ +{ delete mMemReporter; for (auto dwSrcFile : mEmptySrcFiles) delete dwSrcFile; for (auto dwCompileUnit : mCompileUnits) - delete dwCompileUnit; - + delete dwCompileUnit; + delete mSymbolData; delete mStringTable; delete mDebugLineData; @@ -2242,11 +2240,11 @@ DbgModule::~DbgModule() delete mDebugRangesData; delete mDebugAbbrevData; delete mDebugAbbrevPtrData; - delete mDebugStrData; + delete mDebugStrData; for (auto entry : mExceptionDirectory) delete entry.mData; delete mEHFrameData; - + delete mOrigImageData; if ((IsObjectFile()) && (mImageBase != 0)) @@ -2263,7 +2261,7 @@ DbgSubprogram* DbgModule::FindSubprogram(DbgType* dbgType, const char * methodNa dbgType = dbgType->GetPrimaryType(); dbgType->PopulateType(); - if (dbgType->mNeedsGlobalsPopulated) + if (dbgType->mNeedsGlobalsPopulated) PopulateTypeGlobals(dbgType); for (auto methodNameEntry : dbgType->mMethodNameList) @@ -2306,7 +2304,7 @@ void DbgModule::Fail(const StringImpl& error) errorStr += mFilePath; errorStr += ": "; } - errorStr += error; + errorStr += error; errorStr += "\n"; mDebugger->OutputRawMessage(errorStr); @@ -2360,7 +2358,7 @@ char* DbgModule::DbgDupString(const char* str, const char* allocName) { int strLen = (int)strlen(str); if (strLen == 0) - return NULL; + return NULL; char* dupStr = (char*)mAlloc.AllocBytes(strLen + 1, (allocName != NULL) ? allocName : "DbgDupString"); memcpy(dupStr, str, strLen); return dupStr; @@ -2406,17 +2404,14 @@ void DbgModule::MapCompileUnitMethods(DbgCompileUnit * compileUnit) void DbgModule::MapCompileUnitMethods(int compileUnitId) { - } void DbgModule::PopulateType(DbgType* dbgType) { - } void DbgModule::PopulateTypeGlobals(DbgType* dbgType) { - } void DbgModule::PopulateStaticVariableMap() @@ -2425,8 +2420,8 @@ void DbgModule::PopulateStaticVariableMap() return; for (auto staticVariable : mStaticVariables) - { - mStaticVariableMap[staticVariable->GetMappedName()] = staticVariable; + { + mStaticVariableMap[staticVariable->GetMappedName()] = staticVariable; } mPopulatedStaticVariables = true; @@ -2444,7 +2439,7 @@ addr_target DbgModule::RemapAddr(addr_target addr) } void DbgModule::ParseAbbrevData(const uint8* data) -{ +{ while (true) { int abbrevIdx = (int)DecodeULEB128(data); @@ -2599,7 +2594,7 @@ T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8* else offset = GET(int32); if (extraData != NULL) - { + { *extraData = mDebugLocationData + offset; return 0; } @@ -2615,10 +2610,10 @@ T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8* { int64_t exprLen = DecodeULEB128(data); const uint8* endData = data + exprLen; - + if (extraData != NULL) *extraData = data; - + data = endData; return (T)exprLen; } @@ -2636,7 +2631,7 @@ T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8* } break; case DW_FORM_sdata: - return (T)DecodeSLEB128(data); + return (T)DecodeSLEB128(data); case DW_FORM_udata: return (T)DecodeULEB128(data); case DW_FORM_string: @@ -2648,17 +2643,17 @@ T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8* data++; if (val == 0) return (T)(intptr)str; - } + } } case DW_FORM_block: - { + { int blockLen = (int)DecodeULEB128(data); const uint8* retVal = data; data += blockLen; return (T)(intptr)retVal; } case DW_FORM_block1: - { + { int blockLen = (int)*((uint8*)data); data += sizeof(uint8); const uint8* retVal = data; @@ -2677,16 +2672,16 @@ T DbgModule::ReadValue(const uint8*& data, int form, int refOffset, const uint8* static int gAbbrevNum = 0; DbgType* DbgModule::GetOrCreateType(int typeIdx, DbgDataMap& dataMap) -{ +{ if (typeIdx == 0) return NULL; DbgModule* linkedModule = GetLinkedModule(); DbgType* dbgType = dataMap.Get(typeIdx); if (dbgType != NULL) return dbgType; - dbgType = mAlloc.Alloc(); - dbgType->mTypeIdx = (int)linkedModule->mTypes.size(); - linkedModule->mTypes.push_back(dbgType); + dbgType = mAlloc.Alloc(); + dbgType->mTypeIdx = (int)linkedModule->mTypes.size(); + linkedModule->mTypes.push_back(dbgType); dataMap.Set(typeIdx, dbgType); return dbgType; } @@ -2696,7 +2691,7 @@ typedef llvm::SmallVector DataStack; template T DbgModule::GetOrCreate(int idx, DbgDataMap& dataMap) -{ +{ if (idx == 0) return NULL; T val = dataMap.Get(idx); @@ -2707,7 +2702,6 @@ T DbgModule::GetOrCreate(int idx, DbgDataMap& dataMap) return val; } - template static T GetStackTop(DataStack* dataStack) { @@ -2724,9 +2718,9 @@ DbgBlock* GetStackTop(DataStack* dataStack) if (dataPair.first == DbgBlock::ClassType) return (DbgBlock*)dataPair.second; if (dataPair.first == DbgSubprogram::ClassType) - return &((DbgSubprogram*)dataPair.second)->mBlock; + return &((DbgSubprogram*)dataPair.second)->mBlock; if (dataPair.first == DbgType::ClassType) - return ((DbgType*)dataPair.second)->mBlockParam; + return ((DbgType*)dataPair.second)->mBlockParam; return NULL; } @@ -2743,7 +2737,7 @@ template static T GetStackLast(DataStack* dataStack) { for (int i = (int)dataStack->size() - 1; i >= 0; i--) - { + { if ((*dataStack)[i].first == RemoveTypePointer::type::ClassType) return (T)(*dataStack)[i].second; } @@ -2764,7 +2758,7 @@ void DbgModule::FixupInnerTypes(int startingTypeIdx) { DbgType* dbgType = mTypes[typeIdx]; - if ((dbgType->mPriority == DbgTypePriority_Primary_Implicit) && (dbgType->mParent != NULL) && (dbgType->mParent->mTypeCode != DbgType_Namespace) && + if ((dbgType->mPriority == DbgTypePriority_Primary_Implicit) && (dbgType->mParent != NULL) && (dbgType->mParent->mTypeCode != DbgType_Namespace) && (dbgType->mParent->mPriority <= DbgTypePriority_Primary_Implicit)) { auto primaryParent = dbgType->mParent->GetPrimaryType(); @@ -2779,16 +2773,16 @@ void DbgModule::FixupInnerTypes(int startingTypeIdx) void DbgModule::MapTypes(int startingTypeIdx) { BP_ZONE("DbgModule_MapTypes"); - - bool needsInnerFixups = false; + + bool needsInnerFixups = false; for (int typeIdx = startingTypeIdx; typeIdx < (int)mTypes.size(); typeIdx++) { DbgType* dbgType = mTypes[typeIdx]; BF_ASSERT(dbgType->mTypeCode != DbgType_Null); - + if ((dbgType->mTypeCode == DbgType_Namespace) && (dbgType->mPriority < DbgTypePriority_Primary_Implicit)) - continue; - + continue; + //TODO: Always valid? if (dbgType->mIsDeclaration) continue; @@ -2798,7 +2792,7 @@ void DbgModule::MapTypes(int startingTypeIdx) if ((dbgType->mTypeName == NULL) || (dbgType->mName == NULL) /*|| (dbgType->mTypeName[0] == '<')*/) continue; - if (dbgType->mTypeCode > DbgType_DefinitionEnd) + if (dbgType->mTypeCode > DbgType_DefinitionEnd) { // Only add "definition types" continue; @@ -2820,7 +2814,7 @@ void DbgModule::MapTypes(int startingTypeIdx) if ((member->mIsStatic) && (member->mLocationData != NULL)) dbgType->mDefinedMembersSize++; } - + if ((dbgType->mTypeName != NULL) && (strcmp(dbgType->mTypeName, "@") == 0)) { // Globals type. @@ -2860,7 +2854,7 @@ void DbgModule::MapTypes(int startingTypeIdx) prevTypeEntry->mValue = dbgType; } continue; - } + } // Don't replace a ptr to an BfObject with a BfObject if ((prevType->mTypeCode == DbgType_Ptr) && (dbgType->mTypeCode == DbgType_Struct)) @@ -2871,19 +2865,19 @@ void DbgModule::MapTypes(int startingTypeIdx) // Allow this to override prevTypeEntry->mValue = dbgType; continue; - } + } if (prevType->mTypeCode == DbgType_Namespace) - { + { if (dbgType->mTypeCode != DbgType_Namespace) { - // Old type was namespace but new isn't? Replace old type. + // Old type was namespace but new isn't? Replace old type. while (!prevType->mSubTypeList.IsEmpty()) { DbgType* subType = prevType->mSubTypeList.PopFront(); subType->mParent = dbgType; dbgType->mSubTypeList.PushBack(subType); - } + } prevType->mPriority = DbgTypePriority_Normal; if (dbgType->mPriority < DbgTypePriority_Primary_Implicit) dbgType->mPriority = DbgTypePriority_Primary_Implicit; @@ -2905,13 +2899,13 @@ void DbgModule::MapTypes(int startingTypeIdx) continue; if (!prevType->mIsDeclaration) - { + { if ((prevType->mCompileUnit == NULL) || (dbgType->mLanguage < prevType->mLanguage)) { // We always want 'Beef' types to supersede 'C' types, but don't override the built-in primitive types continue; } - + if (prevType->mDefinedMembersSize > 0) { if (dbgType->mDefinedMembersSize > 0) @@ -2973,8 +2967,8 @@ void DbgModule::CreateNamespaces() for (int typeIdx = 0; typeIdx < startLength; typeIdx++) { - DbgType* dbgType = mTypes[typeIdx]; - + DbgType* dbgType = mTypes[typeIdx]; + if (dbgType->mName == NULL) continue; @@ -3005,14 +2999,14 @@ void DbgModule::CreateNamespaces() mTypes.push_back(namespaceType); mTypeMap.Insert(namespaceType); - } + } else namespaceType = namespaceTypeEntry->mValue; - + while (!dbgType->mMemberList.IsEmpty()) - { + { DbgVariable* curVar = dbgType->mMemberList.PopFront(); - namespaceType->mMemberList.PushBack(curVar); + namespaceType->mMemberList.PushBack(curVar); } DbgType* prevType = NULL; @@ -3033,7 +3027,7 @@ void DbgModule::CreateNamespaces() continue; } - } + } // If we didn't have a parent type for a namespace (ie: if System.Collections wasn't linked to System) then we wait // until the end and move those from the global list to the parent list @@ -3042,7 +3036,7 @@ void DbgModule::CreateNamespaces() DbgType* dbgType = mTypes[typeIdx]; if (dbgType->mParent != NULL) continue; - + char* typeName = (char*)dbgType->mTypeName; int lastDotIdx = -1; for (int i = 0; true; i++) @@ -3063,7 +3057,7 @@ void DbgModule::CreateNamespaces() if (parentEntry == NULL) continue; - auto parentType = parentEntry->mValue; + auto parentType = parentEntry->mValue; dbgType->mCompileUnit->mGlobalType->mSubTypeList.Remove(dbgType); dbgType->mParent = parentType; parentType->mSubTypeList.PushBack(dbgType); @@ -3083,7 +3077,7 @@ void DbgModule::FindTemplateStr(const char*& name, int& templateNameIdx) } } templateNameIdx = -1; - } + } } void DbgModule::TempRemoveTemplateStr(const char*& name, int& templateNameIdx) @@ -3091,7 +3085,7 @@ void DbgModule::TempRemoveTemplateStr(const char*& name, int& templateNameIdx) if (templateNameIdx == 0) FindTemplateStr(name, templateNameIdx); if (templateNameIdx == -1) - return; + return; if (!DbgIsStrMutable(name)) name = DbgDupString(name); @@ -3106,7 +3100,7 @@ void DbgModule::ReplaceTemplateStr(const char*& name, int& templateNameIdx) } void DbgModule::MapSubprogram(DbgSubprogram* dbgSubprogram) -{ +{ if (dbgSubprogram->mBlock.IsEmpty()) return; @@ -3116,11 +3110,11 @@ void DbgModule::MapSubprogram(DbgSubprogram* dbgSubprogram) int curSize = progSize - progOffset; if (curSize <= 0) break; - + BP_ALLOC_T(DbgSubprogramMapEntry); DbgSubprogramMapEntry* subprogramMapEntry = mAlloc.Alloc(); subprogramMapEntry->mAddress = dbgSubprogram->mBlock.mLowPC + progOffset; - subprogramMapEntry->mEntry = dbgSubprogram; + subprogramMapEntry->mEntry = dbgSubprogram; mDebugTarget->mSubprogramMap.Insert(subprogramMapEntry); } } @@ -3134,7 +3128,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) int dataOfs = (int)(data - mDebugInfoData); intptr_target length = GET(int); - + DbgModule* linkedModule = GetLinkedModule(); if (length == -1) @@ -3158,20 +3152,20 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) mDbgFlavor = DbgFlavor_GNU; compileUnit->mDbgModule = this; mCompileUnits.push_back(compileUnit); - - DbgSubprogram* subProgram = NULL; - + + DbgSubprogram* subProgram = NULL; + //std::map typeMap; //std::map subprogramMap; int tagStart = (int)(data - startData); int tagEnd = (int)(dataEnd - startData); DbgDataMap dataMap(tagStart, tagEnd); - DataStack dataStack; + DataStack dataStack; Array abstractOriginReplaceList; - - Array deferredArrayDims; - int startingTypeIdx = (int)linkedModule->mTypes.size(); + Array deferredArrayDims; + + int startingTypeIdx = (int)linkedModule->mTypes.size(); while (data < dataEnd) { @@ -3179,29 +3173,29 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) const uint8* tagDataStart = data; int tagIdx = (int)(tagDataStart - startData); - + int abbrevIdx = (int)DecodeULEB128(data); const uint8* abbrevData = mDebugAbbrevPtrData[abbrevIdx]; - - if (abbrevIdx == 0) + + if (abbrevIdx == 0) { if (deferredArrayDims.size() > 0) - { + { DbgType* arrType = GetStackTop(&dataStack); BF_ASSERT(arrType->mTypeCode == DbgType_SizedArray); arrType->mSize = deferredArrayDims[0]; // Byte count still needs to be multiplied by the underlying type size - - DbgType* rootArrType = arrType; + + DbgType* rootArrType = arrType; for (int dimIdx = 0; dimIdx < (int)deferredArrayDims.size() - 1; dimIdx++) { int dimSize = deferredArrayDims[dimIdx]; - + DbgType* subArrType = mAlloc.Alloc(); subArrType->mCompileUnit = compileUnit; subArrType->mLanguage = compileUnit->mLanguage; subArrType->mTypeIdx = (int)linkedModule->mTypes.size(); linkedModule->mTypes.push_back(subArrType); - + subArrType->mTypeCode = DbgType_SizedArray; subArrType->mTypeParam = arrType->mTypeParam; subArrType->mSize = deferredArrayDims[dimIdx + 1]; @@ -3213,12 +3207,12 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) deferredArrayDims.Clear(); } - dataStack.pop_back(); + dataStack.pop_back(); continue; } - + int entryTag = (int) DecodeULEB128(abbrevData); - bool hasChildren = GET_FROM(abbrevData, char) == DW_CHILDREN_yes; + bool hasChildren = GET_FROM(abbrevData, char) == DW_CHILDREN_yes; int64 atLowPC = 0; int64 atHighPC = 0; @@ -3232,13 +3226,13 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) const char* atName = NULL; const char* atCompDir = NULL; const char* atLinkageName = NULL; - int64 atConstValue = 0; + int64 atConstValue = 0; int atDataMemberLocation = 0; const uint8* atDataMemberData = NULL; int atDeclFile = 0; int atDeclLine = 0; int atCallFile = 0; - int atCallLine = 0; + int atCallLine = 0; int atCount = 0; int atType = 0; int atImport = 0; @@ -3252,9 +3246,9 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) int atBitOffset = 0; int atBitSize = 0; int atAbstractOrigin = 0; - const uint8* atVirtualLocData = NULL; + const uint8* atVirtualLocData = NULL; bool atDeclaration = false; - bool atVirtual = false; + bool atVirtual = false; bool hadConstValue = false; bool hadMemberLocation = false; bool isOptimized = false; @@ -3277,7 +3271,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) atLocationLen = (int)ReadValue(data, form, dataOfs, &atLocationData, startData); break; case DW_AT_name: - atName = ReadValue(data, form); + atName = ReadValue(data, form); break; case DW_AT_ordering: /*TODO:*/ ReadValue(data, form); @@ -3344,7 +3338,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) /*TODO:*/ ReadValue(data, form); break; case DW_AT_producer: - atProducer = ReadValue(data, form); + atProducer = ReadValue(data, form); break; case DW_AT_prototyped: /*TODO:*/ ReadValue(data, form); @@ -3386,7 +3380,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) case DW_AT_data_member_location: if (form == DW_FORM_exprloc) { - atDataMemberLocation = (int)ReadValue(data, form, dataOfs, &atDataMemberData); + atDataMemberLocation = (int)ReadValue(data, form, dataOfs, &atDataMemberData); hadMemberLocation = true; } else @@ -3561,7 +3555,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) // case DW_AT_MIPS_linkage_name: - atLinkageName = ReadValue(data, form); + atLinkageName = ReadValue(data, form); break; case DW_AT_APPLE_optimized: @@ -3586,7 +3580,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (compileUnit->mLowPC != (addr_target)-1) { - // These are sometimes relative to the compile unit and sometimes absolute + // These are sometimes relative to the compile unit and sometimes absolute if (highPC + compileUnit->mLowPC <= compileUnit->mHighPC) { lowPC += compileUnit->mLowPC; @@ -3609,11 +3603,10 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (highPC > (addr_target)atHighPC) atHighPC = highPC;*/ } - } switch (entryTag) - { + { case DW_TAG_compile_unit: { newDataPair = MakeDataPair(compileUnit); @@ -3632,7 +3625,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) } else { - compileUnit->mLanguage = DbgLanguage_C; + compileUnit->mLanguage = DbgLanguage_C; } compileUnit->mGlobalType->mLanguage = compileUnit->mLanguage; } @@ -3640,23 +3633,23 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) case DW_TAG_imported_module: { DbgType* parentType = GetStackTop(&dataStack); - DbgType* importType = GetOrCreateType(atImport, dataMap); + DbgType* importType = GetOrCreateType(atImport, dataMap); if (parentType != NULL) // Parent type is NULL for Clang DbgModule info parentType->mUsingNamespaces.PushFront(importType, &mAlloc); } break; - case DW_TAG_inlined_subroutine: - case DW_TAG_subprogram: - { + case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: + { /*//TODO: This is a test. See if it breaks anything. if ((atExternal != 0) && (atLowPC == 0)) break;*/ if (atSpecification == 0) - { + { subProgram = GetOrCreate(tagIdx, dataMap); - subProgram->mCompileUnit = compileUnit; + subProgram->mCompileUnit = compileUnit; subProgram->mVirtual = atVirtual; subProgram->mIsOptimized = isOptimized; @@ -3670,19 +3663,19 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) } //subProgram->mVTableLoc = atVirtualLoc * sizeof(addr_target); - //SplitName(atName, subProgram->mName, subProgram->mTemplateName); + //SplitName(atName, subProgram->mName, subProgram->mTemplateName); subProgram->mName = atName; - subProgram->mLinkName = atLinkageName; + subProgram->mLinkName = atLinkageName; if (atAbstractOrigin != NULL) { - DbgSubprogram* originSubProgram = GetOrCreate(atAbstractOrigin, dataMap); - auto abstractOriginEntry = AbstractOriginEntry::Create(DbgSubprogram::ClassType, subProgram, originSubProgram); + DbgSubprogram* originSubProgram = GetOrCreate(atAbstractOrigin, dataMap); + auto abstractOriginEntry = AbstractOriginEntry::Create(DbgSubprogram::ClassType, subProgram, originSubProgram); abstractOriginReplaceList.push_back(abstractOriginEntry); } - subProgram->mParentType = GetStackTop(&dataStack); - newDataPair = MakeDataPair(subProgram); - + subProgram->mParentType = GetStackTop(&dataStack); + newDataPair = MakeDataPair(subProgram); + //if ((atLinkageName != NULL) && (subProgram->mParentType != NULL)) //subProgram->mParentType->mDefinedMembersCount++; @@ -3695,21 +3688,21 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) else { compileUnit->mGlobalType->mMethodList.PushBack(subProgram); - } + } } else { - subProgram = dataMap.Get(atSpecification); + subProgram = dataMap.Get(atSpecification); BF_ASSERT(subProgram != NULL); // We remove params form the declaration and re-add the real ones here subProgram->mParams.Clear(); - } - + } + newDataPair = MakeDataPair(subProgram); DbgBlock* dwBlock = &subProgram->mBlock; - + if (atType != 0) - subProgram->mReturnType = GetOrCreateType(atType, dataMap); + subProgram->mReturnType = GetOrCreateType(atType, dataMap); if (!atDeclaration) { @@ -3726,10 +3719,10 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) subProgram->mHasThis = true; subProgram->mFrameBaseLen = (int)atFrameBaseLength; subProgram->mFrameBaseData = atFrameBase; - + if (atHighPC > 0) { - MapSubprogram(subProgram); + MapSubprogram(subProgram); } } @@ -3738,11 +3731,11 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) DbgSubprogram* parentSubProgram = GetStackLast(&dataStack); subProgram->mInlineeInfo = mAlloc.Alloc(); subProgram->mInlineeInfo->mInlineParent = parentSubProgram; - subProgram->mInlineeInfo->mRootInliner = parentSubProgram->GetRootInlineParent(); + subProgram->mInlineeInfo->mRootInliner = parentSubProgram->GetRootInlineParent(); subProgram->mFrameBaseData = parentSubProgram->mFrameBaseData; subProgram->mFrameBaseLen = parentSubProgram->mFrameBaseLen; } - + //if (subProgram->mParentType != NULL) //subProgram->mParentType->mDefinedMembersCount++; } @@ -3761,12 +3754,12 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dwBlock->mLowPC = (addr_target)atLowPC; dwBlock->mHighPC = (addr_target)(atLowPC + atHighPC); } - newDataPair = MakeDataPair(dwBlock); + newDataPair = MakeDataPair(dwBlock); prevBlock->mSubBlocks.PushBack(dwBlock); } break; - case DW_TAG_variable: - { + case DW_TAG_variable: + { DbgBlock* dwBlock = GetStackTop(&dataStack); if (atName && !strncmp(atName, "__asmLines", 10)) @@ -3801,7 +3794,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) { s += *ptr; } - + //int asmLine = atoi(s.c_str()); //asmLines.push_back(asmLine); const char* sPtr = s.c_str(); @@ -3849,18 +3842,18 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) bool isNewVariable = true; DbgVariable* dbgVariable = NULL; if (atSpecification != 0) - { - //dbgVariable = dataMap.Get(atSpecification); + { + //dbgVariable = dataMap.Get(atSpecification); //BF_ASSERT(dbgVariable != NULL); dbgVariable = GetOrCreate(atSpecification, dataMap); //dbgVariable = dataMap.Get(atSpecification); - //BF_ASSERT(dbgVariable != NULL); + //BF_ASSERT(dbgVariable != NULL); } else if (dwBlock != NULL) - { + { dbgVariable = GetOrCreate(tagIdx, dataMap); - dwBlock->mVariables.PushBack(dbgVariable); + dwBlock->mVariables.PushBack(dbgVariable); } else { @@ -3900,9 +3893,9 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (dbgType != NULL) { BF_ASSERT(dbgType->IsNamespace() || (dbgType->mTypeCode == DbgType_Root)); - + if (isNewVariable) - dbgType->mMemberList.PushBack(dbgVariable); + dbgType->mMemberList.PushBack(dbgVariable); } } @@ -3911,7 +3904,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (atSpecification == 0) { dbgVariable->mIsParam = false; - dbgVariable->mName = atName; + dbgVariable->mName = atName; dbgVariable->mConstValue = atConstValue; dbgVariable->mType = GetOrCreateType(atType, dataMap); dbgVariable->mIsConst = hadConstValue; @@ -3922,16 +3915,16 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgVariable->mLinkName = atLinkageName; dbgVariable->mLocationLen = (int8)atLocationLen; dbgVariable->mLocationData = atLocationData; - dbgVariable->mCompileUnit = compileUnit; + dbgVariable->mCompileUnit = compileUnit; /*if (dbgVariable->mIsStatic && !dbgVariable->mIsConst && (dbgVariable->mLocationLen > 0) && (dbgVariable->mIsExtern)) { DbgAddrType addrType = DbgAddrType_Value; - // + // addr_target valAddr = mDebugTarget->EvaluateLocation(dbgVariable->mCompileUnit->mDbgModule, NULL, dbgVariable->mLocationData, dbgVariable->mLocationLen, NULL, &addrType); if ((addrType == DbgAddrType_Target) && (valAddr != 0)) { - dbgVariable->mStaticCachedAddr = valAddr; + dbgVariable->mStaticCachedAddr = valAddr; if (dbgVariable->mLinkName != NULL) mStaticVariables.push_back(dbgVariable); } @@ -3951,7 +3944,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) abstractOriginReplaceList.push_back(abstractOriginEntry); } else if (dbgVariable->mName == NULL) - dbgVariable->mName = "_unnamed"; + dbgVariable->mName = "_unnamed"; if (addToGlobalVarMap) mGlobalVarMap.Insert(dbgVariable); @@ -3978,13 +3971,13 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) break; } - + if ((dwSubprogram->mParams.IsEmpty()) && (dwSubprogram->mParentType != 0)) - dwSubprogram->mParentType->mMethodsWithParamsCount++; + dwSubprogram->mParentType->mMethodsWithParamsCount++; //DbgVariable* dbgVariable = mAlloc.Alloc(); DbgVariable* dwVariable = GetOrCreate(tagIdx, dataMap); - dwSubprogram->mParams.PushBack(dwVariable); + dwSubprogram->mParams.PushBack(dwVariable); if (atArtificial != 0) { @@ -3995,15 +3988,14 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dwVariable->mCompileUnit = compileUnit; dwVariable->mIsParam = true; - dwVariable->mName = atName; + dwVariable->mName = atName; dwVariable->mLocationLen = (int)atLocationLen; dwVariable->mLocationData = atLocationData; dwVariable->mType = GetOrCreateType(atType, dataMap); if (atAbstractOrigin != 0) { - - } + } } break; case DW_TAG_enumerator: @@ -4011,16 +4003,16 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) DbgVariable* member = mAlloc.Alloc(); member->mCompileUnit = compileUnit; member->mConstValue = atConstValue; - member->mName = atName; + member->mName = atName; member->mIsStatic = true; member->mIsConst = true; - DbgType* parentType = GetStackTop(&dataStack); + DbgType* parentType = GetStackTop(&dataStack); parentType->mMemberList.PushBack(member); member->mMemberOffset = atDataMemberLocation; //member->mType = parentType->mTypeParam; member->mType = parentType; - + // Insert into parent's namespace auto prevTop = dataStack.back(); dataStack.pop_back(); @@ -4030,12 +4022,12 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (dwBlock != NULL) { DbgVariable* dwVariable = mAlloc.Alloc(); - dwBlock->mVariables.PushBack(dwVariable); + dwBlock->mVariables.PushBack(dwVariable); if (atSpecification == 0) { dwVariable->mIsParam = false; - dwVariable->mName = atName; + dwVariable->mName = atName; dwVariable->mConstValue = atConstValue; dwVariable->mType = parentType->mTypeParam; dwVariable->mIsConst = hadConstValue; @@ -4061,7 +4053,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) { DbgType* derivedType = GetStackTop(&dataStack); DbgBaseTypeEntry* baseTypeEntry = mAlloc.Alloc(); - baseTypeEntry->mBaseType = GetOrCreateType(atType, dataMap); + baseTypeEntry->mBaseType = GetOrCreateType(atType, dataMap); if (atDataMemberData != NULL) { bool foundVirtOffset = false; @@ -4069,7 +4061,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (*(opPtr++) == DW_OP_dup) { if (*(opPtr++) == DW_OP_deref) - { + { if (*(opPtr++) == DW_OP_constu) { baseTypeEntry->mVTableOffset = (int)DecodeSLEB128(opPtr) / sizeof(int32); @@ -4078,19 +4070,19 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) if (*(opPtr++) == DW_OP_minus) baseTypeEntry->mVTableOffset = -baseTypeEntry->mVTableOffset; } - } + } } - + BF_ASSERT(foundVirtOffset); } else baseTypeEntry->mThisOffset = atDataMemberLocation; - derivedType->mBaseTypes.PushBack(baseTypeEntry); + derivedType->mBaseTypes.PushBack(baseTypeEntry); } break; case DW_TAG_member: { - DbgType* parentType = GetStackTop(&dataStack); + DbgType* parentType = GetStackTop(&dataStack); if ((atName != NULL) && (strncmp(atName, "_vptr$", 6) == 0)) { @@ -4101,7 +4093,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) DbgVariable* member = GetOrCreate(tagIdx, dataMap); member->mIsMember = true; member->mCompileUnit = compileUnit; - member->mName = atName; + member->mName = atName; member->mType = GetOrCreateType(atType, dataMap); member->mConstValue = atConstValue; member->mIsConst = hadConstValue; @@ -4109,10 +4101,10 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) member->mBitSize = atBitSize; member->mBitOffset = atBitOffset; member->mIsExtern = atExternal != 0; - + parentType->mMemberList.PushBack(member); member->mMemberOffset = atDataMemberLocation; - + if ((member->mIsStatic) && (!member->mIsConst)) parentType->mHasStaticMembers = true; @@ -4129,7 +4121,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) DbgType* parentType = GetStackTop(&dataStack); int arrSize = atCount; - deferredArrayDims.push_back(arrSize); + deferredArrayDims.push_back(arrSize); } break; @@ -4142,7 +4134,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: case DW_TAG_unspecified_type: - case DW_TAG_class_type: + case DW_TAG_class_type: case DW_TAG_enumeration_type: case DW_TAG_structure_type: case DW_TAG_union_type: @@ -4152,7 +4144,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) //case DW_TAG_subrange_type: case DW_TAG_restrict_type: { - int typeIdx = (int)(tagDataStart - startData); + int typeIdx = (int)(tagDataStart - startData); DbgType* dbgType = GetOrCreateType(typeIdx, dataMap); const char* nameSep = (compileUnit->mLanguage == DbgLanguage_Beef) ? "." : "::"; @@ -4164,7 +4156,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) { BF_ASSERT(dbgType->mTypeCode == DbgType_Null); DbgType* parentType = GetStackTop(&dataStack); - + if (parentType != NULL) { dbgType->mParent = parentType; @@ -4178,7 +4170,6 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) } else { - int nameSepLen = strlen(nameSep); int parentNameLen = strlen(dbgType->mParent->mName); int nameLen = strlen(atName); @@ -4196,7 +4187,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) compileUnit->mGlobalType->mSubTypeList.PushBack(dbgType); } } - + const char* useName = atName; /*if ((useName != NULL) && (strcmp(useName, "@") == 0)) useName = NULL;*/ @@ -4214,9 +4205,9 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) int typeNameLen = (dbgType->mTypeName != NULL) ? (int)strlen(dbgType->mTypeName) : 0; //int templateParamsLen = (dbgType->mTemplateParams != NULL) ? strlen(dbgType->mTemplateParams) : 0; if ((parentNameLen != 0) /*&& (templateParamsLen == 0)*/) - { + { int nameSepLen = (int)strlen(nameSep); - + int nameLen = parentNameLen + typeNameLen /*+ templateParamsLen*/; if ((parentNameLen > 0) && (nameLen > 0)) nameLen += nameSepLen; @@ -4244,7 +4235,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) namePtr += templateParamsLen; }*/ } - + dbgType->mTypeCode = DbgType_Null; dbgType->mIsDeclaration = atDeclaration; @@ -4253,7 +4244,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgType->mSize = atByteSize; dbgType->mSizeCalculated = true; } - + switch (entryTag) { case DW_TAG_base_type: @@ -4275,8 +4266,8 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgType->mTypeCode = DbgType_SChar16; else if (atByteSize == 4) dbgType->mTypeCode = DbgType_SChar32; - else - atEncoding = DW_ATE_signed; + else + atEncoding = DW_ATE_signed; break; case DW_ATE_unsigned_char: if (atByteSize == 1) @@ -4292,7 +4283,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgType->mTypeCode = DbgType_Bool; else atEncoding = DW_ATE_unsigned; - break; + break; } if (dbgType->mTypeCode == DbgType_Null) @@ -4352,7 +4343,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgType->mTypeCode = DbgType_u128; break; } - break; + break; case DW_ATE_float: if (atByteSize == 4) dbgType->mTypeCode = DbgType_Single; @@ -4369,7 +4360,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) else if (atByteSize == 16) dbgType->mTypeCode = DbgType_ComplexDouble; else if (atByteSize == 24) - dbgType->mTypeCode = DbgType_ComplexDouble96; + dbgType->mTypeCode = DbgType_ComplexDouble96; else if (atByteSize == 32) dbgType->mTypeCode = DbgType_ComplexDouble128; break; @@ -4379,7 +4370,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) } } break; - case DW_TAG_enumeration_type: //TODO: Handle these differently + case DW_TAG_enumeration_type: //TODO: Handle these differently dbgType->mTypeCode = DbgType_Enum; dbgType->mTypeParam = mAlloc.Alloc(); if (atByteSize == 8) @@ -4396,7 +4387,7 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) } break; case DW_TAG_namespace: - dbgType->mTypeCode = DbgType_Namespace; + dbgType->mTypeCode = DbgType_Namespace; break; case DW_TAG_const_type: dbgType->mTypeCode = DbgType_Const; @@ -4432,15 +4423,15 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) case DW_TAG_array_type: dbgType->mTypeCode = DbgType_SizedArray; dbgType->mTypeParam = GetOrCreateType(atType, dataMap); - break; + break; case DW_TAG_structure_type: - dbgType->mTypeCode = DbgType_Struct; + dbgType->mTypeCode = DbgType_Struct; break; case DW_TAG_class_type: - dbgType->mTypeCode = DbgType_Class; - break; + dbgType->mTypeCode = DbgType_Class; + break; case DW_TAG_union_type: - dbgType->mTypeCode = DbgType_Union; + dbgType->mTypeCode = DbgType_Union; break; case DW_TAG_typedef: dbgType->mTypeCode = DbgType_TypeDef; @@ -4460,28 +4451,28 @@ bool DbgModule::ParseDWARF(const uint8*& dataPtr) dbgType->mTypeCode = DbgType_Restrict; dbgType->mTypeParam = GetOrCreateType(atType, dataMap); break; - } - + } + newDataPair = MakeDataPair(dbgType); } break; } - + if (hasChildren) - dataStack.push_back(newDataPair); + dataStack.push_back(newDataPair); } for (auto& abstractOriginEntry : abstractOriginReplaceList) abstractOriginEntry.Replace(); GetLinkedModule()->MapTypes(startingTypeIdx); - + dataPtr = dataEnd; return true; } void DbgModule::ParseDebugFrameData() -{ +{ BP_ZONE("ParseDebugFrameData"); const uint8* data = mDebugFrameData; @@ -4498,11 +4489,11 @@ void DbgModule::ParseDebugFrameData() int length = GET(int); if (length == 0) break; - + const uint8* dataEnd = data + length; int cieID = GET(int); - + if (cieID < 0) { BP_ALLOC_T(DwCommonFrameDescriptor); @@ -4511,7 +4502,7 @@ void DbgModule::ParseDebugFrameData() char version = GET(char); commonFrameDescriptor->mDbgModule = this; commonFrameDescriptor->mAugmentation = DataGetString(data); - + if (version >= 4) { commonFrameDescriptor->mPointerSize = GET(int8); @@ -4531,7 +4522,7 @@ void DbgModule::ParseDebugFrameData() commonFrameDescriptorMap[mDebugFrameAddress + relSectionAddr] = commonFrameDescriptor; } else - { + { addr_target lowPC = GET(addr_target); addr_target highPC = lowPC + GET(addr_target); @@ -4546,11 +4537,11 @@ void DbgModule::ParseDebugFrameData() frameDescriptor->mLowPC = lowPC; frameDescriptor->mHighPC = highPC; frameDescriptor->mInstData = data; - frameDescriptor->mInstLen = (int)(dataEnd - data); + frameDescriptor->mInstLen = (int)(dataEnd - data); frameDescriptor->mCommonFrameDescriptor = commonFrameDescriptor; } data = dataEnd; - } + } } void DbgModule::ParseEHFrameData() @@ -4584,40 +4575,40 @@ void DbgModule::ParseEHFrameData() commonFrameDescriptor->mCodeAlignmentFactor = (int)DecodeULEB128(data); commonFrameDescriptor->mDataAlignmentFactor = (int)DecodeSLEB128(data); commonFrameDescriptor->mReturnAddressColumn = (int)DecodeULEB128(data); - commonFrameDescriptor->mAugmentation = augmentation; - + commonFrameDescriptor->mAugmentation = augmentation; + if (*augmentation == 'z') { ++augmentation; - int augLen = (int)DecodeULEB128(data); + int augLen = (int)DecodeULEB128(data); commonFrameDescriptor->mAugmentationLength = augLen; - const uint8* augEnd = data + augLen; + const uint8* augEnd = data + augLen; while (*augmentation != '\0') - { + { if (*augmentation == 'R') commonFrameDescriptor->mAddressPointerEncoding = (int) GET(uint8); else if (*augmentation == 'P') { int encodingType = GET(uint8); BF_ASSERT(encodingType == 0); - commonFrameDescriptor->mLSDARoutine = GET(addr_target); + commonFrameDescriptor->mLSDARoutine = GET(addr_target); } - else if (*augmentation == 'L') - commonFrameDescriptor->mLSDAPointerEncodingFDE = GET(uint8); + else if (*augmentation == 'L') + commonFrameDescriptor->mLSDAPointerEncodingFDE = GET(uint8); else if (*augmentation == 'S') { - // mIsSignalHandler - on return from stack frame, CFA is before next instruction rather than after it + // mIsSignalHandler - on return from stack frame, CFA is before next instruction rather than after it } else BF_FATAL("Unknown CIE augmentation"); ++augmentation; - } + } data = augEnd; } commonFrameDescriptor->mInstData = data; commonFrameDescriptor->mInstLen = (int)(dataEnd - data); - + mDebugTarget->mCommonFrameDescriptors.push_back(commonFrameDescriptor); commonFrameDescriptorMap[sectionAddress] = commonFrameDescriptor; } @@ -4628,7 +4619,7 @@ void DbgModule::ParseEHFrameData() addr_target lowPC; addr_target highPC; - + if (commonFrameDescriptor->mAddressPointerEncoding == (DW_EH_PE_pcrel | DW_EH_PE_sdata4)) { lowPC = GET(int); @@ -4637,7 +4628,7 @@ void DbgModule::ParseEHFrameData() } else { - lowPC = GET(int); + lowPC = GET(int); highPC = lowPC + GET(int); } @@ -4673,8 +4664,8 @@ void DbgModule::ParseEHFrameData() augmentation++; } data = augEnd; - } - + } + frameDescriptor->mLowPC = lowPC; frameDescriptor->mHighPC = highPC; frameDescriptor->mInstData = data; @@ -4686,13 +4677,12 @@ void DbgModule::ParseEHFrameData() } void DbgModule::FlushLineData(DbgSubprogram* curSubprogram, std::list& queuedLineData) -{ - +{ } DbgSrcFile* DbgModule::AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath) { - DbgSrcFile* dwSrcFile = mDebugTarget->AddSrcFile(srcFilePath); + DbgSrcFile* dwSrcFile = mDebugTarget->AddSrcFile(srcFilePath); if (compileUnit != NULL) { DbgSrcFileReference srcFileRef; @@ -4705,15 +4695,15 @@ DbgSrcFile* DbgModule::AddSrcFile(DbgCompileUnit* compileUnit, const String& src } bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) -{ +{ BP_ZONE("ParseDebugLineInfo"); - + const uint8* data = dataPtr; - const int startOffset = (int)(data - mDebugLineData); + const int startOffset = (int)(data - mDebugLineData); int length = GET(int); if (length == 0) return false; - DbgCompileUnit* dwCompileUnit = mCompileUnits[compileUnitIdx]; + DbgCompileUnit* dwCompileUnit = mCompileUnits[compileUnitIdx]; const uint8* dataEnd = data + length; short version = GET(short); int headerLength = GET(int); @@ -4744,7 +4734,7 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) int curFileIdx = 0; DbgSubprogram* curSubprogram = NULL; - + #define ADD_LINEDATA(lineData) \ lineBuilder.Add(dwCompileUnit, lineData, dwSrcFileRef->mSrcFile, NULL); @@ -4762,29 +4752,29 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) filePath = String(directoryNames[directoryIdx - 1]) + "/"; filePath += path; filePath = GetAbsPath(filePath, dwCompileUnit->mCompileDir); - AddSrcFile(dwCompileUnit, filePath.c_str()); + AddSrcFile(dwCompileUnit, filePath.c_str()); } if (dwCompileUnit->mSrcFileRefs.size() > 0) dwSrcFileRef = &dwCompileUnit->mSrcFileRefs.front(); - + DbgLineDataBuilder lineBuilder(this); bool queuedPostPrologue = false; - DbgLineDataState dwLineData; + DbgLineDataState dwLineData; dwLineData.mLine = 0; dwLineData.mRelAddress = 0; dwLineData.mOpIndex = 0; dwLineData.mBasicBlock = false; dwLineData.mDiscriminator = 0; dwLineData.mIsStmt = defaultIsStmt != 0; - dwLineData.mIsa = 0; + dwLineData.mIsa = 0; dwLineData.mColumn = -2; while (data < dataEnd) { - uint8_t opcode = GET(uint8_t); + uint8_t opcode = GET(uint8_t); switch (opcode) { case DW_LNS_extended_op: @@ -4794,26 +4784,26 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) switch (exOpcode) { case DW_LNE_end_sequence: - { + { ADD_LINEDATA(dwLineData); - + dwSrcFileRef = &dwCompileUnit->mSrcFileRefs[0]; dwLineData.mLine = 0; dwLineData.mRelAddress = 0; dwLineData.mOpIndex = 0; - dwLineData.mBasicBlock = false; - dwLineData.mDiscriminator = 0; + dwLineData.mBasicBlock = false; + dwLineData.mDiscriminator = 0; dwLineData.mIsStmt = defaultIsStmt != 0; dwLineData.mIsa = 0; - dwLineData.mColumn = -2; + dwLineData.mColumn = -2; } break; - case DW_LNE_set_address: + case DW_LNE_set_address: dwLineData.mRelAddress = (uint32)(RemapAddr(GET(addr_target)) - mImageBase); break; case DW_LNE_define_file: { - const char* path = DataGetString(data); + const char* path = DataGetString(data); int directoryIdx = (int)DecodeULEB128(data); int lastModificationTime = (int)DecodeULEB128(data); int fileLength = (int)DecodeULEB128(data); @@ -4825,11 +4815,11 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) } } break; - case DW_LNS_copy: + case DW_LNS_copy: ADD_LINEDATA(dwLineData); - + dwLineData.mDiscriminator = 0; - dwLineData.mBasicBlock = false; + dwLineData.mBasicBlock = false; break; case DW_LNS_advance_pc: { @@ -4872,7 +4862,7 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) int opAdvance = adjustedOpcode / lineRange; uint32 newAddress = dwLineData.mRelAddress + minimumInstructionLength * ((dwLineData.mOpIndex + opAdvance) / maximumOperationsPerInstruction); int newOpIndex = (dwLineData.mOpIndex + opAdvance) % maximumOperationsPerInstruction; - + dwLineData.mRelAddress = newAddress; dwLineData.mOpIndex = newOpIndex; } @@ -4884,13 +4874,13 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) dwLineData.mOpIndex = 0; } break; - case DW_LNS_set_prologue_end: - { + case DW_LNS_set_prologue_end: + { queuedPostPrologue = true; } break; case DW_LNS_set_epilogue_begin: - { + { dwLineData.mColumn = -2; } break; @@ -4899,7 +4889,7 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) dwLineData.mIsa = (int)DecodeULEB128(data); } break; - default: + default: { // Special opcode int adjustedOpcode = opcode - opcodeBase; @@ -4914,16 +4904,14 @@ bool DbgModule::ParseDebugLineInfo(const uint8*& dataPtr, int compileUnitIdx) dwLineData.mOpIndex = newOpIndex; DbgLineData* lastLineData = NULL; - + if ((newAddress == oldAddress) && (queuedPostPrologue) && (curSubprogram != NULL) && (curSubprogram->mBlock.mLowPC == newAddress)) - { + { // Adjust this line later ADD_LINEDATA(dwLineData); - } + } queuedPostPrologue = false; - - } break; } @@ -4943,7 +4931,7 @@ addr_target DbgModule::GetHotTargetAddress(DbgHotTargetSection* hotTargetSection if (hotTargetSection->mNoTargetAlloc) return 0; - hotTargetSection->mTargetSectionAddr = mDebugger->AllocHotTargetMemory(hotTargetSection->mDataSize, hotTargetSection->mCanExecute, hotTargetSection->mCanWrite, &hotTargetSection->mTargetSectionSize); + hotTargetSection->mTargetSectionAddr = mDebugger->AllocHotTargetMemory(hotTargetSection->mDataSize, hotTargetSection->mCanExecute, hotTargetSection->mCanWrite, &hotTargetSection->mTargetSectionSize); hotTargetSection->mImageOffset = (int)mImageSize; if (mImageBase == NULL) @@ -4977,7 +4965,6 @@ uint8* DbgModule::GetHotTargetData(addr_target address) void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolvedSymbolAddr, PE_SymInfo* symInfo) { - #ifdef BF_DBG_32 if (coffReloc.mType == IMAGE_REL_I386_DIR32) { @@ -4998,7 +4985,7 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c else if (coffReloc.mType == IMAGE_REL_I386_SECTION) { // auto linkedModule = GetLinkedModule(); -// addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF; +// addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF; // int* encodingPtr = NULL; // if (linkedModule->mSecRelEncodingMap.TryAdd(mappedAddr, NULL, &encodingPtr)) // { @@ -5012,7 +4999,7 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c { //*(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += symInfo->mValue; *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += resolvedSymbolAddr; - } + } else { BF_ASSERT(0=="Invalid COFF reloc type"); @@ -5020,13 +5007,13 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c #else // CodeView uses SECTION:SECREL locations, and we just want to find a mapping such that - // COFF::GetSectionAddr can map it to the 64-bit address. We do this by encoding the + // COFF::GetSectionAddr can map it to the 64-bit address. We do this by encoding the // lower 31 bits in the SECREL (allowing a 31-bit offset at the destination as well) // and then we use a 15-bit key to map the upper bits if (coffReloc.mType == IMAGE_REL_AMD64_REL32) { - addr_target myAddr = GetHotTargetAddress(hotTargetSection) + coffReloc.mVirtualAddress; + addr_target myAddr = GetHotTargetAddress(hotTargetSection) + coffReloc.mVirtualAddress; intptr_target addrOffset = resolvedSymbolAddr - myAddr - sizeof(int32); BF_ASSERT((int64)(int32)addrOffset == addrOffset); @@ -5042,7 +5029,7 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c else*/ { auto linkedModule = GetLinkedModule(); - addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF; + addr_target mappedAddr = resolvedSymbolAddr & ~0x7FFFFFF; /*auto pair = linkedModule->mSecRelEncodingMap.insert(std::make_pair(mappedAddr, (int)linkedModule->mSecRelEncodingMap.size())); if (pair.second) linkedModule->mSecRelEncodingVec.push_back(mappedAddr);*/ @@ -5058,16 +5045,15 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c } } else if (coffReloc.mType == IMAGE_REL_AMD64_SECREL) - { + { auto linkedModule = GetLinkedModule(); if ((resolvedSymbolAddr >= linkedModule->mTLSAddr) && (resolvedSymbolAddr < linkedModule->mTLSAddr + linkedModule->mTLSSize)) { // Make relative to actual TLS data resolvedSymbolAddr -= linkedModule->mTLSAddr; } - + *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (uint32)(resolvedSymbolAddr & 0x7FFFFFF); - } else if (coffReloc.mType == IMAGE_REL_AMD64_ADDR64) { @@ -5080,7 +5066,7 @@ void DbgModule::DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& c // It was causing hot-loaded jump tables to have invalid addresses since the need to be relative to __ImageBase *(uint32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += (uint32)(resolvedSymbolAddr - GetTargetImageBase()); //*(int32*)(hotTargetSection->mData + coffReloc.mVirtualAddress) += secRelAddr; - } + } else { BF_ASSERT(0=="Invalid COFF reloc type"); @@ -5110,7 +5096,7 @@ bool DbgModule::IsHotSwapPreserve(const String& name) } void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolvedSymbolAddrs) -{ +{ auto mainModule = mDebugTarget->mTargetBinary; mainModule->ParseSymbolData(); @@ -5145,7 +5131,7 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved name = mStringTable + symInfo->mNameOfs[1]; bool didNameMatch = false; - + addr_target resolvedSymbolAddr = resolvedSymbolAddrs[coffReloc.mSymbolTableIndex]; #ifdef BF_DBG_32 @@ -5154,7 +5140,7 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved name.Remove(0, 1); #else bool needsSymbolAddr = (coffReloc.mType == IMAGE_REL_AMD64_ADDR64) || (coffReloc.mType == IMAGE_REL_AMD64_ADDR32) || (coffReloc.mType == IMAGE_REL_AMD64_ADDR32NB) || - ((coffReloc.mType >= IMAGE_REL_AMD64_REL32) || (coffReloc.mType <= IMAGE_REL_AMD64_REL32_5)); + ((coffReloc.mType >= IMAGE_REL_AMD64_REL32) || (coffReloc.mType <= IMAGE_REL_AMD64_REL32_5)); #endif bool isHsPrev = false; @@ -5167,13 +5153,13 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved bool deferResolve = false; if ((resolvedSymbolAddr == 0) && (needsSymbolAddr)) - { + { bool isHotSwapPreserve = IsHotSwapPreserve(name); if ((symInfo->mSectionNum == 0) || (isHotSwapPreserve) || (isHsPrev)) - { + { auto origSymbolEntry = mainModule->mSymbolNameMap.Find(name.c_str()); if (origSymbolEntry != NULL) - { + { resolvedSymbolAddr = origSymbolEntry->mValue->mAddress; } else @@ -5182,16 +5168,16 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved deferResolve = true; } } - + if ((symInfo->mSectionNum != 0) && (resolvedSymbolAddr == NULL)) - { + { DbgHotTargetSection* refHotTargetSection = mHotTargetSections[symInfo->mSectionNum - 1]; resolvedSymbolAddr = GetHotTargetAddress(refHotTargetSection) + symInfo->mValue; // Using the !hotTargetSection->mNoTargetAlloc check down here caused us to not properly remap reloaded // static members in the debug info. Even though we parse the debug info before we apply the deferred // resolves, the mLocData points into the original data so we still get it remapped when we use that // mLocData - if (/*(!hotTargetSection->mNoTargetAlloc) &&*/ ((refHotTargetSection->mData == NULL) || (refHotTargetSection->mNoTargetAlloc)) && + if (/*(!hotTargetSection->mNoTargetAlloc) &&*/ ((refHotTargetSection->mData == NULL) || (refHotTargetSection->mNoTargetAlloc)) && (!isStaticSymbol)) deferResolve = true; else @@ -5200,13 +5186,13 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved } if (deferResolve) - { + { // It's a static field, defer resolution, but don't bother replacing for debug info sections DbgDeferredHotResolve* deferredResolve = mDeferredHotResolveList.Alloc(); deferredResolve->mHotTargetSection = hotTargetSection; deferredResolve->mName = name; deferredResolve->mNewAddr = resolvedSymbolAddr; - deferredResolve->mReloc = coffReloc; + deferredResolve->mReloc = coffReloc; continue; } else @@ -5214,7 +5200,7 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved resolvedSymbolAddrs[coffReloc.mSymbolTableIndex] = resolvedSymbolAddr; DoReloc(hotTargetSection, coffReloc, resolvedSymbolAddr, symInfo); } - } + } } } } @@ -5266,7 +5252,7 @@ void DbgModule::CommitHotTargetSections() } void DbgModule::HotReplaceType(DbgType* newType) -{ +{ auto linkedModule = GetLinkedModule(); newType->PopulateType(); @@ -5301,9 +5287,9 @@ void DbgModule::HotReplaceType(DbgType* newType) { linkedModule->MapCompileUnitMethods(methodNameEntry->mCompileUnitId); methodNameEntry->mCompileUnitId = -1; - } + } } - + // Now actually remove the linedata from the defining module HashSet checkedFiles; for (auto method : primaryType->mMethodList) @@ -5319,7 +5305,7 @@ void DbgModule::HotReplaceType(DbgType* newType) checkedFiles.Clear(); int prevCtx = -1; - auto inlineRoot = method->GetRootInlineParent(); + auto inlineRoot = method->GetRootInlineParent(); for (int lineIdx = 0; lineIdx < method->mLineInfo->mLines.mSize; lineIdx++) { auto& lineData = method->mLineInfo->mLines[lineIdx]; @@ -5327,7 +5313,7 @@ void DbgModule::HotReplaceType(DbgType* newType) { auto ctxInfo = inlineRoot->mLineInfo->mContexts[lineData.mCtxIdx]; auto srcFile = ctxInfo.mSrcFile; - prevCtx = lineData.mCtxIdx; + prevCtx = lineData.mCtxIdx; if (srcFile != lastSrcFile) { if (checkedFiles.Add(srcFile)) @@ -5336,7 +5322,7 @@ void DbgModule::HotReplaceType(DbgType* newType) // These go into a hot-replaced list so we can still bind to them -- that is necessary because // we may still have old versions of this method running (and may forever, if its in a loop on some thread) // since we only patch entry points - //srcFile->RemoveLines(primaryType->mCompileUnit->mDbgModule, primaryType->mCompileUnit, true); + //srcFile->RemoveLines(primaryType->mCompileUnit->mDbgModule, primaryType->mCompileUnit, true); //srcFile->RemoveLines(primaryType->mCompileUnit->mDbgModule, method, true); srcFile->RemoveLines(method->mCompileUnit->mDbgModule, method, true); @@ -5348,12 +5334,11 @@ void DbgModule::HotReplaceType(DbgType* newType) } } - - //DbgType* primaryType = newType->GetPrimaryType(); + //DbgType* primaryType = newType->GetPrimaryType(); // We need to keep a persistent list of hot replaced methods so we can set hot jumps // in old methods that may still be on the callstack. These entries get removed when - // we unload unused hot files in + // we unload unused hot files in while (!primaryType->mMethodList.IsEmpty()) { auto method = primaryType->mMethodList.PopFront(); @@ -5363,7 +5348,7 @@ void DbgModule::HotReplaceType(DbgType* newType) primaryType->mHotReplacedMethodList.PushFront(method); mHotPrimaryTypes.Add(primaryType); } - + Dictionary oldProgramMap; for (auto oldMethod : primaryType->mHotReplacedMethodList) { @@ -5379,13 +5364,13 @@ void DbgModule::HotReplaceType(DbgType* newType) bool setHotJumpFailed = false; while (!newType->mMethodList.IsEmpty()) - { + { DbgSubprogram* newMethod = newType->mMethodList.PopFront(); if (!newMethod->mBlock.IsEmpty()) { BfLogDbg("Hot added new method %p %s Address:%p\n", newMethod, newMethod->mName, newMethod->mBlock.mLowPC); - newMethod->PopulateSubprogram(); + newMethod->PopulateSubprogram(); auto symInfo = mDebugTarget->mSymbolMap.Get(newMethod->mBlock.mLowPC); if (symInfo != NULL) @@ -5401,7 +5386,7 @@ void DbgModule::HotReplaceType(DbgType* newType) } else { - // When mangles match but the actual signatures don't match, that can mean that the call signature was changed + // When mangles match but the actual signatures don't match, that can mean that the call signature was changed // and thus it's actually a different method and shouldn't hot jump OR it could be lambda whose captures changed. // When the lambda captures change, the user didn't actually enter a different signature so we want to do a hard // fail if the old code gets called to avoid confusion of "why aren't my changes working?" @@ -5421,7 +5406,7 @@ void DbgModule::HotReplaceType(DbgType* newType) auto newType = newParam->mType->mTypeParam->GetPrimaryType(); newType->PopulateType(); if ((oldType->IsStruct()) && (newType->IsStruct())) - { + { bool wasMatch = true; auto oldMember = oldType->mMemberList.front(); @@ -5451,7 +5436,7 @@ void DbgModule::HotReplaceType(DbgType* newType) wasMatch = false; break; } - + oldMember = oldMember->mNext; newMember = newMember->mNext; } @@ -5465,9 +5450,9 @@ void DbgModule::HotReplaceType(DbgType* newType) { mDebugTarget->mDebugger->PhysSetBreakpoint(oldMethod->mBlock.mLowPC); oldMethod->mHotReplaceKind = DbgSubprogram::HotReplaceKind_Invalid; - } + } } - } + } if (doHotJump) { @@ -5479,7 +5464,7 @@ void DbgModule::HotReplaceType(DbgType* newType) oldMethod->mHotReplaceKind = DbgSubprogram::HotReplaceKind_Replaced; } } - } + } } newMethod->mParentType = primaryType; primaryType->mMethodList.PushBack(newMethod); @@ -5494,7 +5479,7 @@ void DbgModule::HotReplaceType(DbgType* newType) // if (!newMethod->mBlock.IsEmpty()) // { // newMethod->PopulateSubprogram(); -// +// // bool found = false; // for (auto oldMethod : primaryType->mHotReplacedMethodList) // { @@ -5507,7 +5492,7 @@ void DbgModule::HotReplaceType(DbgType* newType) // if (!mDebugger->SetHotJump(oldMethod, newMethod)) // setHotJumpFailed = true; // oldMethod->mWasHotReplaced = true; -// } +// } // } // } // } @@ -5515,12 +5500,12 @@ void DbgModule::HotReplaceType(DbgType* newType) // primaryType->mMethodList.PushBack(newMethod); // } - primaryType->mCompileUnit->mWasHotReplaced = true; + primaryType->mCompileUnit->mWasHotReplaced = true; primaryType->mNeedsGlobalsPopulated = newType->mNeedsGlobalsPopulated; primaryType->mUsingNamespaces = newType->mUsingNamespaces; primaryType->mMemberList = newType->mMemberList; - primaryType->mCompileUnit = newType->mCompileUnit; + primaryType->mCompileUnit = newType->mCompileUnit; } bool DbgModule::CanRead(DataStream* stream, DebuggerResult* outResult) @@ -5590,7 +5575,7 @@ const char* DbgModule::GetStringTable(DataStream* stream, int stringTablePos) bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) { - BP_ZONE("DbgModule::ReadCOFF"); + BP_ZONE("DbgModule::ReadCOFF"); //if (this == mDebugTarget->mTargetBinary) //mMemReporter = new MemReporter(); @@ -5607,9 +5592,9 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if (mMemReporter != NULL) mMemReporter->EndSection(); ); - - DbgModule* mainModule = mDebugTarget->mTargetBinary; - + + DbgModule* mainModule = mDebugTarget->mTargetBinary; + MiniDumpDebugger* miniDumpDebugger = NULL; if (mDebugger->IsMiniDumpDebugger()) { @@ -5619,16 +5604,16 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mModuleKind = moduleKind; bool isHotSwap = mModuleKind == DbgModuleKind_HotObject; bool isObjectFile = mModuleKind != DbgModuleKind_Module; - + auto linkedModule = GetLinkedModule(); if (isObjectFile) linkedModule->PopulateStaticVariableMap(); - + mStartTypeIdx = (int)linkedModule->mTypes.size(); int startSrcFile = (int)mDebugTarget->mSrcFiles.size(); mStartSubprogramIdx = (int)mSubprograms.size(); - + PEHeader hdr; memset(&hdr, 0, sizeof(hdr)); @@ -5639,7 +5624,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) { stream->Read(&hdr, sizeof(PEHeader)); stream->SetPos(hdr.e_lfanew); - + stream->Read(&ntHdr, sizeof(PE_NTHeaders)); mPreferredImageBase = ntHdr.mOptionalHeader.mImageBase; @@ -5650,7 +5635,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } if ((hdr.e_magic != PE_DOS_SIGNATURE) || (ntHdr.mSignature != PE_NT_SIGNATURE)) - { + { mLoadState = DbgModuleLoadState_Failed; return false; } @@ -5686,8 +5671,8 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) return false; } #endif - } - + } + int sectionStartPos = stream->GetPos(); int sectionDataEndPos = 0; @@ -5704,19 +5689,19 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) { PESectionHeader sectHdr; - char* name = sectHdr.mName; + char* name = sectHdr.mName; stream->Read(§Hdr, sizeof(PESectionHeader)); if (sectHdr.mSizeOfRawData > 0) sectionDataEndPos = BF_MAX(sectionDataEndPos, (int)(sectHdr.mPointerToRawData + sectHdr.mSizeOfRawData)); if (sectHdr.mNumberOfRelocations > 0) sectionDataEndPos = BF_MAX(sectionDataEndPos, (int)(sectHdr.mPointerToRelocations + sectHdr.mNumberOfRelocations * sizeof(COFFRelocation))); - + if (miniDumpDebugger != NULL) { miniDumpDebugger->MapMemory((addr_target)(mImageBase + sectHdr.mVirtualAddress), (uint8*)mMappedImageFile->mData + sectHdr.mPointerToRawData, sectHdr.mSizeOfRawData); } } - + //fseek(fp, sectionDataEndPos + ntHdr.mFileHeader.mNumberOfSymbols * 18, SEEK_SET); stream->SetPos(sectionDataEndPos); @@ -5726,21 +5711,21 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mSymbolData = symbolData; stream->Read(symbolData, ntHdr.mFileHeader.mNumberOfSymbols * 18); - int curPos = stream->GetPos(); + int curPos = stream->GetPos(); int stringTablePos = curPos; if (isObjectFile) GetStringTable(stream, stringTablePos); - - int mDebugFrameDataLen = 0; - + + int mDebugFrameDataLen = 0; + stream->SetPos(sectionStartPos); - - PEDataDirectory* exportDataDir = &ntHdr.mOptionalHeader.mDataDirectory[0]; - + + PEDataDirectory* exportDataDir = &ntHdr.mOptionalHeader.mDataDirectory[0]; + mHotTargetSections.Resize(ntHdr.mFileHeader.mNumberOfSections); - + Array sectionHeaders; - sectionHeaders.Resize(ntHdr.mFileHeader.mNumberOfSections); + sectionHeaders.Resize(ntHdr.mFileHeader.mNumberOfSections); mSectionRVAs.Resize(sectionHeaders.size() + 1); Array sectionNames; @@ -5752,14 +5737,14 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) { mSectionRVAs[sectNum] = sectionHeaders[sectNum].mVirtualAddress; } - + int tlsSection = -1; for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++) { //PEDataDirectory* dataDir = &ntHdr.mOptionalHeader.mDataDirectory[dirNum]; PESectionHeader& sectHdr = sectionHeaders[sectNum]; - //stream->Read(§Hdr, sizeof(PESectionHeader)); + //stream->Read(§Hdr, sizeof(PESectionHeader)); const char* name = sectHdr.mName; if (name[0] == '/') @@ -5783,7 +5768,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) targetSection->mNoTargetAlloc = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0; mHotTargetSections[sectNum] = targetSection; } - + DbgSection dwSection; dwSection.mIsExecutable = (sectHdr.mCharacteristics & IMAGE_SCN_MEM_EXECUTE) != 0; dwSection.mAddrStart = sectHdr.mVirtualAddress; @@ -5872,8 +5857,8 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mTLSIndexAddr = funcAddr; } - //TODO: - //mDeferredSymbols.PushFront(dwSymbol); + //TODO: + //mDeferredSymbols.PushFront(dwSymbol); dwSymbol->mAddress = (addr_target)(dwSymbol->mAddress + mImageBase); mDebugTarget->mSymbolMap.Insert(dwSymbol); @@ -5883,7 +5868,6 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if ((IsObjectFile()) && (sectHdr.mNumberOfRelocations > 0)) { - //mDebugger->AllocTargetMemory(sectHdr.mSizeOfRawData, true, true); } @@ -5931,13 +5915,13 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } } - //stream->SetPos(debugDirEntry.mVirtualAddress); + //stream->SetPos(debugDirEntry.mVirtualAddress); } } // { - PEDataDirectory& tlsDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]; + PEDataDirectory& tlsDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]; if (tlsDirEntry.mSize > 0) { if ((tlsDirEntry.mVirtualAddress >= sectHdr.mVirtualAddress) && (tlsDirEntry.mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData)) @@ -5950,7 +5934,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mTLSAddr = (addr_target)(tlsDataStart + mImageBase); mTLSSize = (int)(tlsDataEnd - tlsDataStart); - } + } } } @@ -5958,15 +5942,15 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) { PEDataDirectory& debugDirEntry = ntHdr.mOptionalHeader.mDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; if (debugDirEntry.mSize > 0) - { + { if ((debugDirEntry.mVirtualAddress >= sectHdr.mVirtualAddress) && (debugDirEntry.mVirtualAddress < sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData)) - { + { uint8* relPtr = data + debugDirEntry.mVirtualAddress - sectHdr.mVirtualAddress; uint8* endPtr = relPtr + debugDirEntry.mSize; IMAGE_RESOURCE_DIRECTORY* typeDir = (IMAGE_RESOURCE_DIRECTORY*)(relPtr); - - // Skip named entries + + // Skip named entries for (int typeIdx = 0; typeIdx < typeDir->NumberOfIdEntries; typeIdx++) { IMAGE_RESOURCE_DIRECTORY_ENTRY* typeEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((uint8*)typeDir + sizeof(IMAGE_RESOURCE_DIRECTORY) + @@ -5988,25 +5972,25 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) IMAGE_RESOURCE_DATA_ENTRY* dataEntry = (IMAGE_RESOURCE_DATA_ENTRY*)(relPtr + (langEntry->OffsetToData & 0x7FFFFFFF)); uint8* versionData = data + dataEntry->OffsetToData - sectHdr.mVirtualAddress; uint8* vPtr = versionData; - + auto vSize = GET_FROM(vPtr, uint16); auto verEnd = vPtr + vSize; auto vLength = GET_FROM(vPtr, uint16); vPtr += 36; // "VS_VERSION_INFO" - auto fixedFileInfo = GET_FROM(vPtr, VS_FIXEDFILEINFO); + auto fixedFileInfo = GET_FROM(vPtr, VS_FIXEDFILEINFO); auto _GetString = [&]() { wchar_t* cPtr = (wchar_t*)vPtr; int len = (int)wcslen(cPtr); vPtr += (len + 1) * 2; - + if (((intptr)vPtr & 3) != 0) vPtr += 2; UTF16String str16(cPtr, len); - return UTF8Encode(str16); + return UTF8Encode(str16); }; while (vPtr < verEnd) @@ -6042,31 +6026,31 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } vPtr = childEnd; - } + } } - } + } } - //stream->SetPos(debugDirEntry.mVirtualAddress); + //stream->SetPos(debugDirEntry.mVirtualAddress); } } - + bool usedData = true; /*if (isUnwindSection) { mExceptionData = data; - mExceptionDataRVA = sectHdr.mVirtualAddress; + mExceptionDataRVA = sectHdr.mVirtualAddress; }*/ if (strcmp(name, ".pdata") == 0) { DbgSectionData entry; - entry.mData = data; + entry.mData = data; entry.mSize = sectHdr.mSizeOfRawData; mExceptionDirectory.Add(entry); } - + // Old, unsupported DWARF debug info /* else if (strcmp(name, ".debug_info") == 0) @@ -6075,13 +6059,13 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } else if (strcmp(name, ".debug_line") == 0) { - mDebugLineData = data; + mDebugLineData = data; } else if (strcmp(name, ".debug_str") == 0) { mDebugStrData = data; } - else if (strcmp(name, ".debug_frame") == 0) + else if (strcmp(name, ".debug_frame") == 0) { mDebugFrameAddress = ntHdr.mOptionalHeader.mImageBase + sectHdr.mVirtualAddress; mDebugFrameData = data; @@ -6095,11 +6079,11 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) else if (strcmp(name, ".debug_abbrev") == 0) { mDebugAbbrevData = data; - mDebugAbbrevPtrData = new const uint8*[sectHdr.mSizeOfRawData]; + mDebugAbbrevPtrData = new const uint8*[sectHdr.mSizeOfRawData]; } else if (strcmp(name, ".debug_loc") == 0) { - mDebugLocationData = data; + mDebugLocationData = data; } else if (strcmp(name, ".debug_ranges") == 0) { @@ -6120,7 +6104,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) /*if (isUnwindSection) mOwnsExceptionData = true; else*/ - usedData = false; + usedData = false; } if (!usedData) @@ -6141,17 +6125,17 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) int needHotTargetMemory = 0; if (isObjectFile) - { + { for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++) { auto targetSection = mHotTargetSections[sectNum]; if (!targetSection->mNoTargetAlloc) needHotTargetMemory += (targetSection->mDataSize + (mDebugger->mPageSize - 1)) & ~(mDebugger->mPageSize - 1); - } + } mDebugger->ReserveHotTargetMemory(needHotTargetMemory); - + // '0' address is temporary - //mOrigImageData = new DbgModuleMemoryCache(0, NULL, needHotTargetMemory, true); + //mOrigImageData = new DbgModuleMemoryCache(0, NULL, needHotTargetMemory, true); mOrigImageData = new DbgModuleMemoryCache(0, needHotTargetMemory); } @@ -6194,7 +6178,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if (!ParseDebugLineInfo(data, compileUnitIdx)) break; } - + { BP_ZONE("ReadPE_ReadSymbols"); @@ -6224,7 +6208,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if ((symInfo->mStorageClass == COFF_SYM_CLASS_EXTERNAL) || (symInfo->mStorageClass == COFF_SYM_CLASS_STATIC)) { - // 'static' in the C sense. + // 'static' in the C sense. // It means local to the compile unit, so may have multiple copies of the same symbol name. bool isStaticSymbol = symInfo->mStorageClass == COFF_SYM_CLASS_STATIC; @@ -6232,14 +6216,14 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) continue; if (symInfo->mSectionNum > 0) - { + { bool isTLS = false; addr_target targetAddr = 0; if (isObjectFile) { if (symInfo->mSectionNum - 1 == tlsSection) { - isTLS = true; + isTLS = true; } else { @@ -6249,9 +6233,9 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } } else - targetAddr = mSectionRVAs[symInfo->mSectionNum - 1] + symInfo->mValue; - - if (((targetAddr != 0) || (isTLS)) && + targetAddr = mSectionRVAs[symInfo->mSectionNum - 1] + symInfo->mValue; + + if (((targetAddr != 0) || (isTLS)) && (name[0] != '.')) { const char* symbolName = name; @@ -6264,13 +6248,13 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if (strcmp(symbolName, "_tls_index") == 0) { mTLSIndexAddr = (addr_target)(targetAddr + mImageBase); - } - + } + if ((isStaticSymbol) && (IsHotSwapPreserve(symbolName))) isStaticSymbol = false; if ((isObjectFile) && (!isStaticSymbol)) - { + { DbgSymbol* dwSymbol = NULL; linkedModule->ParseSymbolData() ; @@ -6279,15 +6263,15 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) dwSymbol = mAlloc.Alloc(); dwSymbol->mDbgModule = this; dwSymbol->mName = symbolName; - dwSymbol->mAddress = targetAddr; + dwSymbol->mAddress = targetAddr; if (dwSymbol != NULL) - { + { bool isHotSwapPreserve = IsHotSwapPreserve(dwSymbol->mName); bool insertIntoNameMap = true; - + bool oldFound = false; - + auto nameMapEntry = linkedModule->mSymbolNameMap.Find(dwSymbol->mName); if (nameMapEntry != NULL) { @@ -6298,7 +6282,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } else if (mDbgFlavor == DbgFlavor_MS) { - // Store in our own map - this is needed for storing address of the new vdata + // Store in our own map - this is needed for storing address of the new vdata // so the new values can be copied in mSymbolNameMap.Insert(dwSymbol); } @@ -6352,11 +6336,11 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } } } - + if (dwSymbol->mAddress != 0) { if (!oldFound) - linkedModule->mSymbolNameMap.Insert(dwSymbol); + linkedModule->mSymbolNameMap.Insert(dwSymbol); mDebugTarget->mSymbolMap.Insert(dwSymbol); } } @@ -6394,14 +6378,14 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } } - int subProgramSizes = 0; + int subProgramSizes = 0; for (int subProgramIdx = mStartSubprogramIdx; subProgramIdx < mEndSubprogramIdx; subProgramIdx++) { auto dwSubprogram = mSubprograms[subProgramIdx]; subProgramSizes += (int)(dwSubprogram->mBlock.mHighPC - dwSubprogram->mBlock.mLowPC); - + /*for (int i = 0; i < dwSubprogram->mLineDataArray.mSize; i++) - { + { auto lineData = dwSubprogram->mLineDataArray.mData[i]; auto srcFile = lineData->mSrcFileRef->mSrcFile; srcFile->mLineData.push_back(lineData); @@ -6409,7 +6393,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if ((srcFile->mFirstLineDataDbgModule == NULL) || (srcFile->mFirstLineDataDbgModule == this)) srcFile->mFirstLineDataDbgModule = this; else - srcFile->mHasLineDataFromMultipleModules = true; + srcFile->mHasLineDataFromMultipleModules = true; }*/ } @@ -6418,7 +6402,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) /*for (int srcFileIdx = startSrcFile; srcFileIdx < (int)mDebugTarget->mSrcFiles.size(); srcFileIdx++) { if (!mDebugTarget->mSrcFiles[srcFileIdx]->mHadLineData) - { + { mEmptySrcFiles.push_back(mDebugTarget->mSrcFiles[srcFileIdx]); mDebugTarget->mSrcFiles.erase(mDebugTarget->mSrcFiles.begin() + srcFileIdx); } @@ -6445,10 +6429,10 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mImageSize = ntHdr.mOptionalHeader.mSizeOfImage; mEntryPoint = ntHdr.mOptionalHeader.mAddressOfEntryPoint; } - - /*OutputDebugStrF("%s:\n CompileUnits:%d DebugLines: %d Types: %d (%d in map) SubPrograms: %d (%dk) AllocSize:%dk\n", mFilePath.c_str(), mCompileUnits.size(), + + /*OutputDebugStrF("%s:\n CompileUnits:%d DebugLines: %d Types: %d (%d in map) SubPrograms: %d (%dk) AllocSize:%dk\n", mFilePath.c_str(), mCompileUnits.size(), lineDataCount, mEndTypeIdx - mStartTypeIdx, (int)linkedModule->mTypes.size() - mStartTypeIdx, mEndSubprogramIdx - mStartSubprogramIdx, subProgramSizes / 1024, mAlloc.GetAllocSize() / 1024);*/ - + if (isHotSwap) { // In COFF, we don't necessarily add an actual primary type during MapCompileUnitMethods, so this fixes that @@ -6469,7 +6453,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) } if (!didReplaceType) break; - } + } BF_ASSERT(mTypes.size() == 0); for (int typeIdx = mStartTypeIdx; typeIdx < (int)linkedModule->mTypes.size(); typeIdx++) @@ -6480,21 +6464,21 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) HotReplaceType(newType); } } - + if (needHotTargetMemory != 0) { BF_ASSERT(needHotTargetMemory >= (int)mImageSize); } //BF_ASSERT(mEndTypeIdx == (int)linkedModule->mTypes.size()); - //BF_ASSERT(mEndSubprogramIdx == (int)mSubprograms.size()); + //BF_ASSERT(mEndSubprogramIdx == (int)mSubprograms.size()); ParseExceptionData(); mLoadState = DbgModuleLoadState_Loaded; if (mMemReporter != NULL) - { + { mMemReporter->BeginSection("Sections"); ParseSymbolData(); @@ -6506,11 +6490,11 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) orderedSyms.Add(dbgSym); } orderedSyms.Sort([](DbgSymbol* lhs, DbgSymbol* rhs) { return lhs->mAddress < rhs->mAddress; }); - + for (int sectNum = 0; sectNum < ntHdr.mFileHeader.mNumberOfSections; sectNum++) - { + { PESectionHeader& sectHdr = sectionHeaders[sectNum]; - + mMemReporter->BeginSection(sectionNames[sectNum]); DbgSymbol* lastSym = NULL; @@ -6522,7 +6506,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if (dbgSym->mAddress >= mImageBase + sectHdr.mVirtualAddress + sectHdr.mSizeOfRawData) break; - + if (lastSym != NULL) { mMemReporter->Add(lastSym->mName, (int)(dbgSym->mAddress - lastSym->mAddress)); @@ -6533,7 +6517,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) if (startingOffset > 0) mMemReporter->Add("", startingOffset); } - lastSym = dbgSym; + lastSym = dbgSym; } if (lastSym != NULL) @@ -6548,7 +6532,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind) mMemReporter->EndSection(); mMemReporter->mShowInKB = false; - mMemReporter->Report(); + mMemReporter->Report(); } return true; } @@ -6558,7 +6542,7 @@ void DbgModule::FinishHotSwap() BF_ASSERT(IsObjectFile()); auto linkedModule = GetLinkedModule(); - auto mainModule = mDebugTarget->mTargetBinary; + auto mainModule = mDebugTarget->mTargetBinary; HashSet failSet; @@ -6581,10 +6565,10 @@ void DbgModule::FinishHotSwap() } else { - auto symbolEntry = mainModule->mSymbolNameMap.Find(findName.c_str()); + auto symbolEntry = mainModule->mSymbolNameMap.Find(findName.c_str()); if (symbolEntry != NULL) - { + { resolveTargetAddr = symbolEntry->mValue->mAddress; } else @@ -6604,9 +6588,9 @@ void DbgModule::FinishHotSwap() } } } - DoReloc(deferredHotResolve->mHotTargetSection, deferredHotResolve->mReloc, resolveTargetAddr, NULL); + DoReloc(deferredHotResolve->mHotTargetSection, deferredHotResolve->mReloc, resolveTargetAddr, NULL); } - mDeferredHotResolveList.Clear(); + mDeferredHotResolveList.Clear(); if (!failSet.IsEmpty()) { @@ -6617,9 +6601,9 @@ void DbgModule::FinishHotSwap() if (str.Contains("failed to resolve")) { for (auto& sym : failSet) - { + { str += ", "; - str += sym; + str += sym; } handled = true; } @@ -6648,13 +6632,13 @@ void DbgModule::FinishHotSwap() // We need this here because vdata gets loaded first, so we need to wait until we have the addrs for the new methods (from other modules) // before we can finalize the class vdata. - ProcessHotSwapVariables(); + ProcessHotSwapVariables(); for (auto hotTargetSection : mHotTargetSections) delete hotTargetSection; mHotTargetSections.Clear(); - mSymbolNameMap.Clear(); + mSymbolNameMap.Clear(); } addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue) @@ -6667,8 +6651,8 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD addr_target stackFrameData[256]; int stackIdx = 0; - if (pushValue != NULL) - stackFrameData[stackIdx++] = *pushValue; + if (pushValue != NULL) + stackFrameData[stackIdx++] = *pushValue; while (locData < locDataEnd) { @@ -6698,7 +6682,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD break; case DW_OP_stack_value: { - *outAddrType = DbgAddrType_Value; + *outAddrType = DbgAddrType_Value; } break; case DW_OP_addr_noRemap: @@ -6733,7 +6717,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD return 0; BF_ASSERT(dwSubprogram != NULL); DbgSubprogram* nonInlinedSubProgram = dwSubprogram->GetRootInlineParent(); - + if (nonInlinedSubProgram->mFrameBaseData == NULL) { *outAddrType = DbgAddrType_Target; //TODO: why? @@ -6770,7 +6754,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD return 0; BF_ASSERT((opCode - DW_OP_reg0) < CPURegisters::kNumIntRegs); regNum = opCode - DW_OP_reg0; - stackFrameData[stackIdx++] = registers->mIntRegsArray[regNum]; + stackFrameData[stackIdx++] = registers->mIntRegsArray[regNum]; *outAddrType = DbgAddrType_Register; break; @@ -6833,7 +6817,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD } break; case DW_OP_GNU_push_tls_address: - { + { if ((mTLSAddr == 0) || (mTLSIndexAddr == 0)) return 0; @@ -6868,7 +6852,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD intptr DbgModule::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags) { BP_ZONE("DebugTarget::EvaluateLocation"); - + auto dbgModule = this; if (locDataLen == DbgLocationLenKind_SegPlusOffset) @@ -6971,14 +6955,14 @@ void DbgModule::ProcessHotSwapVariables() for (auto staticVariable : mStaticVariables) { bool replaceVariable = false; - + const char* findName = staticVariable->GetMappedName(); auto itr = linkedModule->mStaticVariableMap.find(findName); if (itr != linkedModule->mStaticVariableMap.end()) { DbgVariable* oldVariable = itr->second; // If the old static field has the same type as the new static field then we keep the same - // address, otherwise we use the new (zeroed-out) allocated space + // address, otherwise we use the new (zeroed-out) allocated space auto _GetNewAddress = [&]() { @@ -7001,7 +6985,7 @@ void DbgModule::ProcessHotSwapVariables() if (oldVariable->mType->IsSizedArray()) { mDebugTarget->GetCompilerSettings(); - + bool doMerge = strstr(oldVariable->mName, "sBfClassVData") != NULL; bool keepInPlace = (doMerge) && (strstr(oldVariable->mName, ".vext") == NULL); if (doMerge) @@ -7010,7 +6994,7 @@ void DbgModule::ProcessHotSwapVariables() addr_target newAddress = _GetNewAddress(); if (newAddress == 0) continue; - + uint8* newData = GetHotTargetData(newAddress); int newArraySize = (int)staticVariable->mType->GetByteCount(); int oldArraySize = (int)oldVariable->mType->GetByteCount(); @@ -7069,7 +7053,7 @@ void DbgModule::ProcessHotSwapVariables() // Link the new table to the old extended table addr_target prevLinkage = 0; success = mDebugger->ReadMemory((intptr)oldAddress, sizeof(addr_target), &prevLinkage); - BF_ASSERT(success); + BF_ASSERT(success); success = mDebugger->WriteMemory((intptr)newAddress, &prevLinkage, sizeof(addr_target)); BF_ASSERT(success); @@ -7079,7 +7063,7 @@ void DbgModule::ProcessHotSwapVariables() keepInPlace = true; } - + if (keepInPlace) { // We have to maintain the OLD size because we can't overwrite the original bounds @@ -7088,7 +7072,7 @@ void DbgModule::ProcessHotSwapVariables() staticVariable->mLocationData = oldVariable->mLocationData; staticVariable->mCompileUnit = oldVariable->mCompileUnit; } - } + } else if (oldVariable->mType->Equals(staticVariable->mType)) { if (oldVariable->mType->IsStruct()) @@ -7120,7 +7104,7 @@ void DbgModule::ProcessHotSwapVariables() //staticVariable->mLocationLen = oldVariable->mLocationLen; //staticVariable->mLocationData = oldVariable->mLocationData; replaceVariable = false; - } + } else { BF_ASSERT(!oldVariable->mType->IsSizedArray()); @@ -7136,7 +7120,7 @@ void DbgModule::ProcessHotSwapVariables() if (oldSymbol != NULL) symbolVal->mValue = oldSymbol; } - } + } } else // Not found - new variable replaceVariable = true; @@ -7180,7 +7164,7 @@ DbgFileExistKind DbgModule::CheckSourceFileExist(const StringImpl& path) else existsKind = DbgFileExistKind_HasOldSourceCommand; } - } + } return existsKind; } @@ -7212,12 +7196,11 @@ void DbgModule::RevertWritingEnable() section->mWritingEnabled = false; } } - } template static void RemoveInvalidRange(TRadixMap& radixMap, addr_target startAddr, int addrLength) -{ +{ radixMap.RemoveRange(startAddr, addrLength); } @@ -7257,7 +7240,7 @@ void DbgModule::RemoveTargetData() RemoveInvalidRange(mDebugTarget->mSubprogramMap, (addr_target)mImageBase, (int32)mImageSize); RemoveInvalidRange(mDebugTarget->mExceptionDirectoryMap, (addr_target)mImageBase, (int32)mImageSize); RemoveInvalidRange(mDebugTarget->mContribMap, (addr_target)mImageBase, (int32)mImageSize); - RemoveInvalidMapRange(mDebugTarget->mDwFrameDescriptorMap, (addr_target)mImageBase, (int32)mImageSize); + RemoveInvalidMapRange(mDebugTarget->mDwFrameDescriptorMap, (addr_target)mImageBase, (int32)mImageSize); RemoveInvalidMapRange(mDebugTarget->mCOFFFrameDescriptorMap, (addr_target)mImageBase, (int32)mImageSize); //mDebugTarget->mDwFrameDescriptorMap.erase() @@ -7294,7 +7277,7 @@ void DbgModule::ReportMemory(MemReporter* memReporter) memReporter->BeginSection("OrigImageData"); mOrigImageData->ReportMemory(memReporter); memReporter->EndSection(); - } + } } DbgType* DbgModule::GetPointerType(DbgType* innerType) @@ -7327,7 +7310,7 @@ DbgType* DbgModule::GetConstType(DbgType* innerType) auto linkedModule = GetLinkedModule(); BF_ASSERT(innerType->GetDbgModule()->GetLinkedModule() == linkedModule); - + /*auto itr = linkedModule->mConstTypes.find(innerType); if (itr != linkedModule->mConstTypes.end()) return itr->second;*/ @@ -7351,15 +7334,15 @@ DbgType* DbgModule::GetConstType(DbgType* innerType) } DbgType* DbgModule::GetPrimaryType(DbgType* dbgType) -{ +{ if (dbgType->mPriority <= DbgTypePriority_Normal) { if ((dbgType->mLanguage == DbgLanguage_Beef) && (dbgType->mName != NULL)) - { + { auto newTypeEntry = FindType(dbgType->mName, dbgType->mLanguage); - if (newTypeEntry != NULL) - { - DbgType* newType = newTypeEntry->mValue; + if (newTypeEntry != NULL) + { + DbgType* newType = newTypeEntry->mValue; if ((newType->mTypeCode == DbgType_Ptr) && (newType->IsBfObjectPtr())) newType = newType->mTypeParam; newType->mPriority = DbgTypePriority_Primary_Implicit; @@ -7370,7 +7353,7 @@ DbgType* DbgModule::GetPrimaryType(DbgType* dbgType) { auto newTypeEntry = FindType(dbgType->mName, dbgType->mLanguage); if (newTypeEntry != NULL) - { + { DbgType* newType = newTypeEntry->mValue; newType = newType->RemoveModifiers(); if (newType != dbgType) @@ -7403,7 +7386,7 @@ DbgType* DbgModule::FindTypeHelper(const String& typeName, DbgType* checkType) auto retType = FindTypeHelper(typeName, baseType->mBaseType); if (retType != NULL) return retType; - } + } return NULL; } @@ -7432,12 +7415,12 @@ DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLa } if (contextType != NULL) - { + { DbgType* checkType = contextType; if (checkType->IsPointer()) checkType = checkType->mTypeParam; - return FindTypeHelper(typeName, checkType); + return FindTypeHelper(typeName, checkType); } return NULL; } @@ -7449,7 +7432,7 @@ DbgTypeMap::Entry* DbgModule::FindType(const char* typeName, DbgLanguage languag /*auto& typeMap = GetLinkedModule()->mTypeMap; auto dbgTypeEntry = typeMap.Find(typeName); if (dbgTypeEntry == NULL) - return NULL; + return NULL; if (dbgTypeEntry->mValue->mLanguage == language) return dbgTypeEntry; while (dbgTypeEntry != NULL) @@ -7478,7 +7461,6 @@ DbgType* DbgModule::GetPrimitiveStructType(DbgTypeCode typeCode) return FindType(name, NULL, DbgLanguage_Beef); } - DbgType* DbgModule::GetSizedArrayType(DbgType * elementType, int count) { auto linkedModule = GetLinkedModule(); @@ -7492,7 +7474,7 @@ DbgType* DbgModule::GetSizedArrayType(DbgType * elementType, int count) entry.mElementType = elementType; entry.mCount = count; if (mSizedArrayTypes.TryAdd(entry, NULL, &sizedArrayTypePtr)) - { + { BP_ALLOC_T(DbgType); auto sizedArrayType = mAlloc.Alloc(); sizedArrayType->mCompileUnit = elementType->mCompileUnit; @@ -7507,4 +7489,4 @@ DbgType* DbgModule::GetSizedArrayType(DbgType * elementType, int count) *sizedArrayTypePtr = sizedArrayType; } return *sizedArrayTypePtr; -} +} \ No newline at end of file diff --git a/IDEHelper/DbgModule.h b/IDEHelper/DbgModule.h index 830a25fa..edd59a56 100644 --- a/IDEHelper/DbgModule.h +++ b/IDEHelper/DbgModule.h @@ -31,7 +31,7 @@ enum DbgTypeCode : uint8 { DbgType_Void, DbgType_Root, - DbgType_Null, + DbgType_Null, DbgType_i8, DbgType_u8, DbgType_i16, @@ -80,10 +80,10 @@ enum DbgTypeCode : uint8 DbgType_Ptr, DbgType_PtrToMember, - DbgType_SizedArray, + DbgType_SizedArray, DbgType_Ref, DbgType_RValueReference, - DbgType_Const, + DbgType_Const, DbgType_Volatile, DbgType_Unaligned, DbgType_Restrict, @@ -107,9 +107,9 @@ enum DbgClassType : uint8 DbgClassType_CompileUnit, DbgClassType_Subprogram, DbgClassType_Type, - DbgClassType_Member, + DbgClassType_Member, DbgClassType_Block, - DbgClassType_Variable, + DbgClassType_Variable, }; enum DbgFileExistKind : uint8 @@ -117,7 +117,7 @@ enum DbgFileExistKind : uint8 DbgFileExistKind_NotChecked, DbgFileExistKind_NotFound, DbgFileExistKind_HasOldSourceCommand, - DbgFileExistKind_Found + DbgFileExistKind_Found }; enum DbgModuleKind : uint8 @@ -162,15 +162,15 @@ enum DbgLocationLenKind class DbgVariable : public DbgDebugData { public: - static const DbgClassType ClassType = DbgClassType_Variable; - + static const DbgClassType ClassType = DbgClassType_Variable; + const char* mName; const char* mLinkName; addr_target mRangeStart; int64 mConstValue; DbgType* mType; - const uint8* mLocationData; - int mRangeLen; + const uint8* mLocationData; + int mRangeLen; int mMemberOffset; int8 mLocationLen; uint8 mBitSize; @@ -180,9 +180,9 @@ public: bool mIsMember; bool mIsStatic; bool mIsConst; - bool mInAutoStaticMap; + bool mInAutoStaticMap; bool mSigNoPointer; // Signature was without pointer, mType has pointer - + addr_target mStaticCachedAddr; DbgVariable* mNext; @@ -218,14 +218,14 @@ typedef std::map > DwAsmDebugLineMap; class DbgBlock : public DbgDebugData { public: - static const DbgClassType ClassType = DbgClassType_Block; + static const DbgClassType ClassType = DbgClassType_Block; addr_target mLowPC; // If LowPC is -1 then mHighPC is index into debugRanges - addr_target mHighPC; + addr_target mHighPC; SLIList mVariables; SLIList mSubBlocks; - + DwAsmDebugLineMap* mAsmDebugLineMap; // empty unless inline asm is used DbgBlock* mNext; @@ -259,17 +259,17 @@ class DbgSubprogram; class DbgLineData { -public: +public: uint32 mRelAddress; int32 mLine; int16 mColumn; uint16 mContribSize; - uint16 mCtxIdx; + uint16 mCtxIdx; bool IsStackFrameSetup() { return mColumn != -2; - } + } }; struct DbgLineDataEx @@ -335,7 +335,7 @@ class DbgInlineeInfo { public: DbgSubprogram* mInlineParent; - DbgSubprogram* mRootInliner; + DbgSubprogram* mRootInliner; DbgLineData mFirstLineData; DbgLineData mLastLineData; uint32 mInlineeId; @@ -373,16 +373,16 @@ public: HotReplaceKind_Invalid = 3 // Mangles matched but arguments were incompatible }; - const char* mName; + const char* mName; const char* mLinkName; - int mTemplateNameIdx; - int mFrameBaseLen; + int mTemplateNameIdx; + int mFrameBaseLen; int mPrologueSize; const uint8* mFrameBaseData; DbgBlock mBlock; int mDeferredInternalsSize; int mVTableLoc; - int mStepFilterVersion; + int mStepFilterVersion; LocalBaseRegKind mParamBaseReg; LocalBaseRegKind mLocalBaseReg; bool mHasQualifiedName:1; @@ -390,14 +390,14 @@ public: bool mIsStepFilteredDefault:1; bool mVirtual:1; bool mHasThis:1; - bool mNeedLineDataFixup:1; + bool mNeedLineDataFixup:1; bool mIsOptimized:1; - bool mHasLineAddrGaps:1; // There are gaps of addresses which are not covered by lineinfo + bool mHasLineAddrGaps:1; // There are gaps of addresses which are not covered by lineinfo HotReplaceKind mHotReplaceKind; DbgLineInfo* mLineInfo; DbgInlineeInfo* mInlineeInfo; DbgType* mParentType; - DbgType* mReturnType; + DbgType* mReturnType; DbgMethodType mMethodType; BfProtection mProtection; BfCheckedKind mCheckedKind; @@ -409,13 +409,13 @@ public: DbgSubprogram() { mName = NULL; - mLinkName = NULL; + mLinkName = NULL; mHasThis = false; mNeedLineDataFixup = true; - mHotReplaceKind = HotReplaceKind_None; - mHasLineAddrGaps = false; + mHotReplaceKind = HotReplaceKind_None; + mHasLineAddrGaps = false; mPrologueSize = -1; - mParentType = NULL; + mParentType = NULL; mInlineeInfo = NULL; mFrameBaseData = NULL; mFrameBaseLen = 0; @@ -428,30 +428,30 @@ public: mStepFilterVersion = -1; } - ~DbgSubprogram(); - + ~DbgSubprogram(); + void ToString(StringImpl& str, bool internalName); String ToString(); - DbgLineData* FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram = NULL, DbgSrcFile** srcFile = NULL, int* outLineIdx = NULL); + DbgLineData* FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram = NULL, DbgSrcFile** srcFile = NULL, int* outLineIdx = NULL); DbgType* GetParent(); DbgType* GetTargetType(); // usually mParentType except for closures DbgLanguage GetLanguage(); - bool Equals(DbgSubprogram* checkMethod, bool allowThisMismatch = false); + bool Equals(DbgSubprogram* checkMethod, bool allowThisMismatch = false); int GetParamCount(); String GetParamName(int paramIdx); bool IsGenericMethod(); - bool ThisIsSplat(); + bool ThisIsSplat(); bool IsLambda(); DbgSubprogram* GetRootInlineParent() - { + { if (mInlineeInfo == NULL) return this; - return mInlineeInfo->mRootInliner; + return mInlineeInfo->mRootInliner; } int GetInlineDepth() - { + { int inlineDepth = 0; auto checkSubprogram = this; while (checkSubprogram->mInlineeInfo != NULL) @@ -464,7 +464,7 @@ public: return inlineDepth; } - addr_target GetLineAddr(const DbgLineData& lineData); + addr_target GetLineAddr(const DbgLineData& lineData); DbgSubprogram* GetLineInlinee(const DbgLineData& lineData); DbgSrcFile* GetLineSrcFile(const DbgLineData& lineData); bool HasValidLines(); @@ -481,7 +481,7 @@ public: class DbgExceptionDirectoryEntry { -public: +public: DbgExceptionDirectoryEntry* mNext; DbgModule* mDbgModule; addr_target mAddress; @@ -493,7 +493,7 @@ public: class DbgBaseTypeEntry { public: - DbgType* mBaseType; + DbgType* mBaseType; DbgBaseTypeEntry* mNext; int mThisOffset; int mVTableOffset; @@ -533,39 +533,39 @@ enum DbgExtType : int8 class DbgType : public DbgDebugData { public: - static const DbgClassType ClassType = DbgClassType_Type; - DbgType* mParent; + static const DbgClassType ClassType = DbgClassType_Type; + DbgType* mParent; BumpList mAlternates; // From other compile units DbgType* mPrimaryType; - - DbgTypeCode mTypeCode; + + DbgTypeCode mTypeCode; SLIList mBaseTypes; - DbgType* mTypeParam; - SLIList mMemberList; + DbgType* mTypeParam; + SLIList mMemberList; DbgType* mPtrType; - - DbgBlock* mBlockParam; + + DbgBlock* mBlockParam; SLIList mMethodNameList; - SLIList mMethodList; + SLIList mMethodList; SLIList mSubTypeList; BumpList mUsingNamespaces; - SLIList mHotReplacedMethodList; // Old methods + SLIList mHotReplacedMethodList; // Old methods DbgType* mHotNewType; // Only non-null during actual hotloading - + const char* mName; const char* mTypeName; intptr mSize; // In bytes - int mTemplateNameIdx; - int mAlign; + int mTemplateNameIdx; + int mAlign; int mTypeIdx; uint16 mDefinedMembersSize; - uint16 mMethodsWithParamsCount; + uint16 mMethodsWithParamsCount; bool mIsIncomplete:1; // Not fully loaded bool mIsPacked:1; bool mNeedsGlobalsPopulated:1; - bool mHasGlobalsPopulated:1; - bool mIsDeclaration:1; + bool mHasGlobalsPopulated:1; + bool mIsDeclaration:1; bool mHasStaticMembers:1; bool mHasVTable:1; bool mFixedName:1; @@ -575,20 +575,20 @@ public: bool mSizeCalculated; DbgType* mNext; - + public: DbgType(); - ~DbgType(); + ~DbgType(); //uint64 GetHash(); DbgType* ResolveTypeDef(); bool Equals(DbgType* dbgType); - + bool IsRoot(); bool IsNull(); bool IsVoid(); bool IsValuelessType(); - bool IsPrimitiveType(); + bool IsPrimitiveType(); bool IsStruct(); bool IsValueType(); bool IsTypedPrimitive(); @@ -598,8 +598,8 @@ public: bool IsChar(); bool IsChar(DbgLanguage language); bool IsNamespace(); - bool IsFloat(); - bool IsCompositeType(); + bool IsFloat(); + bool IsCompositeType(); bool WantsRefThis(); // Beef valuetypes want 'this' by ref, Objects and C++ want 'this' by pointer bool IsBfObjectPtr(); bool IsBfObject(); @@ -609,34 +609,34 @@ public: bool IsBfUnion(); bool HasCPPVTable(); bool IsBaseBfObject(); - bool IsInterface(); + bool IsInterface(); bool IsEnum(); - bool IsSigned(); + bool IsSigned(); bool IsRef(); bool IsConst(); - bool IsPointer(bool includeBfObjectPointer = true); - bool HasPointer(bool includeBfObjectPointer = true); + bool IsPointer(bool includeBfObjectPointer = true); + bool HasPointer(bool includeBfObjectPointer = true); bool IsPointerOrRef(bool includeBfObjectPointer = true); - bool IsSizedArray(); + bool IsSizedArray(); bool IsAnonymous(); bool IsGlobalsContainer(); - + DbgExtType CalcExtType(); DbgLanguage GetLanguage(); void FixName(); void PopulateType(); DbgModule* GetDbgModule(); - DbgType* GetUnderlyingType(); + DbgType* GetUnderlyingType(); DbgType* GetPrimaryType(); - DbgType* GetBaseType(); + DbgType* GetBaseType(); DbgType* GetRootBaseType(); - DbgType* RemoveModifiers(bool* hadRef = NULL); + DbgType* RemoveModifiers(bool* hadRef = NULL); String ToStringRaw(DbgLanguage language = DbgLanguage_Unknown); void ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName); String ToString(DbgLanguage language = DbgLanguage_Unknown, bool allowDirectBfObject = false); intptr GetByteCount(); intptr GetStride(); - int GetAlign(); + int GetAlign(); void EnsureMethodsMapped(); }; @@ -685,11 +685,11 @@ public: class DbgLineDataState : public DbgLineData { -public: +public: int mOpIndex; int mDiscriminator; - int mIsa; - bool mBasicBlock; + int mIsa; + bool mBasicBlock; bool mIsStmt; }; @@ -724,7 +724,7 @@ enum DbgHashKind class DbgSrcFile { -public: +public: String mFilePath; String mLocalPath; bool mHadLineData; @@ -733,10 +733,10 @@ public: int mStepFilterVersion; DbgHashKind mHashKind; uint8 mHash[32]; - DbgModule* mFirstLineDataDbgModule; // Just used to detect mHasLineDataFromMultipleModules + DbgModule* mFirstLineDataDbgModule; // Just used to detect mHasLineDataFromMultipleModules Array mDeferredRefs; Array mLineDataRefs; - Array mHotReplacedDbgLineInfo; // Indexing starts at -1 + Array mHotReplacedDbgLineInfo; // Indexing starts at -1 public: DbgSrcFile() @@ -747,15 +747,15 @@ public: mHashKind = DbgHashKind_None; mFileExistKind = DbgFileExistKind_NotChecked; mStepFilterVersion = 0; - + //mLineData.Reserve(64); } bool IsBeef(); ~DbgSrcFile(); - - void RemoveDeferredRefs(DbgModule* debugModule); + + void RemoveDeferredRefs(DbgModule* debugModule); void RemoveLines(DbgModule* debugModule); void RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced); void RehupLineData(); @@ -765,7 +765,7 @@ public: class DwCommonFrameDescriptor { -public: +public: DbgModule* mDbgModule; const char* mAugmentation; int mAugmentationLength; @@ -776,7 +776,7 @@ public: int mReturnAddressColumn; const uint8* mInstData; int mInstLen; - int mAddressPointerEncoding; + int mAddressPointerEncoding; addr_target mLSDARoutine; int mLSDAPointerEncodingFDE; @@ -789,13 +789,13 @@ public: mAugmentationLength = 0; mAddressPointerEncoding = 0; mLSDARoutine = 0; - mLSDAPointerEncodingFDE = 0; + mLSDAPointerEncodingFDE = 0; } }; class DwFrameDescriptor { -public: +public: addr_target mLowPC; addr_target mHighPC; const uint8* mInstData; @@ -808,7 +808,7 @@ public: DwFrameDescriptor() { mAddressPointerEncoding = 0; - mLSDARoutine = 0; + mLSDARoutine = 0; } }; @@ -819,33 +819,33 @@ class DbgCompileUnitContrib public: DbgCompileUnitContrib* mNext; DbgModule* mDbgModule; - addr_target mAddress; + addr_target mAddress; int mCompileUnitId; - int mLength; + int mLength; }; class DbgCompileUnit { public: - static const DbgClassType ClassType = DbgClassType_CompileUnit; + static const DbgClassType ClassType = DbgClassType_CompileUnit; - DbgModule* mDbgModule; + DbgModule* mDbgModule; DbgLanguage mLanguage; DbgBlock* mGlobalBlock; DbgType* mGlobalType; - Array mSrcFileRefs; + Array mSrcFileRefs; String mName; String mProducer; String mCompileDir; addr_target mLowPC; - addr_target mHighPC; + addr_target mHighPC; bool mNeedsLineDataFixup; - bool mWasHotReplaced; + bool mWasHotReplaced; bool mIsMaster; SLIList mOrphanMethods; -public: +public: DbgCompileUnit(DbgModule* dbgModule); virtual ~DbgCompileUnit() @@ -860,14 +860,14 @@ public: //int mDbgIdx; DbgSymbol() { - //mDbgIdx = ++gDbgSymbol_Idx; + //mDbgIdx = ++gDbgSymbol_Idx; } -public: - const char* mName; - addr_target mAddress; +public: + const char* mName; + addr_target mAddress; DbgModule* mDbgModule; - DbgSymbol* mNext; + DbgSymbol* mNext; }; class DbgSection @@ -969,8 +969,8 @@ struct DbgAutoStaticEntry class DbgHotTargetSection { public: - uint8* mData; - int mDataSize; + uint8* mData; + int mDataSize; addr_target mTargetSectionAddr; int mImageOffset; int mTargetSectionSize; @@ -985,18 +985,18 @@ public: { mData = NULL; mDataSize = 0; - mImageOffset = 0; + mImageOffset = 0; mTargetSectionAddr = 0; mTargetSectionSize = 0; mPointerToRelocations = 0; mNumberOfRelocations = 0; mCanExecute = false; mCanWrite = false; - mNoTargetAlloc = false; + mNoTargetAlloc = false; } ~DbgHotTargetSection() - { + { } }; @@ -1008,7 +1008,7 @@ struct DbgDeferredHotResolve { public: DbgHotTargetSection* mHotTargetSection; - String mName; + String mName; addr_target mNewAddr; COFFRelocation mReloc; }; @@ -1114,7 +1114,7 @@ public: MappedFile* mMappedImageFile; MemReporter* mMemReporter; - const uint8* mDebugLineData; + const uint8* mDebugLineData; const uint8* mDebugInfoData; const uint8* mDebugPubNames; const uint8* mDebugFrameData; @@ -1124,26 +1124,26 @@ public: addr_target mCodeAddress; const uint8* mDebugAbbrevData; const uint8* mDebugStrData; - const uint8** mDebugAbbrevPtrData; - Array mExceptionDirectory; + const uint8** mDebugAbbrevPtrData; + Array mExceptionDirectory; const uint8* mEHFrameData; - const char* mStringTable; + const char* mStringTable; const uint8* mSymbolData; addr_target mEHFrameAddress; addr_target mTLSAddr; addr_target mTLSExtraAddr; int mTLSSize; - int mTLSExtraSize; + int mTLSExtraSize; addr_target mTLSIndexAddr; DbgFlavor mDbgFlavor; bool mParsedGlobalsData; bool mParsedSymbolData; bool mParsedTypeData; - bool mPopulatedStaticVariables; - bool mParsedFrameDescriptors; + bool mPopulatedStaticVariables; + bool mParsedFrameDescriptors; - bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old + bool mMayBeOld; // If we had to load debug info from the SymCache or a SymServer then it may be old bool mDeleting; bool mFailed; int mId; @@ -1155,23 +1155,23 @@ public: int mStartSubprogramIdx; int mEndSubprogramIdx; int mStartTypeIdx; - int mEndTypeIdx; + int mEndTypeIdx; uintptr mPreferredImageBase; uintptr mImageBase; - uint32 mImageSize; + uint32 mImageSize; uintptr mEntryPoint; - String mVersion; + String mVersion; String* mFailMsgPtr; DbgType* mBfTypeType; intptr mBfTypesInfoAddr; DbgModuleMemoryCache* mOrigImageData; - DbgCompileUnit* mMasterCompileUnit; + DbgCompileUnit* mMasterCompileUnit; StrHashMap mGlobalVarMap; // Dedups entries into mMasterCompileUnit - BumpAllocator mAlloc; - + BumpAllocator mAlloc; + std::list mAsmDebugLineMaps; Array mSections; Dictionary mSecRelEncodingMap; @@ -1179,39 +1179,39 @@ public: bool mCheckedBfObject; bool mBfObjectHasFlags; DbgModuleKind mModuleKind; - bool mIsDwarf64; + bool mIsDwarf64; HashSet mSrcFileDeferredRefs; Array mSectionRVAs; SLIList mDeferredSymbols; Beefy::OwnedVector mDeferredHotResolveList; - Array mHotTargetSections; + Array mHotTargetSections; HashSet mHotPrimaryTypes; // List of types where we have entries in mHotReplacedMethodList DbgCompileUnit mDefaultCompileUnit; Dictionary mConstTypes; Dictionary mFileExistsCache; Dictionary mSizedArrayTypes; - + int mAllocSizeData; Array mOwnedSectionData; -public: +public: Array mEmptySrcFiles; - Array mCompileUnits; + Array mCompileUnits; Array mStaticVariables; DbgType* mCPrimitiveTypes[DbgType_COUNT]; DbgType* mBfPrimitiveTypes[DbgType_COUNT]; - const char* mPrimitiveStructNames[DbgType_COUNT]; + const char* mPrimitiveStructNames[DbgType_COUNT]; DbgTypeMap mTypeMap; Array mTypes; Array mSubprograms; - + StrHashMap mSymbolNameMap; std::unordered_map mStaticVariableMap; -public: +public: virtual void ParseGlobalsData(); virtual void ParseSymbolData(); virtual void ParseTypeData(); @@ -1219,8 +1219,8 @@ public: virtual void ParseCompileUnits() {} virtual void MapCompileUnitMethods(DbgCompileUnit* compileUnit); virtual void MapCompileUnitMethods(int compileUnitId); - virtual void PopulateType(DbgType* dbgType); - virtual void PopulateTypeGlobals(DbgType* dbgType); + virtual void PopulateType(DbgType* dbgType); + virtual void PopulateTypeGlobals(DbgType* dbgType); virtual void PopulateSubprogram(DbgSubprogram* dbgSubprogram) { } virtual void FixupInlinee(DbgSubprogram* dbgSubprogram) {} virtual void PopulateStaticVariableMap(); @@ -1232,7 +1232,7 @@ public: virtual addr_target LocateSymbol(const StringImpl& name) { return 0; } virtual DbgSubprogram* FindSubprogram(DbgType* dbgType, const char* methodName); const char* GetStringTable(DataStream* stream, int stringTablePos); - + virtual void Fail(const StringImpl& error); virtual void SoftFail(const StringImpl& error); virtual void HardFail(const StringImpl& error); @@ -1240,7 +1240,7 @@ public: void TempRemoveTemplateStr(const char*& name, int& templateNameIdx); void ReplaceTemplateStr(const char*& name, int& templateNameIdx); - char* DbgDupString(const char* str, const char* allocName = NULL); + char* DbgDupString(const char* str, const char* allocName = NULL); DbgModule* GetLinkedModule(); addr_target GetTargetImageBase(); addr_target RemapAddr(addr_target addr); @@ -1255,27 +1255,27 @@ public: void ParseDebugFrameData(); void ParseEHFrameData(); void FlushLineData(DbgSubprogram* curSubprogram, std::list& queuedLineData); - DbgSrcFile* AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath); + DbgSrcFile* AddSrcFile(DbgCompileUnit* compileUnit, const String& srcFilePath); void AddLineData(DbgCompileUnit* dwCompileUnit, DbgLineData& lineData, DbgSubprogram*& curSubProgram, std::list& queuedLineData); bool ParseDebugLineInfo(const uint8*& data, int compileUnitIdx); void FixupInnerTypes(int startingTypeIdx); - void MapTypes(int startingTypeIdx); - void CreateNamespaces(); + void MapTypes(int startingTypeIdx); + void CreateNamespaces(); bool IsObjectFile() { return mModuleKind != DbgModuleKind_Module; } bool IsHotSwapObjectFile() { return mModuleKind == DbgModuleKind_HotObject; } bool IsHotSwapPreserve(const String& name); - addr_target GetHotTargetAddress(DbgHotTargetSection* hotTargetSection); + addr_target GetHotTargetAddress(DbgHotTargetSection* hotTargetSection); uint8* GetHotTargetData(addr_target address); void DoReloc(DbgHotTargetSection* hotTargetSection, COFFRelocation& coffReloc, addr_target resolveSymbolAddr, PE_SymInfo* symInfo); void ParseHotTargetSections(DataStream* stream, addr_target* resovledSymbolAddrs); - void CommitHotTargetSections(); - void HotReplaceType(DbgType* newType); + void CommitHotTargetSections(); + void HotReplaceType(DbgType* newType); void ProcessHotSwapVariables(); virtual bool LoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge) { return false; } - virtual bool CheckSection(const char* name, uint8* sectionData, int sectionSize) { return false; } + virtual bool CheckSection(const char* name, uint8* sectionData, int sectionSize) { return false; } virtual void PreCacheImage() {} virtual void PreCacheDebugInfo() {} - virtual bool RequestImage() { return false; } + virtual bool RequestImage() { return false; } virtual bool HasPendingDebugInfo() { return false; } virtual bool RequestDebugInfo(bool allowRemote = true) { return false; } virtual bool WantsAutoLoadDebugInfo() { return false; } @@ -1286,7 +1286,7 @@ public: T ReadValue(const uint8*& data, int form, int refOffset = 0, const uint8** extraData = NULL, const uint8* startData = NULL); void EnableWriting(addr_target address); - void RevertWritingEnable(); + void RevertWritingEnable(); public: DbgModule(DebugTarget* debugTarget); @@ -1297,18 +1297,18 @@ public: bool ReadCOFF(DataStream* stream, DbgModuleKind dbgModuleKind); void RemoveTargetData(); virtual void ReportMemory(MemReporter* memReporter); - - int64 GetImageSize(); - virtual void FinishHotSwap(); + + int64 GetImageSize(); + virtual void FinishHotSwap(); addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue = NULL); virtual intptr EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None); //const uint8* CopyOrigImageData(addr_target address, int length); - + DbgType* FindTypeHelper(const String& typeName, DbgType* checkType); DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown, bool bfObjectPtr = false); DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language); - + DbgType* GetPointerType(DbgType* innerType); DbgType* GetConstType(DbgType* innerType); DbgType* GetPrimaryType(DbgType* dbgType); @@ -1326,7 +1326,7 @@ namespace std struct hash { size_t operator()(const NS_BF_DBG::DbgSizedArrayEntry& val) const - { + { return (size_t)val.mElementType ^ (val.mCount << 10); } }; diff --git a/IDEHelper/DbgSymSrv.cpp b/IDEHelper/DbgSymSrv.cpp index f15a0104..bb8d8517 100644 --- a/IDEHelper/DbgSymSrv.cpp +++ b/IDEHelper/DbgSymSrv.cpp @@ -19,13 +19,13 @@ USING_NS_BF_DBG; DbgSymRequest::DbgSymRequest() -{ +{ mFailed = false; mSearchingSymSrv = false; mCancelling = false; mInProcess = false; mLastUpdateTick = 0; - mDbgSymSrv = NULL; + mDbgSymSrv = NULL; mWantAge = 0; mMayBeOld = false; mIsPreCache = false; @@ -33,18 +33,17 @@ DbgSymRequest::DbgSymRequest() DbgSymRequest::~DbgSymRequest() { - } String DbgSymRequest::GetGuidString() { String str; - + // Seems like weird ordering, but the guid is really supposed to be (uint32, uint16, uint16, uint8[8]) - str += StrFormat("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + str += StrFormat("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", mWantGuid[3], mWantGuid[2], mWantGuid[1], mWantGuid[0], mWantGuid[5], mWantGuid[4], - mWantGuid[7], mWantGuid[6], + mWantGuid[7], mWantGuid[6], mWantGuid[8], mWantGuid[9], mWantGuid[10], mWantGuid[11], mWantGuid[12], mWantGuid[13], mWantGuid[14], mWantGuid[15]); return str; } @@ -87,7 +86,7 @@ bool DbgSymRequest::CheckPDBData(const StringImpl& pdbPath, uint8 outGuid[16], i { mDbgSymSrv->mDebugger->OutputMessage(StrFormat("ERROR: %s cannot be used due to age mismatch\n", pdbPath.c_str())); } - else + else { bool hasGuid = false; for (int i = 0; i < 16; i++) @@ -108,9 +107,9 @@ bool DbgSymRequest::CheckPDBData(const StringImpl& pdbPath, uint8 outGuid[16], i } bool DbgSymRequest::Get(const StringImpl& url, const StringImpl& destPath, NetResult** chainNetResult, bool ignoreSuccess) -{ +{ if (mIsPreCache) - { + { auto netResult = mDbgSymSrv->mDebugger->mDebugManager->mNetManager->QueueGet(url, destPath, true); if (chainNetResult != NULL) { @@ -121,7 +120,7 @@ bool DbgSymRequest::Get(const StringImpl& url, const StringImpl& destPath, NetRe } return false; } - + return mDbgSymSrv->mDebugger->mDebugManager->mNetManager->Get(url, destPath); } @@ -144,7 +143,7 @@ void DbgSymRequest::SearchLocal() return; } - // Check in same dir as module + // Check in same dir as module String checkPath = ::GetFileDir(mModulePath); checkPath += "\\"; checkPath += GetFileName(mPDBRequested); @@ -157,7 +156,7 @@ void DbgSymRequest::SearchLocal() } } } - + mMayBeOld = true; } @@ -206,12 +205,12 @@ void DbgSymRequest::SearchSymSrv() /*if (mPDBRequested.Contains("IDEHelper")) Sleep(3000);*/ - SetAndRestoreValue prevSearchingSymSrv(mSearchingSymSrv, true); + SetAndRestoreValue prevSearchingSymSrv(mSearchingSymSrv, true); NetResult* chainNetResult = NULL; uint8 outGuid[16]; int32 outAge; - + String cacheDir = mOptions.mCacheDir; cacheDir += GetPDBStoreDir(); @@ -244,7 +243,7 @@ void DbgSymRequest::SearchSymSrv() checkPath += GetFileName(mPDBRequested); if (Get(checkPath, cacheFilePath, &chainNetResult)) done = true; - + if ((!done) && (!mCancelling)) { // Compressed version @@ -264,7 +263,7 @@ void DbgSymRequest::SearchSymSrv() } done = true; } - } + } if ((!done) && (!mCancelling)) { @@ -312,7 +311,7 @@ void DbgSymRequest::SearchSymSrv() if (mIsPreCache) continue; - // Re-check cache + // Re-check cache if (CheckPDBData(cacheFilePath, outGuid, outAge)) { mFinalPDBPath = cacheFilePath; @@ -329,12 +328,12 @@ bool DbgSymRequest::CheckPEFile(const StringImpl& filePath, uint32 fileTime, int if (!fs.Open(filePath, "rb")) return false; - + PEHeader hdr; fs.ReadT(hdr); - - PE_NTHeaders64 ntHdr64; - fs.SetPos(hdr.e_lfanew); + + PE_NTHeaders64 ntHdr64; + fs.SetPos(hdr.e_lfanew); fs.Read(&ntHdr64, sizeof(PE_NTHeaders64)); if (ntHdr64.mFileHeader.mMachine == PE_MACHINE_X64) { @@ -349,12 +348,12 @@ bool DbgSymRequest::CheckPEFile(const StringImpl& filePath, uint32 fileTime, int if ((ntHdr32.mFileHeader.mTimeDateStamp != fileTime) || (ntHdr32.mOptionalHeader.mSizeOfImage != size)) return false; } - + return true; } String DbgSymRequest::SearchForImage(const String& filePath, uint32 fileTime, int size) -{ +{ if ((gDebugManager->mSymSrvOptions.mFlags & BfSymSrvFlag_Disable) != 0) return ""; @@ -371,15 +370,15 @@ String DbgSymRequest::SearchForImage(const String& filePath, uint32 fileTime, in { mFailed = true; return ""; - } + } NetResult* chainNetResult = NULL; String fileName = GetFileName(filePath); String imageStoreDir = "/"; imageStoreDir += fileName; - imageStoreDir += "/"; - imageStoreDir += StrFormat("%08X%x/", fileTime, size); + imageStoreDir += "/"; + imageStoreDir += StrFormat("%08X%x/", fileTime, size); SetAndRestoreValue prevSearchingSymSrv(mSearchingSymSrv, true); @@ -400,7 +399,7 @@ String DbgSymRequest::SearchForImage(const String& filePath, uint32 fileTime, in if (CheckPEFile(cacheFilePath, fileTime, size)) { return cacheFilePath; - } + } for (auto& symServAddr : mOptions.mSymbolServers) { @@ -466,7 +465,7 @@ String DbgSymRequest::SearchForImage(const String& filePath, uint32 fileTime, in checkPath += imageStoreDir; checkPath += fileName; if (CheckPEFile(checkPath, fileTime, size)) - { + { return checkPath; } @@ -490,14 +489,14 @@ String DbgSymRequest::SearchForImage(const String& filePath, uint32 fileTime, in // Re-check cache if (CheckPEFile(cacheFilePath, fileTime, size)) { - return cacheFilePath; + return cacheFilePath; } } if (!mIsPreCache) { - mDbgSymSrv->mDebugger->mHadImageFindError = true; - mDbgSymSrv->mDebugger->OutputMessage(StrFormat("ERROR: Unable to locate image '%s' (%08X%x). If this file is located on a symbol server, configure the symbol server location in File\\Preferences\\Settings under Debugger\\Symbol File Locations.\n", + mDbgSymSrv->mDebugger->mHadImageFindError = true; + mDbgSymSrv->mDebugger->OutputMessage(StrFormat("ERROR: Unable to locate image '%s' (%08X%x). If this file is located on a symbol server, configure the symbol server location in File\\Preferences\\Settings under Debugger\\Symbol File Locations.\n", GetFileName(filePath).c_str(), fileTime, size)); } @@ -526,7 +525,7 @@ bool DbgSymRequest::IsDone() DbgSymSrv::DbgSymSrv(Debugger* debugger) { - mDebugger = debugger; + mDebugger = debugger; } void DbgSymSrv::PreCacheImage(const String& filePath, uint32 fileTime, int size) @@ -558,7 +557,7 @@ DbgSymRequest* DbgSymSrv::CreateRequest() DbgSymRequest* symRequest = new DbgSymRequest(); symRequest->mOptions = mDebugger->mDebugManager->mSymSrvOptions; - symRequest->mDbgSymSrv = this; + symRequest->mDbgSymSrv = this; return symRequest; } @@ -569,6 +568,4 @@ void DbgSymSrv::ReleaseRequest(DbgSymRequest* dbgSymRequest) void DbgSymSrv::Update() { - -} - +} \ No newline at end of file diff --git a/IDEHelper/DbgTypeMap.cpp b/IDEHelper/DbgTypeMap.cpp index bda5749d..74eb0f91 100644 --- a/IDEHelper/DbgTypeMap.cpp +++ b/IDEHelper/DbgTypeMap.cpp @@ -81,7 +81,7 @@ USING_NS_BF; // char cIn; // do { cIn = *(inPtr++); } while (cIn == ' '); // char cMap; -// do { cMap = *(mapPtr++); } while (cMap == ' '); +// do { cMap = *(mapPtr++); } while (cMap == ' '); // if (cIn != cMap) // { // if ((cIn == '`') || (cIn == '\'')) @@ -136,7 +136,7 @@ USING_NS_BF; //} // //void DbgTypeMap::Insert(DbgType* value) -//{ +//{ // if (mHashHeads == NULL) // mHashHeads = (Entry**)mAlloc.AllocBytes(sizeof(Entry*) * HashSize, alignof(Entry*)); // @@ -157,7 +157,7 @@ USING_NS_BF; //} // //DbgTypeMap::Entry* DbgTypeMap::Find(const char* name, DbgLanguage language) -//{ +//{ // if (language == DbgLanguage_BeefUnfixed) // { // std::string str = name; @@ -184,7 +184,7 @@ USING_NS_BF; // // Find our way to the end and remove the star // int chevCount = 0; // for (char* cTestPtr = cPtr - 1; cTestPtr >= name; cTestPtr--) -// { +// { // char c = *cTestPtr; // if (c == 0) // break; @@ -217,7 +217,7 @@ USING_NS_BF; // } // } // } -// +// // if (nameStart != NULL) // { // if (strncmp(nameStart, "System.Array1", 13) == 0) @@ -376,7 +376,7 @@ bool DbgTypeMap::StrEqual(const char* inStr, const char* mapStr) } DbgTypeMap::Entry* DbgTypeMap::Find(const char* name, DbgLanguage language) -{ +{ if (language == DbgLanguage_BeefUnfixed) { std::string str = name; @@ -395,7 +395,7 @@ DbgTypeMap::Entry* DbgTypeMap::Find(const char* name, DbgLanguage language) // Find our way to the end and remove the star int chevCount = 0; for (char* cTestPtr = cPtr - 1; cTestPtr >= name; cTestPtr--) - { + { char c = *cTestPtr; if (c == 0) break; @@ -428,7 +428,7 @@ DbgTypeMap::Entry* DbgTypeMap::Find(const char* name, DbgLanguage language) } } } - + if (nameStart != NULL) { if (strncmp(nameStart, "System.Array1", 13) == 0) @@ -470,15 +470,15 @@ DbgTypeMap::Entry* DbgTypeMap::Find(const char* name, DbgLanguage language) int hashCode = GetHash(name, language) & 0x7FFFFFFF; for (int i = mMap.mBuckets[hashCode % mMap.mAllocSize]; i >= 0; i = mMap.mEntries[i].mNext) - { + { if (mMap.mEntries[i].mHashCode == hashCode) { - Entry* entry = (Entry*)&mMap.mEntries[i].mKey; + Entry* entry = (Entry*)&mMap.mEntries[i].mKey; if (StrEqual(name, entry->mValue->mName)) return entry; } } - + return NULL; } @@ -490,4 +490,4 @@ Beefy::HashSet::iterator DbgTypeMap::begin() Beefy::HashSet::iterator DbgTypeMap::end() { return mMap.end(); -} +} \ No newline at end of file diff --git a/IDEHelper/DebugManager.cpp b/IDEHelper/DebugManager.cpp index 58c706df..09cf16a1 100644 --- a/IDEHelper/DebugManager.cpp +++ b/IDEHelper/DebugManager.cpp @@ -80,7 +80,7 @@ DebugManager::DebugManager() mStepOverExternalFiles = false; mDebugger32 = NULL; - mDebugger64 = NULL; + mDebugger64 = NULL; mNetManager = new NetManager(); mNetManager->mDebugManager = this; @@ -106,12 +106,11 @@ DebugManager::~DebugManager() delete mNetManager; delete mDebugger64; - delete mDebugger32; + delete mDebugger32; /*for (auto stepFilter : mStepFilters) { - }*/ - delete mDebugVisualizers; + delete mDebugVisualizers; } void DebugManager::OutputMessage(const StringImpl& msg) @@ -144,7 +143,6 @@ void DebugManager::SetSourceServerCacheDir() #endif } - //#define CAPTURE_ALLOC_BACKTRACE //#define CAPTURE_ALLOC_SOURCES @@ -153,7 +151,7 @@ const int sNumAllocAddrs = 0x300000; const int sCaptureDepth = 14; const int sCaptureOffset = 4; static intptr gAllocAddrs[sNumAllocAddrs][sCaptureDepth]; -#endif +#endif #ifdef CAPTURE_ALLOC_SOURCES #include @@ -191,7 +189,7 @@ static void ReallocEntry(long oldRequest, long newRequest, int newSize) entry->mAllocSize = newSize; gBfCaptureSourceAllocMap[newRequest] = *entry; gBfCaptureSourceAllocMap.erase(itr); - } + } } static void RemoveAllocEntry(long lRequest) @@ -203,13 +201,11 @@ static void RemoveAllocEntry(long lRequest) entry->mLoc->mTotalSize -= entry->mAllocSize; gBfCaptureSourceAllocMap.erase(itr); - } + } } - //const LOC_HASHES - #endif static int gBfNumAllocs = 0; @@ -246,7 +242,7 @@ static int BfAllocHook(int nAllocType, void *pvData, if (hProcess == NULL) { hProcess = GetCurrentProcess(); - BOOL worked = SymInitialize(hProcess, NULL, TRUE); + BOOL worked = SymInitialize(hProcess, NULL, TRUE); } if (nAllocType == _HOOK_ALLOC) @@ -317,7 +313,6 @@ static int BfAllocHook(int nAllocType, void *pvData, if ((captureAllocLoc->mIsEndpoint) && (foundSym)) { - } gHashCaptureAllocSize[hashVal] = captureAllocLoc; @@ -330,7 +325,6 @@ static int BfAllocHook(int nAllocType, void *pvData, continue; } - captureAllocLoc->mTotalSize += (int)nSize; CaptureAllocEntry entry; @@ -433,19 +427,18 @@ static int BfAllocHook(int nAllocType, void *pvData, #endif //BF_PLATFORM_WINDOWS - void BfReportMemory() { BfLogDbg("Used: %.2fM NumAllocs: %d Allocs: %.2fM\n", (gBfAllocCount - gBfFreeCount) / (1024.0 * 1024.0), gBfNumAllocs, gBfAllocCount / (1024.0 * 1024.0)); } void BfFullReportMemory() -{ +{ /*OutputDebugStrF("Testing OOB\n"); char* str = new char[12]; delete str; char c = str[1];*/ - + if (gBfParserCache != NULL) { MemReporter memReporter; @@ -457,7 +450,7 @@ void BfFullReportMemory() OutputDebugStrF("Used: %.2fM NumAllocs: %d Allocs: %.2fM\n", (gBfAllocCount - gBfFreeCount) / (1024.0 * 1024.0), gBfNumAllocs, gBfAllocCount / (1024.0 * 1024.0)); OutputDebugStrF("ChunkedDataBuffer allocated blocks: %d\n", ChunkedDataBuffer::sBlocksAllocated); - + if (gDebugManager != NULL) { MemReporter memReporter; @@ -493,7 +486,7 @@ void BfFullReportMemory() for (auto kv : byNameMap) { - //OutputDebugStrF("%dk %s\n", (kv.second + 1023) / 1024, kv.first.c_str()); + //OutputDebugStrF("%dk %s\n", (kv.second + 1023) / 1024, kv.first.c_str()); bySizeMap.insert(std::multimap::value_type(-kv.second, kv.first)); } @@ -528,7 +521,7 @@ struct _CrtMemBlockHeader //static _CrtMemBlockHeader* __acrt_last_block; void ShowMemoryUsage() -{ +{ #ifdef BF_PLATFORM_WINDOWS PROCESS_MEMORY_COUNTERS processMemCounters; processMemCounters.cb = sizeof(PROCESS_MEMORY_COUNTERS); @@ -538,7 +531,7 @@ void ShowMemoryUsage() static bool hasCheckpoint = true; _CrtMemState memState; - _CrtMemCheckpoint(&memState); + _CrtMemCheckpoint(&memState); //OutputDebugStrF("Crt Size: %dk\n", (int)(memState.lTotalCount / 1024)); char* names[6] = { "_FREE_BLOCK", "_NORMAL_BLOCK", "_CRT_BLOCK", "_IGNORE_BLOCK", "_CLIENT_BLOCK", "_MAX_BLOCKS" }; @@ -546,7 +539,7 @@ void ShowMemoryUsage() { OutputDebugStrF("%s : %d %dk\n", names[i], memState.lCounts[i], memState.lSizes[i] / 1024); } - + #ifdef _DEBUG // int64 totalCrtSize = 0; // int64 totalUseCrtSize = 0; @@ -568,9 +561,9 @@ void ShowMemoryUsage() while ((heapStatus = _heapwalk(&heapInfo)) == _HEAPOK) { heapSize += (int64)heapInfo._size; - } + } OutputDebugStrF("WALKED HEAP SIZE: %dk\n", heapSize / 1024); - + //_CrtMemDumpStatistics(&memState); #endif } @@ -591,9 +584,7 @@ BOOL WINAPI DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) -{ - - +{ if (dwReason == DLL_PROCESS_ATTACH) { BpInit("127.0.0.1", "Beef IDE"); @@ -638,13 +629,13 @@ namespace BeefyDbg64 static _CrtMemState gStartMemCheckpoint; #endif BF_EXPORT void BF_CALLTYPE Debugger_Create() -{ +{ //TODO: Very slow, remove //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF); //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_EVERY_16_DF); //TODO: _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_EVERY_16_DF*/); //_CrtSetAllocHook(BfAllocHook); - + #ifdef BF_PLATFORM_WINDOWS _CrtMemCheckpoint(&gStartMemCheckpoint); #endif @@ -661,7 +652,7 @@ BF_EXPORT void BF_CALLTYPE Debugger_Create() gDebugManager->mDebugger64 = NULL; #else gDebugManager->mDebugger64 = CreateDebugger64(gDebugManager, NULL); -#endif +#endif #ifdef BF_PLATFORM_WINDOWS ::AllowSetForegroundWindow(ASFW_ANY); @@ -672,12 +663,11 @@ BF_EXPORT void BF_CALLTYPE Debugger_Create() BF_EXPORT void BF_CALLTYPE Debugger_SetCallbacks(void* callback) { - } BF_EXPORT void BF_CALLTYPE Debugger_FullReportMemory() { - //WdAllocTest(); + //WdAllocTest(); ShowMemoryUsage(); BfFullReportMemory(); } @@ -777,7 +767,7 @@ BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* launchPath, const char* Array envBlock; if (envBlockPtr != NULL) - { + { if (envBlockSize != 0) envBlock.Insert(0, (uint8*)envBlockPtr, envBlockSize); } @@ -787,7 +777,7 @@ BF_EXPORT bool BF_CALLTYPE Debugger_OpenFile(const char* launchPath, const char* } BF_EXPORT bool BF_CALLTYPE Debugger_ComptimeAttach(void* bfCompiler) -{ +{ gDebugger = new CeDebugger(gDebugManager, (BfCompiler*)bfCompiler); return true; } @@ -808,12 +798,12 @@ BF_EXPORT void BF_CALLTYPE Debugger_SetSymSrvOptions(const char* symCacheDir, co if (!symStr.IsEmpty()) symServers.Add(symStr); startStr = cPtr; - } + } if (*cPtr == 0) break; } - + AutoCrit autoCrit(gDebugManager->mCritSect); gDebugManager->mSymSrvOptions.mCacheDir = symCacheDir; @@ -834,12 +824,11 @@ BF_EXPORT void BF_CALLTYPE Debugger_SetSymSrvOptions(const char* symCacheDir, co } gDebugManager->SetSourceServerCacheDir(); - } BF_EXPORT bool BF_CALLTYPE Debugger_OpenMiniDump(const char* fileName) { -#ifdef BF_PLATFORM_WINDOWS +#ifdef BF_PLATFORM_WINDOWS DbgMiniDump* dbgMiniDump = new DbgMiniDump(); bool result = dbgMiniDump->StartLoad(fileName); if (!result) @@ -847,7 +836,6 @@ BF_EXPORT bool BF_CALLTYPE Debugger_OpenMiniDump(const char* fileName) delete dbgMiniDump; return false; } - if (dbgMiniDump->GetTargetBitCount() == 32) gDebugger = CreateDebugger32(gDebugManager, dbgMiniDump); @@ -875,7 +863,7 @@ BF_EXPORT bool BF_CALLTYPE Debugger_Attach(int processId, BfDbgAttachFlags attac gDebugger = gDebugManager->mDebugger32; return true; } - + return false; } @@ -886,7 +874,7 @@ BF_EXPORT void BF_CALLTYPE Debugger_Run() BF_EXPORT bool BF_CALLTYPE Debugger_HotLoad(const char* fileNamesStr, int hotIdx) { - //DbgModule* dwarf = new DbgModule(gDebugger); + //DbgModule* dwarf = new DbgModule(gDebugger); //dwarf->ReadPE(fileName); Array fileNames; @@ -919,8 +907,8 @@ BF_EXPORT bool BF_CALLTYPE Debugger_HotLoad(const char* fileNamesStr, int hotIdx BF_EXPORT bool BF_CALLTYPE Debugger_LoadDebugVisualizers(const char* fileName) { String fn = fileName; - bool worked = false; - worked = gDebugManager->mDebugVisualizers->Load(fileName); + bool worked = false; + worked = gDebugManager->mDebugVisualizers->Load(fileName); if (!gDebugManager->mDebugVisualizers->mErrorString.empty()) { gDebugManager->mOutMessages.push_back(StrFormat("msg ERROR: %s\n", gDebugManager->mDebugVisualizers->mErrorString.c_str())); @@ -999,7 +987,7 @@ BF_EXPORT void BF_CALLTYPE Breakpoint_HotBindBreakpoint(Breakpoint* breakpoint, BF_EXPORT void BF_CALLTYPE Breakpoint_SetThreadId(Breakpoint* breakpoint, intptr threadId) { - BfLogDbg("Breakpoint %p set ThreadId=%d\n", breakpoint, threadId); + BfLogDbg("Breakpoint %p set ThreadId=%d\n", breakpoint, threadId); breakpoint->mThreadId = threadId; gDebugger->CheckBreakpoint(breakpoint); } @@ -1064,19 +1052,19 @@ BF_EXPORT void BF_CALLTYPE Breakpoint_Disable(Breakpoint* wdBreakpoint) BF_EXPORT void BF_CALLTYPE Debugger_CreateStepFilter(const char* filter, bool isGlobal, BfStepFilterKind filterKind) { - AutoCrit autoCrit(gDebugManager->mCritSect); + AutoCrit autoCrit(gDebugManager->mCritSect); StepFilter stepFilter; stepFilter.mFilterKind = filterKind; gDebugManager->mStepFilters[filter] = stepFilter; - gDebugManager->mStepFilterVersion++; + gDebugManager->mStepFilterVersion++; } BF_EXPORT void BF_CALLTYPE StepFilter_Delete(const char* filter) { - AutoCrit autoCrit(gDebugManager->mCritSect); + AutoCrit autoCrit(gDebugManager->mCritSect); bool didRemove = gDebugManager->mStepFilters.Remove(filter); BF_ASSERT(didRemove); - + gDebugManager->mStepFilterVersion++; } @@ -1110,7 +1098,7 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_PopMessage() BF_EXPORT bool BF_CALLTYPE Debugger_HasMessages() { AutoCrit autoCrit(gDebugManager->mCritSect); - return gDebugManager->mOutMessages.size() != 0; + return gDebugManager->mOutMessages.size() != 0; } BF_EXPORT const char* BF_CALLTYPE Debugger_GetCurrentException() @@ -1177,7 +1165,7 @@ BF_EXPORT void BF_CALLTYPE Debugger_SetDisplayTypes(const char* referenceId, con displayInfo = &gDebugManager->mDefaultDisplayInfo; else gDebugManager->mDisplayInfos.TryAdd(referenceId, NULL, &displayInfo); - + if (formatStr != NULL) displayInfo->mFormatStr = formatStr; displayInfo->mIntDisplayType = (DwIntDisplayType)intDisplayType; @@ -1246,11 +1234,11 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_EvaluateContinue() BF_EXPORT void BF_CALLTYPE Debugger_EvaluateContinueKeep() { auto debugger = gDebugger; - debugger->EvaluateContinueKeep(); + debugger->EvaluateContinueKeep(); } BF_EXPORT StringView BF_CALLTYPE Debugger_Evaluate(const char* expr, int callStackIdx, int cursorPos, int32 language, uint16 expressionFlags) -{ +{ auto debugger = gDebugger; if (debugger == NULL) @@ -1291,39 +1279,37 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_EvaluateAtAddress(const char* expr, i BF_EXPORT const char* BF_CALLTYPE Debugger_GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) { - String& outString = *gTLStrReturn.Get(); + String& outString = *gTLStrReturn.Get(); outString = gDebugger->GetAutoExpressions(callStackIdx, memoryRangeStart, memoryRangeLen); return outString.c_str(); } BF_EXPORT const char* BF_CALLTYPE Debugger_GetAutoLocals(int callStackIdx, bool showRegs) { - String& outString = *gTLStrReturn.Get(); + String& outString = *gTLStrReturn.Get(); outString = gDebugger->GetAutoLocals(callStackIdx, showRegs); return outString.c_str(); } BF_EXPORT const char* BF_CALLTYPE Debugger_CompactChildExpression(const char* expr, const char* parentExpr, int callStackIdx) { - String& outString = *gTLStrReturn.Get(); + String& outString = *gTLStrReturn.Get(); outString = gDebugger->CompactChildExpression(expr, parentExpr, callStackIdx); return outString.c_str(); } BF_EXPORT const char* BF_CALLTYPE Debugger_GetCollectionContinuation(const char* continuationData, int callStackIdx, int count) { - String& outString = *gTLStrReturn.Get(); + String& outString = *gTLStrReturn.Get(); outString = gDebugger->GetCollectionContinuation(continuationData, callStackIdx, count); return outString.c_str(); } - BF_EXPORT void BF_CALLTYPE Debugger_ForegroundTarget() { gDebugger->ForegroundTarget(); - - //BOOL worked = EnumThreadWindows(gDebugger->mProcessInfo.dwThreadId, WdEnumWindowsProc, 0); + //BOOL worked = EnumThreadWindows(gDebugger->mProcessInfo.dwThreadId, WdEnumWindowsProc, 0); //BF_ASSERT(worked); } @@ -1394,7 +1380,7 @@ BF_EXPORT int BF_CALLTYPE CallStack_GetBreakStackFrameIdx() BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameInfo(int stackFrameIdx, intptr* addr, const char** outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) -{ +{ String& outString = *gTLStrReturn.Get(); String& outString2 = *gTLStrReturn2.Get(); @@ -1413,7 +1399,7 @@ BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameId(int stackFrameIdx) BF_EXPORT const char* BF_CALLTYPE Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) { String& outString = *gTLStrReturn.Get(); - outString = gDebugger->Callstack_GetStackFrameOldFileInfo(stackFrameIdx); + outString = gDebugger->Callstack_GetStackFrameOldFileInfo(stackFrameIdx); return outString.c_str(); } @@ -1531,7 +1517,7 @@ BF_EXPORT int BF_CALLTYPE Debugger_LoadDebugInfoForModuleWith(const char* module } BF_EXPORT void BF_CALLTYPE Debugger_SetStepOverExternalFiles(bool stepOverExternalFiles) -{ +{ gDebugManager->mStepOverExternalFiles = stepOverExternalFiles; gDebugManager->mStepFilterVersion++; } @@ -1552,7 +1538,7 @@ BF_EXPORT Profiler* BF_CALLTYPE Debugger_StartProfiling(intptr threadId, char* d Profiler* profiler = gDebugger->StartProfiling(); profiler->mTargetThreadId = threadId; if (desc != NULL) - profiler->mDescription = desc; + profiler->mDescription = desc; profiler->mSamplesPerSecond = sampleRate; profiler->Start(); return profiler; @@ -1560,7 +1546,7 @@ BF_EXPORT Profiler* BF_CALLTYPE Debugger_StartProfiling(intptr threadId, char* d BF_EXPORT Profiler* BF_CALLTYPE Debugger_PopProfiler() { - Profiler* profiler = gDebugger->PopProfiler(); + Profiler* profiler = gDebugger->PopProfiler(); return profiler; } @@ -1570,7 +1556,6 @@ BF_EXPORT void BF_CALLTYPE Debugger_InitiateHotResolve(int flags) gDebugger->InitiateHotResolve((DbgHotResolveFlags)flags); } - BF_EXPORT intptr BF_CALLTYPE Debugger_GetDbgAllocHeapSize() { AutoCrit autoCrit(gDebugManager->mCritSect); @@ -1580,7 +1565,7 @@ BF_EXPORT intptr BF_CALLTYPE Debugger_GetDbgAllocHeapSize() BF_EXPORT const char* BF_CALLTYPE Debugger_GetDbgAllocInfo() { AutoCrit autoCrit(gDebugManager->mCritSect); - + String& outString = *gTLStrReturn.Get(); outString = gDebugger->GetDbgAllocInfo(); return outString.c_str(); @@ -1640,7 +1625,7 @@ BF_EXPORT NetResult* HTTP_GetFile(char* url, char* destPath) { AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect); - auto netResult = gDebugManager->mNetManager->QueueGet(url, destPath, false); + auto netResult = gDebugManager->mNetManager->QueueGet(url, destPath, false); netResult->mDoneEvent = new SyncEvent(); return netResult; } @@ -1674,7 +1659,7 @@ BF_EXPORT void HTTP_Delete(NetResult* netResult) netResult->mCurRequest->Cancel(); } netResult->mDoneEvent->WaitFor(-1); - } + } delete netResult; } @@ -1738,12 +1723,12 @@ BF_EXPORT void BF_CALLTYPE TimeTest(uint32 startTime) } BF_EXPORT void BF_CALLTYPE BFTest() -{ +{ struct DeferredResolveEntry2 { BfFieldDef* mFieldDef; int mTypeArrayIdx; - }; + }; DeferredResolveEntry2 entry = { NULL, 333 }; @@ -1752,10 +1737,10 @@ BF_EXPORT void BF_CALLTYPE BFTest() vec.push_back(DeferredResolveEntry2 { NULL, 222 } ); } -/// +/// -// __attribute__((weak)) +// __attribute__((weak)) // Debugger* Beefy::CreateDebugger32(DebugManager* debugManager, DbgMiniDump* miniDump) // { // return NULL; -// } +// } \ No newline at end of file diff --git a/IDEHelper/DebugManager.h b/IDEHelper/DebugManager.h index 2f8658b9..2c3ce576 100644 --- a/IDEHelper/DebugManager.h +++ b/IDEHelper/DebugManager.h @@ -44,7 +44,7 @@ public: StepFilter() { // Set global / local - mFilterKind = BfStepFilterKind_Filtered; + mFilterKind = BfStepFilterKind_Filtered; } bool IsFiltered(bool defaultValue) @@ -65,11 +65,11 @@ class DebugManager { public: Debugger* mDebugger32; - Debugger* mDebugger64; + Debugger* mDebugger64; CritSect mCritSect; Dictionary mStepFilters; - int mStepFilterVersion; + int mStepFilterVersion; std::deque mOutMessages; DebugVisualizers* mDebugVisualizers; diff --git a/IDEHelper/DebugTarget.cpp b/IDEHelper/DebugTarget.cpp index 6e25838d..f79a26ae 100644 --- a/IDEHelper/DebugTarget.cpp +++ b/IDEHelper/DebugTarget.cpp @@ -30,22 +30,22 @@ DebugTarget::DebugTarget(WinDebugger* debugger) mCapturedNamesPtr = NULL; mCapturedTypesPtr = NULL; mHotHeap = NULL; - mLastHotHeapCleanIdx = 0; + mLastHotHeapCleanIdx = 0; mIsEmpty = false; mWasLocallyBuilt = false; mCurModuleId = 0; - + /*dbgType = new DbgType(); dbgType->mName = "int"; dbgType->mTypeCode = DbgType_i32; dbgType->mSize = 4; - mPrimitiveTypes[DbgType_i32] = dbgType;*/ + mPrimitiveTypes[DbgType_i32] = dbgType;*/ } DebugTarget::~DebugTarget() { for (auto dwarf : mDbgModules) - delete dwarf; + delete dwarf; for (auto& dwSrcFilePair : mSrcFiles) delete dwSrcFilePair.mValue; @@ -63,7 +63,7 @@ static bool PathEquals(const String& pathA, String& pathB) { char cA = *(ptrA++); char cB = *(ptrB++); - + if ((cA == 0) || (cB == 0)) { return (cA == 0) && (cB == 0); @@ -91,7 +91,7 @@ void DebugTarget::SetupTargetBinary() #else if (wantsHotHeap) { - // 64-bit hot loaded code needs to be placed close to the original EXE so 32-bit relative + // 64-bit hot loaded code needs to be placed close to the original EXE so 32-bit relative // offsets within the hot code can still reach the old code addr_target checkHotReserveAddr = (addr_target)mTargetBinary->mImageBase + mTargetBinary->mImageSize; int mb = 1024 * 1024; @@ -104,7 +104,7 @@ void DebugTarget::SetupTargetBinary() addr_target reservedPtr = NULL; while ((addr_target)checkHotReserveAddr < (addr_target)mTargetBinary->mImageBase + 0x30000000) - { + { reservedPtr = (addr_target)VirtualAllocEx(mDebugger->mProcessInfo.hProcess, (void*)(intptr)checkHotReserveAddr, reserveSize, MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (reservedPtr != NULL) break; @@ -129,7 +129,7 @@ void DebugTarget::CheckTargetBinary(DbgModule* module) if (mTargetBinary != NULL) return; if (!PathEquals(module->mFilePath, mTargetPath)) - return; + return; mTargetBinary = module; if (mTargetBinary != mLaunchBinary) SetupTargetBinary(); @@ -150,7 +150,7 @@ DbgModule* DebugTarget::Init(const StringImpl& launchPath, const StringImpl& tar return NULL; } - DbgModule* dwarf = new COFF(this); + DbgModule* dwarf = new COFF(this); mLaunchBinary = dwarf; dwarf->mDisplayName = GetFileName(launchPath); dwarf->mFilePath = launchPath; @@ -190,15 +190,15 @@ DbgModule* DebugTarget::HotLoad(const StringImpl& fileName, int hotIdx) } DbgModule* dwarf = new COFF(this); - dwarf->mHotIdx = hotIdx; + dwarf->mHotIdx = hotIdx; dwarf->mDisplayName = GetFileName(fileName); dwarf->mFilePath = fileName; if (!dwarf->ReadCOFF(&fileStream, DbgModuleKind_HotObject)) { mDebugger->OutputMessage(StrFormat("Debugger failed to read binary: %s\n", fileName.c_str())); - delete dwarf; + delete dwarf; return NULL; - } + } AddDbgModule(dwarf); return dwarf; } @@ -206,7 +206,7 @@ DbgModule* DebugTarget::HotLoad(const StringImpl& fileName, int hotIdx) DbgModule* DebugTarget::SetupDyn(const StringImpl& filePath, DataStream* stream, intptr imageBase) { BP_ZONE("DebugTarget::SetupDyn"); - + AutoDbgTime dbgTime("DebugTarget::SetupDyn " + filePath); DbgModule* dwarf = new COFF(this); @@ -240,12 +240,12 @@ String DebugTarget::UnloadDyn(addr_target imageBase) String filePath; AutoDbgTime dbgTime("DebugTarget::UnloadDyn"); - + for (int i = 0; i < (int)mDbgModules.size(); i++) { DbgModule* dwarf = mDbgModules[i]; if (dwarf->mImageBase == imageBase) - { + { dwarf->mDeleting = true; dwarf->RemoveTargetData(); RemoveTargetData(); @@ -253,7 +253,7 @@ String DebugTarget::UnloadDyn(addr_target imageBase) if (mTargetBinary == dwarf) mTargetBinary = NULL; - + mDbgModules.RemoveAt(i); bool success = mDbgModuleMap.Remove(dwarf->mId); BF_ASSERT_REL(success); @@ -261,7 +261,7 @@ String DebugTarget::UnloadDyn(addr_target imageBase) delete dwarf; return filePath; } - } + } return ""; } @@ -282,9 +282,9 @@ void DebugTarget::CleanupHotHeap() Beefy::OutputDebugStrF("Clearing hot module %p data from %@ to %@\n", dbgModule, dbgModule->mImageBase, dbgModule->mImageBase + dbgModule->mImageSize); BfLogDbg("Unloading hot idx: %s@%d\n", dbgModule->mFilePath.c_str(), dbgModule->mHotIdx); - dbgModule->mDeleting = true; - dbgModule->RemoveTargetData(); - hadRemovals = true; + dbgModule->mDeleting = true; + dbgModule->RemoveTargetData(); + hadRemovals = true; } } } @@ -296,15 +296,15 @@ void DebugTarget::CleanupHotHeap() { DbgModule* dbgModule = mDbgModules[dwarfIdx]; if (dbgModule->mDeleting) - { + { mDbgModules.RemoveAt(dwarfIdx); bool success = mDbgModuleMap.Remove(dbgModule->mId); BF_ASSERT_REL(success); delete dbgModule; dwarfIdx--; } - } - } + } + } } void DebugTarget::RehupSrcFiles() @@ -349,11 +349,11 @@ DbgSrcFile* DebugTarget::GetSrcFile(const String& srcFilePath) } bool DebugTarget::FindSymbolAt(addr_target addr, String* outSymbol, addr_target* outOffset, DbgModule** outDWARF, bool allowRemote) -{ +{ //TODO: First search for symbol, then determine if the addr is within the defining DbgModule DbgModule* insideDWARF = NULL; - + auto dbgModule = FindDbgModuleForAddress(addr); if (dbgModule != NULL) dbgModule->ParseSymbolData(); @@ -363,7 +363,7 @@ bool DebugTarget::FindSymbolAt(addr_target addr, String* outSymbol, addr_target* { dbgModule = dwSymbol->mDbgModule; } - + if (dbgModule == NULL) return false; @@ -375,7 +375,7 @@ bool DebugTarget::FindSymbolAt(addr_target addr, String* outSymbol, addr_target* for (int i = 0; i < (int)dbgModule->mSections.size(); i++) { auto section = &dbgModule->mSections[i]; - + if ((addr >= section->mAddrStart + dbgModule->mImageBase) && (addr < section->mAddrStart + dbgModule->mImageBase + section->mAddrLength)) { if (dbgModule->HasPendingDebugInfo()) @@ -383,9 +383,9 @@ bool DebugTarget::FindSymbolAt(addr_target addr, String* outSymbol, addr_target* if (dbgModule->WantsAutoLoadDebugInfo()) { DbgPendingDebugInfoLoad* dbgPendingDebugInfoLoad = NULL; - mDebugger->mPendingDebugInfoLoad.TryAdd(dbgModule, NULL, &dbgPendingDebugInfoLoad); + mDebugger->mPendingDebugInfoLoad.TryAdd(dbgModule, NULL, &dbgPendingDebugInfoLoad); dbgPendingDebugInfoLoad->mModule = dbgModule; - dbgPendingDebugInfoLoad->mAllowRemote |= allowRemote; + dbgPendingDebugInfoLoad->mAllowRemote |= allowRemote; } } @@ -413,7 +413,7 @@ bool DebugTarget::FindSymbolAt(addr_target addr, String* outSymbol, addr_target* if (outSymbol != NULL) { - *outSymbol = dwSymbol->mName; + *outSymbol = dwSymbol->mName; } if (outOffset != NULL) *outOffset = addr - dwSymbol->mAddress; @@ -444,7 +444,7 @@ bool DebugTarget::GetValueByName(DbgSubprogram* subProgram, const StringImpl& na BP_ZONE("DebugTarget::GetValueByName"); //BF_ASSERT(*outAddrType == DbgAddrType_None); - + String checkName = name; if (subProgram != NULL) @@ -477,7 +477,7 @@ void DebugTarget::AddAutoStaticEntry(const DbgAutoStaticEntry& entry) while (remainingSize > 0) { int bucketIndex = -1; - + /*auto map_iter = mAutoStaticEntryBucketMap.find((addr_target)curPage); if (map_iter != mAutoStaticEntryBucketMap.end())*/ @@ -610,14 +610,14 @@ void DebugTarget::GetAutoValueNames(DbgAutoValueMapType& outAutos, WdStackFrame* auto subProgram = dbgModule->mSubprograms[subProgramIdx]; GetAutoValueNamesInBlock(outAutos, subProgram, &subProgram->mBlock, stackFrame, memoryRangeStart, memoryRangeLen); } - + for (auto compileUnit : dbgModule->mCompileUnits) { GetAutoValueNamesInBlock(outAutos, NULL, compileUnit->mGlobalBlock, stackFrame, memoryRangeStart, memoryRangeLen); - } + } } - std::function iterFunc = [this, &outAutos](const DbgAutoStaticEntry& entry) + std::function iterFunc = [this, &outAutos](const DbgAutoStaticEntry& entry) { //outAutos.insert(DbgAutoValueMapType::value_type(entry.mFullName, DbgAutoValueMapType::value_type::second_type(entry.mAddrStart, entry.mAddrLen))); outAutos.TryAdd(entry.mFullName, std::make_pair(entry.mAddrStart, entry.mAddrLen)); @@ -713,7 +713,7 @@ bool DebugTarget::GetAutoLocalsInBlock(Array& outLocals, DbgSubprogram* { auto dwarf = dwSubprogram->mCompileUnit->mDbgModule; if (dwBlock->mLowPC == -1) - { + { //Debug ranges addr_target* rangeData = (addr_target*)(dwarf->mDebugRangesData + dwBlock->mHighPC); while (true) @@ -733,7 +733,7 @@ bool DebugTarget::GetAutoLocalsInBlock(Array& outLocals, DbgSubprogram* for (auto subBlock : dwBlock->mSubBlocks) { - GetAutoLocalsInBlock(outLocals, dwSubprogram, subBlock, stackFrame, dwLineData); + GetAutoLocalsInBlock(outLocals, dwSubprogram, subBlock, stackFrame, dwLineData); } if (dwBlock == &dwSubprogram->mBlock) @@ -763,14 +763,13 @@ bool DebugTarget::GetAutoLocalsInBlock(Array& outLocals, DbgSubprogram* return true; } - DbgSubprogram* DebugTarget::FindSubProgram(addr_target pc, DbgOnDemandKind onDemandKind) { BP_ZONE("WinDebugger::FindSubProgram"); - + for (int pass = 0; pass < 2; pass++) { - int mapBlockSize = 1 << DbgRadixMap::BLOCK_SHIFT; + int mapBlockSize = 1 << DbgRadixMap::BLOCK_SHIFT; DbgSubprogram* foundSubprogram = NULL; @@ -812,7 +811,6 @@ DbgSubprogram* DebugTarget::FindSubProgram(addr_target pc, DbgOnDemandKind onDem } else { - }*/ return dwSubprogram; @@ -827,11 +825,11 @@ DbgSubprogram* DebugTarget::FindSubProgram(addr_target pc, DbgOnDemandKind onDem if (pass != 0) return NULL; - + DbgCompileUnitContrib* contrib = mContribMap.Get(pc, DBG_MAX_LOOKBACK); if ((contrib != NULL) && (pc >= contrib->mAddress) && (pc < contrib->mAddress + contrib->mLength)) - { - contrib->mDbgModule->ParseCompileUnit(contrib->mCompileUnitId); + { + contrib->mDbgModule->ParseCompileUnit(contrib->mCompileUnitId); } else if (onDemandKind != DbgOnDemandKind_None) { @@ -857,7 +855,7 @@ DbgSubprogram* DebugTarget::FindSubProgram(addr_target pc, DbgOnDemandKind onDem } if (module->RequestDebugInfo(onDemandKind == DbgOnDemandKind_AllowRemote)) - { + { // Give another chance to ParseCompileUnit and then match again found = true; pass = -1; @@ -912,7 +910,7 @@ void DebugTarget::GetCompilerSettings() } void DebugTarget::AddDbgModule(DbgModule* dbgModule) -{ +{ dbgModule->mId = ++mCurModuleId; mDbgModules.Add(dbgModule); bool success = mDbgModuleMap.TryAdd(dbgModule->mId, dbgModule); @@ -944,7 +942,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR struct EntryHeader { - uint8 mVersion; + uint8 mVersion; uint8 mPrologSize; uint8 mNumUnwindCodes; uint8 mFrameRegister; @@ -962,7 +960,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR //BF_ASSERT(version == 1); //uint8 prologSize = GET(uint8); - //uint8 numUnwindCodes = GET(uint8); + //uint8 numUnwindCodes = GET(uint8); int dataSize = entryHeader.mNumUnwindCodes * 2; @@ -976,14 +974,12 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR uint8 dataBuf[512]; dbgModule->mOrigImageData->Read(dbgModule->mImageBase + exceptionPos + sizeof(EntryHeader), dataBuf, dataSize); const uint8* data = dataBuf; - + if (flags & 1) // UNW_FLAG_EHANDLER { - } else if (flags & 4) // UNW_FLAG_CHAININFO { - } /*if (pcAddress < exceptionDirectoryEntry->mAddress + prologSize) @@ -999,16 +995,16 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR uint8 frameRegisterOffset = frameRegister >> 4; frameRegister &= 15; - intptr_target newSP = 0; + intptr_target newSP = 0; const uint8* paramAreaStart = data; const uint8* dataEnd = data + entryHeader.mNumUnwindCodes * 2; while (data < dataEnd) - { + { uint8 offsetInProlog = GET(uint8); uint8 unwindOpCode = GET(uint8); uint8 opInfo = unwindOpCode >> 4; - unwindOpCode &= 15; + unwindOpCode &= 15; bool executeOp = pcAddress >= exceptionDirectoryEntry->mAddress - exceptionDirectoryEntry->mOrigAddressOffset + offsetInProlog; @@ -1024,7 +1020,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR { // UWOP_ALLOC_LARGE int allocSize = 0; - if (opInfo == 0) + if (opInfo == 0) allocSize = (int)GET(uint16) * 8; else if (opInfo == 1) allocSize = (int)GET(int32); @@ -1034,7 +1030,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR else if ((unwindOpCode == 2) && (executeOp)) { // UWOP_ALLOC_SMALL - int allocSize = (int)opInfo * 8 + 8; + int allocSize = (int)opInfo * 8 + 8; *regSP += allocSize; } else if ((unwindOpCode == 3) && (executeOp)) @@ -1096,7 +1092,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR alreadyRolledBackPC = true; if (opInfo == 0) - { + { addr_target regRIP; gDebugger->ReadMemory(*regSP, sizeof(intptr_target), ®RIP); // RIP (correct back trace) *regSP += sizeof(intptr_target); @@ -1124,11 +1120,9 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR *regSP += 6 * sizeof(intptr_target); } } - - } - // Note: RCX/RDX are reversed + // Note: RCX/RDX are reversed } if (flags & 4) // UNW_FLAG_CHAININFO @@ -1146,7 +1140,6 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR return RollBackStackFrame_ExceptionDirectory(dbgModule->mImageBase + chainedRVAStart, registers, outReturnAddressLoc, alreadyRolledBackPC); } - return true; } @@ -1175,7 +1168,7 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi struct EntryHeader { - uint8 mVersion; + uint8 mVersion; uint8 mPrologSize; uint8 mNumUnwindCodes; uint8 mFrameRegister; @@ -1204,11 +1197,9 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi if (flags & 1) // UNW_FLAG_EHANDLER { - } else if (flags & 4) // UNW_FLAG_CHAININFO { - } /*if (pcAddress < exceptionDirectoryEntry->mAddress + prologSize) @@ -1224,16 +1215,16 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi uint8 frameRegisterOffset = frameRegister >> 4; frameRegister &= 15; - intptr_target newSP = 0; + intptr_target newSP = 0; const uint8* paramAreaStart = data; const uint8* dataEnd = data + entryHeader.mNumUnwindCodes * 2; while (data < dataEnd) - { + { uint8 offsetInProlog = GET(uint8); uint8 unwindOpCode = GET(uint8); uint8 opInfo = unwindOpCode >> 4; - unwindOpCode &= 15; + unwindOpCode &= 15; bool executeOp = pcAddress >= exceptionDirectoryEntry->mAddress - exceptionDirectoryEntry->mOrigAddressOffset + offsetInProlog; @@ -1245,14 +1236,14 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi { mDebugger->WriteMemory(regSP, regRef, sizeof(intptr_target)); wasSaved = true; - } + } regSP += sizeof(intptr_target); } else if (unwindOpCode == 1) { // UWOP_ALLOC_LARGE int allocSize = 0; - if (opInfo == 0) + if (opInfo == 0) allocSize = (int)GET(uint16) * 8; else if (opInfo == 1) allocSize = (int)GET(int32); @@ -1262,7 +1253,7 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi else if ((unwindOpCode == 2) && (executeOp)) { // UWOP_ALLOC_SMALL - int allocSize = (int)opInfo * 8 + 8; + int allocSize = (int)opInfo * 8 + 8; regSP += allocSize; } else if ((unwindOpCode == 3) && (executeOp)) @@ -1336,9 +1327,9 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi // UWOP_PUSH_MACHFRAME if (executeOp) - { + { if (opInfo == 0) - { + { //addr_target regRIP; //gDebugger->ReadMemory(*regSP, sizeof(intptr_target), ®RIP); // RIP (correct back trace) regSP += sizeof(intptr_target); @@ -1366,11 +1357,9 @@ bool DebugTarget::PropogateRegisterUpCallStack_ExceptionDirectory(addr_target fi regSP += 6 * sizeof(intptr_target); } } - - } - // Note: RCX/RDX are reversed + // Note: RCX/RDX are reversed } if (flags & 4) // UNW_FLAG_CHAININFO @@ -1410,22 +1399,19 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR uint8 version = GET(uint8); uint8 flags = (version >> 3); version &= 7; - + uint8 prologSize = GET(uint8); uint8 numUnwindCodes = GET(uint8); if (exceptionDirectoryEntry->mAddress - dbgModule->mImageBase == 0x0000000000048efc) { - } if (flags & 1) // UNW_FLAG_EHANDLER { - } else if (flags & 4) // UNW_FLAG_CHAININFO { - } /*if (pcAddress < exceptionDirectoryEntry->mAddress + prologSize) @@ -1434,38 +1420,38 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR return false; }*/ - addr_target* regSP = registers->GetSPRegisterRef(); + addr_target* regSP = registers->GetSPRegisterRef(); int regFPOffset = 0; uint8 frameRegister = GET(uint8); uint8 frameRegisterOffset = frameRegister >> 4; frameRegister &= 15; - intptr_target newSP = 0; + intptr_target newSP = 0; const uint8* paramAreaStart = data; const uint8* dataEnd = data + numUnwindCodes * 2; while (data < dataEnd) - { + { uint8 offsetInProlog = GET(uint8); uint8 unwindOpCode = GET(uint8); uint8 opInfo = unwindOpCode >> 4; - unwindOpCode &= 15; + unwindOpCode &= 15; bool executeOp = pcAddress >= exceptionDirectoryEntry->mAddress - exceptionDirectoryEntry->mOrigAddressOffset + offsetInProlog; if ((unwindOpCode == 0) && (executeOp)) { - // UWOP_PUSH_NONVOL + // UWOP_PUSH_NONVOL intptr_target* regRef = registers->GetExceptionRegisterRef(opInfo); gDebugger->ReadMemory(*regSP, sizeof(intptr_target), regRef); - *regSP += sizeof(intptr_target); + *regSP += sizeof(intptr_target); } else if (unwindOpCode == 1) { // UWOP_ALLOC_LARGE int allocSize = 0; - if (opInfo == 0) + if (opInfo == 0) allocSize = (int)GET(uint16) * 8; else if (opInfo == 1) allocSize = (int)GET(int32); @@ -1475,7 +1461,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR else if ((unwindOpCode == 2) && (executeOp)) { // UWOP_ALLOC_SMALL - int allocSize = (int)opInfo * 8 + 8; + int allocSize = (int)opInfo * 8 + 8; *regSP += allocSize; } else if ((unwindOpCode == 3) && (executeOp)) @@ -1530,7 +1516,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR BF_ASSERT(0 == "Not supported"); } - // Note: RCX/RDX are reversed + // Note: RCX/RDX are reversed } if (flags & 4) // UNW_FLAG_CHAININFO @@ -1548,7 +1534,6 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR return RollBackStackFrame_ExceptionDirectory(dbgModule->mImageBase + chainedRVAStart, registers, outReturnAddressLoc); } - return true; } @@ -1558,7 +1543,7 @@ bool DebugTarget::RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPUR bool DebugTarget::RollBackStackFrame_ExceptionDirectory(CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC) { - addr_target pcAddress = (addr_target)registers->GetPC(); + addr_target pcAddress = (addr_target)registers->GetPC(); return RollBackStackFrame_ExceptionDirectory(registers->GetPC(), registers, outReturnAddressLoc, alreadyRolledBackPC); } @@ -1583,7 +1568,7 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, auto dwFrameDescriptor = &stackFrameItr->second; if (pcAddress > dwFrameDescriptor->mHighPC) return false; - + struct RegisterRuleData { public: @@ -1621,9 +1606,9 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, State rootState; rootState.mRegisterRuleDataIdx = DwarfReg_SP; - State* state = &rootState; + State* state = &rootState; - // Set up default rule to restore stack pointer + // Set up default rule to restore stack pointer state->mRegisterRuleDataArray[state->mRegisterRuleDataIdx].mRegisterRule = DW_CFA_val_offset; state->mRegisterRuleDataArray[state->mRegisterRuleDataIdx].mParamOffset = 0; @@ -1656,7 +1641,7 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, else { switch (opCode) - { + { case DW_CFA_advance_loc1: curLoc += GET(uint8) * dwFrameDescriptor->mCommonFrameDescriptor->mCodeAlignmentFactor; break; @@ -1719,7 +1704,7 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, { int regNum = (int)DecodeULEB128(data); BF_ASSERT(regNum < CPURegisters::kNumIntRegs); - int blockLen = (int)DecodeULEB128(data); + int blockLen = (int)DecodeULEB128(data); auto registerRuleData = &state->mRegisterRuleDataArray[regNum]; registerRuleData->mRegisterRule = DW_CFA_expression; registerRuleData->mParamOffset = blockLen; @@ -1826,7 +1811,7 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers int stackPos = 0; COFFFrameProgram::Command stackCmds[8]; addr_target stackValues[8]; - addr_target temps[4]; + addr_target temps[4]; auto _GetValue = [&](int stackPos) { @@ -1901,7 +1886,7 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers if (cmd == COFFFrameProgram::Command_None) break; switch (cmd) - { + { case COFFFrameProgram::Command_EIP: case COFFFrameProgram::Command_ESP: case COFFFrameProgram::Command_EBP: @@ -1916,9 +1901,9 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers case COFFFrameProgram::Command_RASearch: if (stackPos >= 8) return false; - stackCmds[stackPos++] = cmd; + stackCmds[stackPos++] = cmd; break; - case COFFFrameProgram::Command_Add: + case COFFFrameProgram::Command_Add: { if (stackPos < 2) return false; @@ -1938,7 +1923,7 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers stackPos -= 2; stackValues[stackPos] = lhs - rhs; stackCmds[stackPos++] = COFFFrameProgram::Command_Value; - } + } break; case COFFFrameProgram::Command_Align: { @@ -1949,10 +1934,10 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers stackPos -= 2; stackValues[stackPos] = BF_ALIGN(lhs, rhs); stackCmds[stackPos++] = COFFFrameProgram::Command_Value; - } + } break; case COFFFrameProgram::Command_Set: - { + { if (stackPos < 2) return false; addr_target rhs = _GetValue(stackPos - 1); @@ -2002,15 +1987,15 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers } break; case COFFFrameProgram::Command_Deref: - { + { if (stackPos < 1) return false; - addr_target addr = _GetValue(stackPos - 1); + addr_target addr = _GetValue(stackPos - 1); stackPos--; stackValues[stackPos] = mDebugger->ReadMemory(addr); stackCmds[stackPos++] = COFFFrameProgram::Command_Value; } - break; + break; case COFFFrameProgram::Command_Value: { if (stackPos >= 8) @@ -2054,9 +2039,9 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe { if (outReturnAddressLoc != NULL) *outReturnAddressLoc = 0; - + CPUInst inst; - if (DecodeInstruction(registers->GetPC(), &inst)) + if (DecodeInstruction(registers->GetPC(), &inst)) { if (inst.IsReturn()) { @@ -2066,7 +2051,7 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe } } -#ifdef BF_DBG_32 +#ifdef BF_DBG_32 if (RollBackStackFrame_DwFrameDescriptor(registers, outReturnAddressLoc)) return true; if (RollBackStackFrame_COFFFrameDescriptor(registers, outReturnAddressLoc, isStackStart)) @@ -2077,7 +2062,7 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe { if (pc == dbgSubprogram->mBlock.mLowPC) return RollBackStackFrame_SimpleRet(registers); - + auto dbgModule = dbgSubprogram->mCompileUnit->mDbgModule; if ((dbgModule != NULL) && (!dbgModule->mParsedFrameDescriptors)) { @@ -2087,7 +2072,7 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe } } else - { + { return RollBackStackFrame_SimpleRet(registers); } #endif @@ -2107,7 +2092,7 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe if (alreadyRolledBackPC) return true; -#ifdef BF_DBG_32 +#ifdef BF_DBG_32 // Try rollback assuming a frame pointer addr_target newPC = 0; addr_target stackFrame = registers->GetBP(); @@ -2174,7 +2159,7 @@ int DebugTarget::GetFrameBaseRegister(DbgSubprogram* dwSubprogram) } } -#ifdef BF_DBG_32 +#ifdef BF_DBG_32 if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) return X86Reg_EBP; else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) @@ -2187,7 +2172,7 @@ int DebugTarget::GetFrameBaseRegister(DbgSubprogram* dwSubprogram) return X64Reg_R13; return X64Reg_RBP; #endif - + return -1; } @@ -2217,9 +2202,6 @@ bool DebugTarget::GetVariableIndexRegisterAndOffset(DbgVariable* dwVariable, int //int64 BfDebuggerReadMemory(int64 addr); - - - addr_target DebugTarget::GetStaticAddress(DbgVariable* dwVariable) { DbgAddrType addrType; @@ -2288,7 +2270,7 @@ bool DebugTarget::GetValueByNameInBlock_Helper(DbgSubprogram* dwSubprogram, DbgB *outType = dwSubprogram->mCompileUnit->mDbgModule->GetConstType(*outType); } }; - + for (int varIdx = (int)checkVars.size() - 1; varIdx >= 0; varIdx--) { auto variable = checkVars[varIdx]; @@ -2349,7 +2331,7 @@ bool DebugTarget::GetValueByNameInBlock_Helper(DbgSubprogram* dwSubprogram, DbgB return false; *outAddr = variable->mCompileUnit->mDbgModule->EvaluateLocation(dwSubprogram, variable->mLocationData, variable->mLocationLen, stackFrame, outAddrType); - + _FixParam(variable); return true; @@ -2361,7 +2343,7 @@ bool DebugTarget::GetValueByNameInBlock_Helper(DbgSubprogram* dwSubprogram, DbgB if (dwBlock == &dwSubprogram->mBlock) { for (auto variable : dwSubprogram->mParams) - { + { if (variable->mName == NULL) continue; @@ -2435,22 +2417,20 @@ bool DebugTarget::GetValueByNameInBlock(DbgSubprogram* dwSubprogram, DbgBlock* d if (GetValueByNameInBlock(dwSubprogram, subBlock, name, stackFrame, outAddr, outType, outAddrType)) return true; } - + if (GetValueByNameInBlock_Helper(dwSubprogram, dwBlock, name, stackFrame, outAddr, outType, outAddrType)) return true; - - + return false; } - const DbgMemoryFlags DebugTarget::ReadOrigImageData(addr_target address, uint8* data, int size) { for (auto dwarf : mDbgModules) { - if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize) && (dwarf->mOrigImageData != NULL)) - { - return dwarf->mOrigImageData->Read(address, data, size); + if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize) && (dwarf->mOrigImageData != NULL)) + { + return dwarf->mOrigImageData->Read(address, data, size); } //return dbgModule->mOrigImageData + (address - dbgModule->mImageBase); } @@ -2463,13 +2443,12 @@ bool DebugTarget::DecodeInstruction(addr_target address, CPUInst* inst) for (auto dwarf : mDbgModules) { if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize) && (dwarf->mOrigImageData != NULL)) - { + { return mDebugger->mCPU->Decode(address, dwarf->mOrigImageData, inst); } } return false; - } DbgBreakKind DebugTarget::GetDbgBreakKind(addr_target address, CPURegisters* registers, intptr_target* objAddr) @@ -2477,14 +2456,13 @@ DbgBreakKind DebugTarget::GetDbgBreakKind(addr_target address, CPURegisters* reg for (auto dwarf : mDbgModules) { if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize) && (dwarf->mOrigImageData != NULL)) - { + { auto result = mDebugger->mCPU->GetDbgBreakKind(address, dwarf->mOrigImageData, registers->mIntRegsArray, objAddr); - return result; + return result; } } return DbgBreakKind_None; - } DbgModule* DebugTarget::FindDbgModuleForAddress(addr_target address) @@ -2499,7 +2477,7 @@ DbgModule* DebugTarget::FindDbgModuleForAddress(addr_target address) } DbgModule* DebugTarget::GetMainDbgModule() -{ +{ return mTargetBinary; } @@ -2527,12 +2505,12 @@ void ReportRadixMap(MemReporter* memReporter, RadixMap64& radixMap) auto mid = radixMap.mRoot[rootIdx]; if (mid != NULL) { - memReporter->Add(sizeof(RadixMap64::Mid)); + memReporter->Add(sizeof(RadixMap64::Mid)); for (int midIdx = 0; midIdx < RadixMap64::MID_LENGTH; midIdx++) { auto leaf = mid->mLeafs[midIdx]; if (leaf != NULL) - { + { memReporter->Add(sizeof(RadixMap64::Leaf)); } } @@ -2614,7 +2592,6 @@ struct VectorRemoveCtx mVec->RemoveRange(mMatchStartIdx, (int)mVec->size() - mMatchStartIdx); mFinished = true; } - }; void DebugTarget::RemoveTargetData() @@ -2638,11 +2615,11 @@ void DebugTarget::RemoveTargetData() problemModule = node->mDbgModule; //OutputDebugStrF("Should have been removed by DbgModule::RemoveTargetData %@ %s\n", node->mAddress, node->mName); BF_DBG_FATAL("Should have been removed by DbgModule::RemoveTargetData"); - mSymbolMap.Remove(node); + mSymbolMap.Remove(node); } node = next; } - } + } if (problemModule != NULL) { @@ -2672,13 +2649,13 @@ void DebugTarget::RemoveTargetData() { auto next = node->mNext; if (node->mDbgModule->mDeleting) - { + { //BF_DBG_FATAL("Should have been removed by DbgModule::RemoveTargetData"); mExceptionDirectoryMap.Remove(node); } node = next; } - } + } #endif VectorRemoveCtx> cieRemoveCtx(mCommonFrameDescriptors); @@ -2698,4 +2675,4 @@ void DebugTarget::RemoveTargetData() else ++frameDescItr; } -} +} \ No newline at end of file diff --git a/IDEHelper/DebugTarget.h b/IDEHelper/DebugTarget.h index 0a486ee8..6a616c7f 100644 --- a/IDEHelper/DebugTarget.h +++ b/IDEHelper/DebugTarget.h @@ -23,13 +23,13 @@ class DebugTarget public: WinDebugger* mDebugger; - DbgRadixMap mSymbolMap; + DbgRadixMap mSymbolMap; DbgAutoStaticEntryBucketMap mAutoStaticEntryBucketMap; Array > mAutoStaticEntryBuckets; DbgRadixMap mSubprogramMap; DbgRadixMap mExceptionDirectoryMap; DbgRadixMap mContribMap; - + Array* mCapturedNamesPtr; Array* mCapturedTypesPtr; @@ -37,17 +37,17 @@ public: int mLastHotHeapCleanIdx; String mTargetPath; DbgModule* mLaunchBinary; - DbgModule* mTargetBinary; + DbgModule* mTargetBinary; Array mDbgModules; Dictionary mDbgModuleMap; HashSet mPendingSrcFileRehup; // Waiting to remove old/invalid line info - - BumpAllocator mAlloc; + + BumpAllocator mAlloc; bool mWasLocallyBuilt; bool mIsEmpty; bool mCheckedCompilerSettings; bool mBfObjectHasFlags; - bool mBfObjectHasVDataExtender; + bool mBfObjectHasVDataExtender; bool mBfHasLargeStrings; bool mBfHasLargeCollections; int mBfObjectVDataIntefaceSlotCount; @@ -57,11 +57,11 @@ public: Array mCommonFrameDescriptors; std::map mDwFrameDescriptorMap; std::map mCOFFFrameDescriptorMap; - + Dictionary mSrcFiles; Dictionary mLocalToOrigSrcMap; -protected: +protected: bool RollBackStackFrame_ExceptionDirectory(addr_target findPC, CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC); bool RollBackStackFrame_ExceptionDirectory(CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC); bool RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, addr_target* outReturnAddressLoc); @@ -74,7 +74,7 @@ protected: public: DebugTarget(WinDebugger* debugger); ~DebugTarget(); - + void AddDbgModule(DbgModule* dbgModule); DbgModule* Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase = 0); void SetupTargetBinary(); @@ -89,8 +89,8 @@ public: DbgSrcFile* GetSrcFile(const String& srcFilePath); bool FindSymbolAt(addr_target addr, String* outSymbol, addr_target* outOffset = NULL, DbgModule** outDWARF = NULL, bool allowRemote = true); - addr_target FindSymbolAddr(const StringImpl& name); - + addr_target FindSymbolAddr(const StringImpl& name); + addr_target GetStaticAddress(DbgVariable* dwVariable); DbgSubprogram* FindSubProgram(addr_target address, DbgOnDemandKind onDemandKind = DbgOnDemandKind_AllowRemote); void GetCompilerSettings(); @@ -103,7 +103,7 @@ public: bool GetValueByNameInBlock(DbgSubprogram* dwSubprogram, DbgBlock* dwBlock, String& name, WdStackFrame* stackFrame, intptr* outAddr, DbgType** outType, DbgAddrType* outAddrType); void GetAutoValueNames(DbgAutoValueMapType& outAutos, WdStackFrame* stackFrame, uint64 memoryRangeStart, uint64 memoryRangeLen); void GetAutoValueNamesInBlock(DbgAutoValueMapType& outAutos, DbgSubprogram* dwSubprogram, DbgBlock* dwBlock, WdStackFrame* stackFrame, uint64 memoryRangeStart, uint64 memoryRangeLen); - bool GetAutoLocalsInBlock(Array& outLocals, DbgSubprogram* dwSubprogram, DbgBlock* dwBlock, WdStackFrame* stackFrame, DbgLineData* dwLineData); + bool GetAutoLocalsInBlock(Array& outLocals, DbgSubprogram* dwSubprogram, DbgBlock* dwBlock, WdStackFrame* stackFrame, DbgLineData* dwLineData); bool RollBackStackFrame(CPURegisters* registers, addr_target* outReturnAddressLoc, bool isStackStart); bool PropogateRegisterUpCallStack(CPURegisters* callerRegisters, CPURegisters* calleeRegisters, void* regPtr, bool& wasSaved); int GetFrameBaseRegister(DbgSubprogram* dwSubprogram); diff --git a/IDEHelper/DebugVisualizers.cpp b/IDEHelper/DebugVisualizers.cpp index a95ed81c..eb5bdc5b 100644 --- a/IDEHelper/DebugVisualizers.cpp +++ b/IDEHelper/DebugVisualizers.cpp @@ -5,7 +5,7 @@ USING_NS_BF; void DebugVisualizers::Fail(const StringImpl& error) { if (mErrorString.length() != 0) - return; + return; mErrorString = StrFormat("Debug visualizer failure: %s in %s", error.c_str(), mCurFileName.c_str()); } @@ -125,7 +125,7 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName) else if ((name == "DisplayString") | (name == "StringView")) { bool isStringView = name == "StringView"; - + if (value.is()) { for (auto& displayValue : ExpectArray(value)) @@ -143,7 +143,7 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName) else Fail("Unexpected entry", value); } - + if (isStringView) entry->mStringViews.push_back(displayStringEntry); else @@ -158,7 +158,7 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName) entry->mStringViews.push_back(displayStringEntry); else entry->mDisplayStrings.push_back(displayStringEntry); - } + } } else if (name == "Action") { @@ -193,7 +193,7 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName) else if (name == "Condition") expandItem->mCondition = ExpectString(value); else - Fail("Unexpected entry", value); + Fail("Unexpected entry", value); } } } @@ -234,7 +234,7 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName) else if (name == "LowerDimSizes") { for (auto& dimValue : ExpectArray(value)) - entry->mLowerDimSizes.push_back(ExpectString(dimValue)); + entry->mLowerDimSizes.push_back(ExpectString(dimValue)); } else if (name == "ValueNode") entry->mValuePointer = ExpectString(value); @@ -364,7 +364,7 @@ bool DebugVisualizers::Load(const StringImpl& fileNamesStr) fileNames.Add(fileNamesStr.Substring(startIdx, crPos - startIdx)); startIdx = crPos + 1; } - + HashContext hashCtx; for (auto fileName : fileNames) { @@ -376,7 +376,7 @@ bool DebugVisualizers::Load(const StringImpl& fileNamesStr) } hashCtx.Mixin(lastWrite); } - + Val128 hash = hashCtx.Finish128(); if ((hash == mHash) && (!hasError)) return true; @@ -394,13 +394,12 @@ bool DebugVisualizers::Load(const StringImpl& fileNamesStr) return success; } - DebugVisualizerEntry* DebugVisualizers::FindEntryForType(const StringImpl& typeName, DbgFlavor wantFlavor, Array* wildcardCaptures) -{ +{ //TODO: Do smarter name matching. Right now we just compare up to the '*' - + for (auto entry : mDebugVisualizers) - { + { if ((entry->mFlavor != DbgFlavor_Unknown) && (entry->mFlavor != wantFlavor)) continue; @@ -435,7 +434,7 @@ DebugVisualizerEntry* DebugVisualizers::FindEntryForType(const StringImpl& typeN int openDepth = 0; String wildcardCapture; while (true) - { + { typeC = *typeCharP; bool isSep = typeC == ','; @@ -459,7 +458,7 @@ DebugVisualizerEntry* DebugVisualizers::FindEntryForType(const StringImpl& typeN { typeCharP--; break; - } + } wildcardCapture += typeC; typeCharP++; @@ -476,14 +475,14 @@ DebugVisualizerEntry* DebugVisualizers::FindEntryForType(const StringImpl& typeN } else if (entryC != typeC) break; - + typeCharP++; entryCharP++; } if (wildcardCaptures != NULL) - wildcardCaptures->Clear(); - } + wildcardCaptures->Clear(); + } return NULL; } @@ -504,4 +503,4 @@ String DebugVisualizers::DoStringReplace(const StringImpl& origStr, const Array< } } return newString; -} +} \ No newline at end of file diff --git a/IDEHelper/DebugVisualizers.h b/IDEHelper/DebugVisualizers.h index aa25a744..1c797701 100644 --- a/IDEHelper/DebugVisualizers.h +++ b/IDEHelper/DebugVisualizers.h @@ -48,7 +48,7 @@ public: OwnedVector mExpandItems; CollectionType mCollectionType; - + String mSize; Array mLowerDimSizes; String mNextPointer; @@ -58,11 +58,11 @@ public: String mRightPointer; String mValueType; String mValuePointer; - String mTargetPointer; + String mTargetPointer; String mCondition; String mBuckets; String mEntries; - String mKey; + String mKey; bool mShowedError; bool mShowElementAddrs; @@ -76,7 +76,7 @@ public: mCollectionType = CollectionType_None; mShowedError = false; mShowElementAddrs = false; - } + } }; class DebugVisualizers @@ -87,9 +87,9 @@ public: String mCurFileName; const char* mSrcStr; OwnedVector mDebugVisualizers; - + void Fail(const StringImpl& error); - void Fail(const StringImpl& error, const toml::Value& value); + void Fail(const StringImpl& error, const toml::Value& value); String ExpectString(const toml::Value& value); bool ExpectBool(const toml::Value& value); diff --git a/IDEHelper/Debugger.cpp b/IDEHelper/Debugger.cpp index 727bbd99..d1bae9a5 100644 --- a/IDEHelper/Debugger.cpp +++ b/IDEHelper/Debugger.cpp @@ -5,7 +5,7 @@ USING_NS_BF; DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, int size) -{ +{ mAddr = addr; mSize = size; @@ -27,7 +27,7 @@ DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, int size) // mBlocks = new uint8*[1]; // mFlags = new DbgMemoryFlags[1]; // mSize = size; -// +// // if (makeCopy) // { // uint8* dataCopy = new uint8[size]; @@ -40,8 +40,8 @@ DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, int size) // else // { // mBlocks[0] = data; -// } -// +// } +// // mOwns = makeCopy; // mBlockCount = 1; // } @@ -75,7 +75,7 @@ DbgMemoryFlags DbgModuleMemoryCache::Read(uintptr addr, uint8* data, int size) int relAddr = (int)(addr - mAddr); int blockIdx = relAddr / mBlockSize; int curOffset = relAddr % mBlockSize; - + while (sizeLeft > 0) { uint8* block = mBlocks[blockIdx]; @@ -98,7 +98,7 @@ DbgMemoryFlags DbgModuleMemoryCache::Read(uintptr addr, uint8* data, int size) } sizeLeft -= readSize; curOffset = 0; - blockIdx++; + blockIdx++; } return flags; @@ -114,4 +114,4 @@ void DbgModuleMemoryCache::ReportMemory(MemReporter * memReporter) totalMemory += mBlockSize; } memReporter->Add(totalMemory); -} +} \ No newline at end of file diff --git a/IDEHelper/Debugger.h b/IDEHelper/Debugger.h index 984bd03c..ec7609d9 100644 --- a/IDEHelper/Debugger.h +++ b/IDEHelper/Debugger.h @@ -29,7 +29,7 @@ public: int mPendingHotBindIdx; int mHitCount; int mTargetHitCount; - DbgHitCountBreakKind mHitCountBreakKind; + DbgHitCountBreakKind mHitCountBreakKind; String mLogging; bool mBreakAfterLogging; @@ -40,7 +40,7 @@ public: Breakpoint* mLinkedSibling; // For things like templates with multiple imps on same source line bool mIsLinkedSibling; // Not in breakpoint list -public: +public: Breakpoint() { mRequestedLineNum = -1; @@ -50,11 +50,11 @@ public: mPendingHotBindIdx = -1; mHitCount = 0; mTargetHitCount = 0; - mHitCountBreakKind = DbgHitCountBreakKind_None; + mHitCountBreakKind = DbgHitCountBreakKind_None; mThreadId = -1; mHead = NULL; mLinkedSibling = NULL; - mIsLinkedSibling = false; + mIsLinkedSibling = false; mBreakAfterLogging = false; } @@ -62,7 +62,6 @@ public: virtual bool IsMemoryBreakpointBound() = 0; }; - enum DbgTypeKindFlags { DbgTypeKindFlag_None = 0, @@ -97,7 +96,7 @@ enum DwFloatDisplayType : int8 { DwFloatDisplayType_Default, DwFloatDisplayType_Minimal, - DwFloatDisplayType_Full, + DwFloatDisplayType_Full, DwFloatDisplayType_HexUpper, DwFloatDisplayType_HexLower, @@ -126,7 +125,7 @@ enum DwEvalExpressionFlags : int16 DwEvalExpressionFlag_MemoryAddress = 0x40, DwEvalExpressionFlag_MemoryWatch = 0x80, DwEvalExpressionFlag_Symbol = 0x100, - DwEvalExpressionFlag_StepIntoCalls = 0x200, + DwEvalExpressionFlag_StepIntoCalls = 0x200, DwEvalExpressionFlag_RawStr = 0x400, DwEvalExpressionFlag_AllowStringView = 0x800 }; @@ -148,7 +147,7 @@ struct DwDisplayInfo enum RunState { - RunState_NotStarted, + RunState_NotStarted, RunState_Running, RunState_Running_ToTempBreakpoint, RunState_Paused, @@ -158,7 +157,7 @@ enum RunState RunState_HotStep, RunState_Exception, RunState_Terminating, - RunState_Terminated, + RunState_Terminated, RunState_SearchingSymSrv, RunState_HotResolve }; @@ -203,16 +202,15 @@ enum DbgMemoryFlags : uint8 class DbgModuleMemoryCache { public: - -public: +public: uintptr mAddr; int mSize; int mBlockSize; uint8** mBlocks; DbgMemoryFlags* mFlags; int mBlockCount; - bool mOwns; + bool mOwns; public: DbgModuleMemoryCache(uintptr addr, int size); @@ -229,7 +227,7 @@ public: struct TypeData { intptr mCount; - intptr mSize; + intptr mSize; TypeData() { @@ -249,7 +247,7 @@ class Debugger { public: DebugManager* mDebugManager; - RunState mRunState; + RunState mRunState; DbgHotResolveData* mHotResolveData; bool mHadImageFindError; @@ -257,7 +255,7 @@ public: Debugger() { mDebugManager = NULL; - mRunState = RunState_NotStarted; + mRunState = RunState_NotStarted; mHotResolveData = NULL; mHadImageFindError = false; } @@ -283,7 +281,7 @@ public: virtual Breakpoint* CreateAddressBreakpoint(intptr address) = 0; virtual void CheckBreakpoint(Breakpoint* breakpoint) = 0; virtual void HotBindBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int hotIdx) = 0; - virtual void DeleteBreakpoint(Breakpoint* wdBreakpoint) = 0; + virtual void DeleteBreakpoint(Breakpoint* wdBreakpoint) = 0; virtual void DetachBreakpoint(Breakpoint* wdBreakpoint) = 0; virtual void MoveBreakpoint(Breakpoint* wdBreakpoint, int lineNum, int wantColumn, bool rebindNow) = 0; virtual void MoveMemoryBreakpoint(Breakpoint* wdBreakpoint, intptr addr, int byteCount) = 0; @@ -306,13 +304,13 @@ public: virtual void EvaluateContinueKeep() = 0; virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) = 0; virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) = 0; - virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) = 0; + virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) = 0; virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) = 0; virtual String GetAutoLocals(int callStackIdx, bool showRegs) = 0; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) = 0; virtual String GetProcessInfo() = 0; virtual String GetThreadInfo() = 0; - virtual void SetActiveThread(int threadId) = 0; + virtual void SetActiveThread(int threadId) = 0; virtual int GetActiveThread() = 0; virtual void FreezeThread(int threadId) = 0; virtual void ThawThread(int threadId) = 0; @@ -321,12 +319,12 @@ public: virtual void UpdateCallStack(bool slowEarlyOut = true) = 0; virtual int GetCallStackCount() = 0; virtual int GetRequestedStackFrameIdx() = 0; - virtual int GetBreakStackFrameIdx() = 0; + virtual int GetBreakStackFrameIdx() = 0; virtual bool ReadMemory(intptr address, uint64 length, void* dest, bool local = false) = 0; virtual bool WriteMemory(intptr address, void* src, uint64 length) = 0; virtual DbgMemoryFlags GetMemoryFlags(intptr address) = 0; - virtual void UpdateRegisterUsage(int stackFrameIdx) = 0; - virtual void UpdateCallStackMethod(int stackFrameIdx) = 0; + virtual void UpdateRegisterUsage(int stackFrameIdx) = 0; + virtual void UpdateCallStackMethod(int stackFrameIdx) = 0; virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) = 0; virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) = 0; virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) = 0; @@ -340,8 +338,8 @@ public: virtual String GetAddressSymbolName(intptr address, bool demangle) = 0; virtual String DisassembleAtRaw(intptr address) = 0; virtual String DisassembleAt(intptr address) = 0; - virtual String FindLineCallAddresses(intptr address) = 0; - virtual String GetCurrentException() = 0; + virtual String FindLineCallAddresses(intptr address) = 0; + virtual String GetCurrentException() = 0; virtual String GetModulesInfo() = 0; virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) = 0; virtual void CancelSymSrv() = 0; @@ -351,7 +349,7 @@ public: virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) = 0; virtual void StopDebugging() = 0; virtual void Terminate() = 0; - virtual void Detach() = 0; + virtual void Detach() = 0; virtual Profiler* StartProfiling() = 0; virtual Profiler* PopProfiler() = 0; // Profiler requested by target program virtual void ReportMemory(MemReporter* memReporter) = 0; @@ -380,7 +378,7 @@ public: virtual bool IsSampling() = 0; virtual String GetOverview() = 0; virtual String GetThreadList() = 0; - virtual String GetCallTree(int threadId, bool reverse) = 0; + virtual String GetCallTree(int threadId, bool reverse) = 0; }; NS_BF_END diff --git a/IDEHelper/DwAutoComplete.h b/IDEHelper/DwAutoComplete.h index 021e1c8a..4b66be92 100644 --- a/IDEHelper/DwAutoComplete.h +++ b/IDEHelper/DwAutoComplete.h @@ -15,7 +15,7 @@ class DwAutoComplete : public Beefy::AutoCompleteBase public: class MethodMatchEntry { - public: + public: DwTypeVector mDwGenericArguments; DbgSubprogram* mDwSubprogram; }; diff --git a/IDEHelper/HandleDbg.cpp b/IDEHelper/HandleDbg.cpp index 5d9e94b2..51bd90c9 100644 --- a/IDEHelper/HandleDbg.cpp +++ b/IDEHelper/HandleDbg.cpp @@ -149,7 +149,7 @@ void HDCheckHandles(const std::string& traceStr) handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); NTSTATUS status; - /* NtQuerySystemInformation won't give us the correct buffer size, + /* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */ while ((status = gNtQuerySystemInformation( SystemHandleInformation, @@ -181,7 +181,7 @@ void HDCheckHandles(const std::string& traceStr) /* Check if this handle belongs to the PID the user specified. */ if (handle.ProcessId != GetCurrentProcessId()) continue; - + auto itr = oldHandleMap.find(handle.Handle); if (itr != oldHandleMap.end()) gHDHandleMap.insert(*itr); @@ -261,7 +261,7 @@ void HDDump() continue; } - /* Query the object name (unless it has an access of + /* Query the object name (unless it has an access of 0x0012019f, on which NtQueryObject could hang. */ if (handle.GrantedAccess == 0x0012019f) { @@ -375,7 +375,7 @@ int ZZwmain(int argc, WCHAR *argv[]) handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); - /* NtQuerySystemInformation won't give us the correct buffer size, + /* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */ while ((status = NtQuerySystemInformation( SystemHandleInformation, @@ -435,7 +435,7 @@ int ZZwmain(int argc, WCHAR *argv[]) continue; } - /* Query the object name (unless it has an access of + /* Query the object name (unless it has an access of 0x0012019f, on which NtQueryObject could hang. */ if (handle.GrantedAccess == 0x0012019f) { @@ -520,4 +520,4 @@ int ZZwmain(int argc, WCHAR *argv[]) CloseHandle(processHandle); return 0; -} +} \ No newline at end of file diff --git a/IDEHelper/HotHeap.cpp b/IDEHelper/HotHeap.cpp index 7b601a59..04675ea4 100644 --- a/IDEHelper/HotHeap.cpp +++ b/IDEHelper/HotHeap.cpp @@ -14,7 +14,7 @@ HotHeap::HotHeap(addr_target hotStart, int size) } HotHeap::HotHeap() -{ +{ mHotAreaStart = 0xFFFFFFFF; mHotAreaSize = 0; mCurBlockIdx = 0; @@ -59,17 +59,17 @@ addr_target HotHeap::Alloc(int size) } if (!isOccupied) - { + { mBlockAllocIdx += blockCount; addr_target addr = mHotAreaStart + mCurBlockIdx * BLOCK_SIZE; OutputDebugStrF("HotHeap Alloc %d length %d %@\n", mCurBlockIdx, blockCount, addr); for (int checkIdx = 0; checkIdx < blockCount; checkIdx++) - { + { mHotAreaUsed[mCurBlockIdx] = (HotUseFlags)(mHotAreaUsed[mCurBlockIdx] | HotUseFlags_Allocated); mCurBlockIdx++; - } + } return addr; } } @@ -100,7 +100,7 @@ void HotHeap::Release(addr_target addr, int size) } bool HotHeap::IsReferenced(addr_target addr, int size) -{ +{ int blockStart = (int)(addr - mHotAreaStart) / BLOCK_SIZE; int blockCount = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; for (int blockNum = blockStart; blockNum < blockStart + blockCount; blockNum++) @@ -111,7 +111,7 @@ bool HotHeap::IsReferenced(addr_target addr, int size) void HotHeap::MarkBlockReferenced(addr_target addr) { - int blockNum = (int)(addr - mHotAreaStart) / BLOCK_SIZE; + int blockNum = (int)(addr - mHotAreaStart) / BLOCK_SIZE; mHotAreaUsed[blockNum] = (HotUseFlags)(mHotAreaUsed[blockNum] | HotUseFlags_Referenced); } @@ -124,7 +124,7 @@ void HotHeap::ClearReferencedFlags() } intptr_target HotHeap::GetUsedSize() -{ +{ if (mTrackedMap.size() != 0) { int usedBytes = 0; @@ -133,7 +133,7 @@ intptr_target HotHeap::GetUsedSize() return usedBytes; } - int usedCount = 0; + int usedCount = 0; for (auto flag : mHotAreaUsed) if ((flag & HotUseFlags_Allocated) != 0) usedCount++; diff --git a/IDEHelper/HotHeap.h b/IDEHelper/HotHeap.h index 5f54d97d..c053cb16 100644 --- a/IDEHelper/HotHeap.h +++ b/IDEHelper/HotHeap.h @@ -18,10 +18,10 @@ public: public: static const int BLOCK_SIZE = 4096; - + addr_target mHotAreaStart; int mHotAreaSize; - Beefy::Array mHotAreaUsed; + Beefy::Array mHotAreaUsed; int mCurBlockIdx; int mBlockAllocIdx; // Total blocks allocated, doesn't decrease with frees @@ -31,9 +31,9 @@ public: public: HotHeap(addr_target hotStart, int size); HotHeap(); - + void AddTrackedRegion(addr_target hotStart, int size); - + addr_target Alloc(int size); void Release(addr_target addr, int size); void MarkBlockReferenced(addr_target addr); diff --git a/IDEHelper/HotScanner.cpp b/IDEHelper/HotScanner.cpp index d88baccf..e623821e 100644 --- a/IDEHelper/HotScanner.cpp +++ b/IDEHelper/HotScanner.cpp @@ -12,7 +12,7 @@ DbgHotScanner::DbgHotScanner(WinDebugger* debugger) NS_BF_DBG_BEGIN namespace TCFake -{ +{ struct Span { addr_target start; // Starting page number @@ -45,7 +45,7 @@ struct Fake_BfObject_WithFlags { union { - addr_target mClassVData; + addr_target mClassVData; struct { BfObjectFlags mObjectFlags; @@ -154,15 +154,15 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK intptr pageSize = (intptr)1 << kPageShift; int spanSize = pageSize * span->length; addr_target spanStart = ((addr_target)span->start << kPageShift); - + if (spanSize > mScanData.size()) { mScanData.Resize(spanSize); } void* spanPtr = &mScanData[0]; - mDebugger->ReadMemory(spanStart, spanSize, spanPtr); + mDebugger->ReadMemory(spanStart, spanSize, spanPtr); void* spanEnd = (void*)((intptr)spanPtr + spanSize); - + //BF_LOGASSERT((spanStart >= TCFake::PageHeap::sAddressStart) && (spanEnd <= TCFake::PageHeap::sAddressEnd)); int elementSize = mDbgGCData.mSizeClasses[span->sizeclass]; @@ -183,6 +183,10 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK int objectSize = ((mDbgGCData.mDbgFlags & BfRtFlags_ObjectHasDebugFlags) != 0) ? sizeof(addr_target)*2 : sizeof(addr_target); + mDebugger->mDebugTarget->GetCompilerSettings(); + if (mDebugger->mDebugTarget->mBfObjectSize != 0) + objectSize = mDebugger->mDebugTarget->mBfObjectSize; + while (spanPtr <= (uint8*)spanEnd - elementSize) { addr_target classVDataAddr = 0; @@ -211,9 +215,8 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK if ((mDbgGCData.mDbgFlags & BfRtFlags_ObjectHasDebugFlags) != 0) classVDataAddr = classVDataAddr & ~0xFF; } - else + else { - int* rawTypeIdPtr = NULL; if (mFoundRawAllocDataAddrs.TryAdd(rawAllocDataAddr, NULL, &rawTypeIdPtr)) { @@ -231,8 +234,8 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK *typeAddrIdPtr = typeData.mTypeId; *rawTypeIdPtr = typeData.mTypeId; _MarkTypeUsed(typeData.mTypeId, elementSize); - } - } + } + } else { _MarkTypeUsed(*typeAddrIdPtr, elementSize); @@ -249,7 +252,7 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK if (classVDataAddr != 0) { - int* typeIdPtr = NULL; + int* typeIdPtr = NULL; if (mFoundClassVDataAddrs.TryAdd(classVDataAddr, NULL, &typeIdPtr)) { addr_target typeAddr = mDebugger->ReadMemory(classVDataAddr); @@ -271,7 +274,7 @@ void DbgHotScanner::ScanSpan(TCFake::Span* span, int expectedStartPage, int memK } else { - _MarkTypeUsed(*typeIdPtr, elementSize); + _MarkTypeUsed(*typeIdPtr, elementSize); } } @@ -296,7 +299,7 @@ void DbgHotScanner::ScanRoot(addr_target rootPtr, int memKind) if (spanAddr == 0) continue; - int expectedStartPage = (rootIdx * PageHeap::PageMap::LEAF_LENGTH) + leafIdx; + int expectedStartPage = (rootIdx * PageHeap::PageMap::LEAF_LENGTH) + leafIdx; TCFake::Span span; mDebugger->ReadMemory(spanAddr, sizeof(span), &span); ScanSpan(&span, expectedStartPage, memKind); @@ -367,7 +370,7 @@ void DbgHotScanner::Scan(DbgHotResolveFlags flags) bool success = mDebugger->ReadMemory(gcDbgDataAddr, sizeof(DbgGCData), &mDbgGCData); if (!success) - { + { BF_ASSERT("Failed to read DbgGCData"); success = mDebugger->ReadMemory(gcDbgDataAddr, sizeof(DbgGCData), &mDbgGCData); } @@ -376,7 +379,7 @@ void DbgHotScanner::Scan(DbgHotResolveFlags flags) if (mDbgGCData.mObjRootPtr != NULL) ScanRoot(mDbgGCData.mObjRootPtr, 0); if (mDbgGCData.mRawRootPtr != NULL) - ScanRoot(mDbgGCData.mRawRootPtr, 1); + ScanRoot(mDbgGCData.mRawRootPtr, 1); } if ((prevRunState == RunState_Running) && ((flags & DbgHotResolveFlag_KeepThreadState) == 0)) @@ -384,4 +387,4 @@ void DbgHotScanner::Scan(DbgHotResolveFlags flags) mDebugger->ThreadRestoreUnpause(); mDebugger->mRunState = prevRunState; } -} +} \ No newline at end of file diff --git a/IDEHelper/HotScanner.h b/IDEHelper/HotScanner.h index d79f7274..b52944b0 100644 --- a/IDEHelper/HotScanner.h +++ b/IDEHelper/HotScanner.h @@ -76,7 +76,7 @@ public: addr_target mRawRootPtr; addr_target mRawObjectSentinel; - int mSizeClasses[TCFake::kNumClasses]; + int mSizeClasses[TCFake::kNumClasses]; }; class DbgHotScanner @@ -88,7 +88,7 @@ public: Beefy::Dictionary mFoundRawAllocDataAddrs; Beefy::Dictionary mFoundTypeAddrs; Beefy::HashSet mFoundFuncPtrs; - + #ifdef BF_DBG_32 TCFake::PageHeap::PageMap::Root mRoot; TCFake::PageHeap::PageMap::Leaf mNode; @@ -97,7 +97,7 @@ public: TCFake::PageHeap::PageMap::Node mNode1; TCFake::PageHeap::PageMap::Leaf mNode2; #endif - Beefy::Array mScanData; + Beefy::Array mScanData; public: void AddSubProgram(DbgSubprogram* subProgram, bool followInlineParent, const Beefy::StringImpl& prefix); diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index 48c8a48e..7f17b0d4 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -139,6 +139,7 @@ MultiThreadedDebugDLL ProgramDatabase false + true Windows @@ -166,6 +167,7 @@ MultiThreadedDebug ProgramDatabase false + true Windows @@ -197,6 +199,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;C:\llvm-3.8\llvm\include;C:\llvm-3.8\bin\include;C:\llvm-3.8\llvm\lib\Target;C:\llvm-3.8\bin\lib\Target\X86;C:\llvm-3.8\llvm\tools\clang\include MultiThreadedDLL + true Windows @@ -222,6 +225,7 @@ ../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_13_0_1\llvm\include;..\extern\llvm_win64_13_0_1\include;..\extern\llvm-project_13_0_1\llvm\lib\Target;..\extern\llvm_win64_13_0_1\lib\Target\X86;..\extern\llvm-project_13_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include MultiThreaded false + true Windows diff --git a/IDEHelper/LLVMUtils.h b/IDEHelper/LLVMUtils.h index 71ec0575..415f257f 100644 --- a/IDEHelper/LLVMUtils.h +++ b/IDEHelper/LLVMUtils.h @@ -18,13 +18,13 @@ NS_BF_BEGIN /// raw_null_ostream - A raw_ostream that discards all output. -class debug_ostream : public llvm::raw_ostream +class debug_ostream : public llvm::raw_ostream { /// write_impl - See raw_ostream::write_impl. void write_impl(const char *Ptr, size_t size) override { StringT<1024> str; - str.Append(Ptr, size); + str.Append(Ptr, size); OutputDebugStr(str); } @@ -33,7 +33,7 @@ class debug_ostream : public llvm::raw_ostream uint64_t current_pos() const override { return 0; - } + } }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/MiniDumpDebugger.cpp b/IDEHelper/MiniDumpDebugger.cpp index 5900abdc..e5170a78 100644 --- a/IDEHelper/MiniDumpDebugger.cpp +++ b/IDEHelper/MiniDumpDebugger.cpp @@ -23,9 +23,9 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini if (section.mStreamType == ThreadExListStream) { auto& threadEx = mMiniDump->GetStreamData(section); - + /*WdThreadInfo* threadInfo = new WdThreadInfo(); - threadInfo->mThreadId = threadEx.ThreadId; + threadInfo->mThreadId = threadEx.ThreadId; mThreadList.Add(threadInfo); if (mActiveThread == NULL) @@ -54,7 +54,7 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini //TODO: 'get' the actual image dbgModule->mTimeStamp = module.TimeDateStamp; //dbgModule->mExpectedFileSize = module.; - + const wchar_t* moduleName = &mMiniDump->GetData(module.ModuleNameRva + 4); dbgModule->mFilePath = UTF8Encode(moduleName); dbgModule->mDisplayName = GetFileName(dbgModule->mFilePath); @@ -74,8 +74,8 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini //dbgModule->LoadPDB(codeViewEntry.mPDBPath, codeViewEntry.mGUID, codeViewEntry.mAge); } - auto miscEntry = &mMiniDump->GetData(module.MiscRecord.Rva); - + auto miscEntry = &mMiniDump->GetData(module.MiscRecord.Rva); + mDebugTarget->AddDbgModule(dbgModule); //TESTING @@ -124,7 +124,7 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini auto& memoryInfoList = mMiniDump->GetStreamData(section); for (int memoryInfoIdx = 0; memoryInfoIdx < (int)memoryInfoList.NumberOfEntries; memoryInfoIdx++) { - auto& memoryInfo = mMiniDump->GetData(section.mDataRVA + memoryInfoList.SizeOfHeader + memoryInfoIdx*memoryInfoList.SizeOfEntry); + auto& memoryInfo = mMiniDump->GetData(section.mDataRVA + memoryInfoList.SizeOfHeader + memoryInfoIdx*memoryInfoList.SizeOfEntry); } } else if (section.mStreamType == MemoryListStream) @@ -143,15 +143,15 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini else if (section.mStreamType == ExceptionStream) { auto& exceptionStream = mMiniDump->GetStreamData(section); - - //mCurException = exceptionStream.ExceptionRecord; + + //mCurException = exceptionStream.ExceptionRecord; mCurException.ExceptionCode = exceptionStream.ExceptionRecord.ExceptionCode; mCurException.ExceptionFlags = exceptionStream.ExceptionRecord.ExceptionFlags; mCurException.ExceptionAddress = (PVOID)exceptionStream.ExceptionRecord.ExceptionAddress; mCurException.NumberParameters = exceptionStream.ExceptionRecord.NumberParameters; for (int i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++) mCurException.ExceptionInformation[i] = exceptionStream.ExceptionRecord.ExceptionInformation[i]; - + WdThreadInfo* threadInfo = NULL; if (mThreadMap.TryGetValue(exceptionStream.ThreadId, &threadInfo)) { @@ -168,19 +168,19 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini } else if (section.mStreamType == SystemInfoStream) { - auto& systemInfo = mMiniDump->GetStreamData(section); + auto& systemInfo = mMiniDump->GetStreamData(section); } else if (section.mStreamType == MiscInfoStream) { - auto& miscInfo = mMiniDump->GetStreamData(section); + auto& miscInfo = mMiniDump->GetStreamData(section); } else if (section.mStreamType == 21/*SystemMemoryInfoStream*/) { - auto data = ((uint8*)mMiniDump->mMF.mData + section.mDataRVA); + auto data = ((uint8*)mMiniDump->mMF.mData + section.mDataRVA); } else if (section.mStreamType == 22/*ProcessVmCountersStream*/) { - auto data = ((uint8*)mMiniDump->mMF.mData + section.mDataRVA); + auto data = ((uint8*)mMiniDump->mMF.mData + section.mDataRVA); } else if (section.mStreamType == 24) // Thread names { @@ -199,7 +199,7 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini int nameLen = *(int32*)((uint8*)mMiniDump->mMF.mData + threadNameInfo->mNameRVA); UTF16String name = UTF16String((wchar_t*)((uint8*)mMiniDump->mMF.mData + threadNameInfo->mNameRVA + 4), nameLen); - + WdThreadInfo* threadInfo = NULL; if (mThreadMap.TryGetValue(threadNameInfo->mThreadId, &threadInfo)) { @@ -216,15 +216,15 @@ MiniDumpDebugger::MiniDumpDebugger(DebugManager* debugManager, DbgMiniDump* mini GUID mClientID; }; - auto& crashPadInfo = mMiniDump->GetStreamData<_MiniDumpCrashPadInfo>(section); + auto& crashPadInfo = mMiniDump->GetStreamData<_MiniDumpCrashPadInfo>(section); } else if (section.mStreamType == 0x4b6b0002) // Stability report { - const char* report = &mMiniDump->GetStreamData(section); + const char* report = &mMiniDump->GetStreamData(section); } else if (section.mStreamType == 0x4b6b0002) // Stability report { - const char* report = &mMiniDump->GetStreamData(section); + const char* report = &mMiniDump->GetStreamData(section); } else if (section.mStreamType == 0xBEEF00) // Error text { @@ -257,7 +257,7 @@ void MiniDumpDebugger::MapMemory(addr_target addr, void* data, intptr_target siz break; MiniDumpMemoryRegion* memRegion = mAlloc.Alloc(); - memRegion->mAddress = beginAddress + memOffset; + memRegion->mAddress = beginAddress + memOffset; memRegion->mAddressLength = curSize; memRegion->mData = (uint8*)data + memOffset; memRegion->mNext = NULL; @@ -271,9 +271,9 @@ MappedFile* MiniDumpDebugger::MapModule(COFF* dbgModule, const StringImpl& fileN if (!mappedFile->Open(fileName)) { delete mappedFile; - return NULL; + return NULL; } - mMappedFiles.Add(mappedFile); + mMappedFiles.Add(mappedFile); return mappedFile; } @@ -289,7 +289,6 @@ bool MiniDumpDebugger::PopulateRegisters(CPURegisters* registers) { if (section.mStreamType == ThreadExListStream) { - } else if (section.mStreamType == ThreadListStream) { @@ -352,21 +351,20 @@ bool MiniDumpDebugger::ReadMemory(intptr address, uint64 length, void* dest, boo return false; } return true; - } + } useAddr = BF_MIN(useAddr, memRegion->mAddress - 1); - memRegion = memRegion->mNext; + memRegion = memRegion->mNext; } //if (((uintptr)address < (uintptr)memRegion->mAddress) || ((uintptr)(address + length) > uintptr(memRegion->mAddress + memRegion->mAddressLength))) //return false; // Out of bounds } - + return false; } bool MiniDumpDebugger::WriteMemory(intptr address, void* src, uint64 length) { return false; -} - +} \ No newline at end of file diff --git a/IDEHelper/MiniDumpDebugger.h b/IDEHelper/MiniDumpDebugger.h index 616d5cd8..1b2f892e 100644 --- a/IDEHelper/MiniDumpDebugger.h +++ b/IDEHelper/MiniDumpDebugger.h @@ -32,7 +32,7 @@ public: void MapMemory(addr_target addr, void* data, intptr_target size); MappedFile* MapModule(COFF* dbgModule, const StringImpl& fileName); - + virtual bool PopulateRegisters(CPURegisters* registers) override; using WinDebugger::PopulateRegisters; @@ -40,7 +40,7 @@ public: virtual bool WriteMemory(intptr address, void* src, uint64 length) override; virtual bool IsOnDemandDebugger() override { return true; } - virtual bool IsMiniDumpDebugger() override { return true; } + virtual bool IsMiniDumpDebugger() override { return true; } virtual void ContinueDebugEvent() { } virtual Breakpoint* CreateBreakpoint(const StringImpl& fileName, int lineNum, int wantColumn, int instrOffset) { return NULL; } @@ -60,5 +60,3 @@ public: }; NS_BF_DBG_END - - diff --git a/IDEHelper/NetManager.cpp b/IDEHelper/NetManager.cpp index 47ac716d..953ca872 100644 --- a/IDEHelper/NetManager.cpp +++ b/IDEHelper/NetManager.cpp @@ -83,10 +83,10 @@ void NetRequest::Cleanup() { if (mCURLMulti != NULL) curl_multi_remove_handle(mCURLMulti, mCURL); - if (mCURL != NULL) - curl_easy_cleanup(mCURL); - if (mCURLMulti != NULL) - curl_multi_cleanup(mCURLMulti); + if (mCURL != NULL) + curl_easy_cleanup(mCURL); + if (mCURLMulti != NULL) + curl_multi_cleanup(mCURLMulti); mCURL = NULL; mCURLMulti = NULL; @@ -160,7 +160,7 @@ void NetRequest::DoTransfer() // mFailed = true; // return; // } - + response_code = 0; curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code); mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code)); @@ -199,20 +199,20 @@ void NetRequest::DoTransfer() } if (response_code != 200) - { + { mOutFile.Close(); // Bad result mFailed = true; return; } - + BfLogDbg("NetManager successfully completed %s\n", mURL.c_str()); if (mCancelOnSuccess != NULL) mNetManager->Cancel(mCancelOnSuccess); if (!mOutFile.IsOpen()) - { + { mFailed = true; return; // No data } @@ -223,14 +223,14 @@ void NetRequest::DoTransfer() BfpFile_Rename(mOutTempPath.c_str(), mOutPath.c_str(), &renameResult); if (renameResult != BfpFileResult_Ok) - { - mFailed = true; + { + mFailed = true; } } void NetRequest::Perform() -{ - DoTransfer(); +{ + DoTransfer(); } #elif defined BF_PLATFORM_WINDOWS @@ -263,16 +263,16 @@ void NetRequest::Perform() Fail("Invalid URL"); return; } - + protoName = mURL.Substring(0, colonPos); serverName = mURL.Substring(colonPos + 3); - + int slashPos = (int)serverName.IndexOf('/'); if (slashPos != -1) { objectName = serverName.Substring(slashPos); serverName.RemoveToEnd(slashPos); - } + } mOutTempPath = mOutPath + "__partial"; @@ -291,8 +291,8 @@ void NetRequest::Perform() if (mOutFile.IsOpen()) mOutFile.Close(); - }; - + }; + bool isHttp = protoName.Equals("http", StringImpl::CompareKind_OrdinalIgnoreCase); bool isHttps = protoName.Equals("https", StringImpl::CompareKind_OrdinalIgnoreCase); if ((!isHttp) && (!isHttps)) @@ -350,23 +350,23 @@ void NetRequest::Perform() } if (mShowTracking) - { + { mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str())); } - uint8 buffer[4096]; + uint8 buffer[4096]; while (true) { DWORD dwBytesRead = 0; BOOL bRead = InternetReadFile(hHttpFile, buffer, 4096, &dwBytesRead); - if (dwBytesRead == 0) + if (dwBytesRead == 0) break; - if (!bRead) + if (!bRead) { //printf("InternetReadFile error : <%lu>\n", GetLastError()); Fail("Failed to receive"); return; - } + } if (!mOutFile.IsOpen()) { @@ -378,7 +378,7 @@ void NetRequest::Perform() } } mOutFile.Write(buffer, (int)dwBytesRead); - } + } BfLogDbg("NetManager successfully completed %s\n", mURL.c_str()); @@ -402,7 +402,6 @@ void NetRequest::Perform() void NetRequest::Cleanup() { - } #else @@ -414,7 +413,6 @@ void NetRequest::Perform() void NetRequest::Cleanup() { - } #endif @@ -437,7 +435,7 @@ NetRequest::~NetRequest() delete mResult; } - mNetManager->mRequestDoneEvent.Set(); + mNetManager->mRequestDoneEvent.Set(); } void NetRequest::Fail(const StringImpl& error) @@ -456,7 +454,7 @@ bool NetRequest::Cancel() } void NetRequest::ShowTracking() -{ +{ //mNetManager->mDebugManager->OutputMessage(StrFormat("Getting '%s'\n", mURL.c_str())); mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str())); mShowTracking = true; @@ -464,7 +462,6 @@ void NetRequest::ShowTracking() void NetManagerThread() { - } NetManager::NetManager() : mThreadPool(8, 1*1024*1024) @@ -480,13 +477,13 @@ NetManager::~NetManager() for (auto kv : mCachedResults) { delete kv.mValue; - } + } } NetRequest* NetManager::CreateGetRequest(const StringImpl& url, const StringImpl& destPath, bool useCache) { AutoCrit autoCrit(mThreadPool.mCritSect); - + NetRequest* netRequest = new NetRequest(); netRequest->mNetManager = this; netRequest->mURL = url; @@ -520,7 +517,7 @@ NetRequest* NetManager::CreateGetRequest(const StringImpl& url, const StringImpl NetResult* NetManager::QueueGet(const StringImpl& url, const StringImpl& destPath, bool useCache) { BfLogDbg("NetManager queueing %s %d\n", url.c_str(), useCache); - + auto netRequest = CreateGetRequest(url, destPath, useCache); auto netResult = netRequest->mResult; mThreadPool.AddJob(netRequest); @@ -528,7 +525,7 @@ NetResult* NetManager::QueueGet(const StringImpl& url, const StringImpl& destPat } bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) -{ +{ NetRequest* netRequest = NULL; int waitCount = 0; while (true) @@ -539,7 +536,7 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) mWaitingResult = NULL; NetResult* netResult; - if (mCachedResults.TryGetValue(url, &netResult)) + if (mCachedResults.TryGetValue(url, &netResult)) { if (netResult->mCurRequest == NULL) { @@ -547,7 +544,7 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) return (!netResult->mFailed) && (FileExists(netResult->mOutPath)); } else if (!netResult->mCurRequest->mShowTracking) // Is done? - { + { if (!netResult->mCurRequest->mProcessing) { BfLogDbg("NetManager::Get pulling queued request into current thread %s\n", url.c_str()); @@ -557,9 +554,9 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) break; } - mWaitingResult = netResult; + mWaitingResult = netResult; netResult->mCurRequest->ShowTracking(); - } + } } else { @@ -597,12 +594,12 @@ void NetManager::CancelAll() AutoCrit autoCrit(mThreadPool.mCritSect); if (mWaitingRequest != NULL) mWaitingRequest->Cancel(); - mThreadPool.CancelAll(); + mThreadPool.CancelAll(); } void NetManager::Clear() { - AutoCrit autoCrit(mThreadPool.mCritSect); + AutoCrit autoCrit(mThreadPool.mCritSect); BF_ASSERT(mWaitingResult == NULL); // The debugger thread shouldn't be waiting on anything, it should be detached at this point for (auto job : mThreadPool.mJobs) @@ -649,7 +646,7 @@ void NetManager::SetCancelOnSuccess(NetResult* dependentResult, NetResult* cance { AutoCrit autoCrit(mThreadPool.mCritSect); if (dependentResult->mCurRequest != NULL) - { + { dependentResult->mCurRequest->mCancelOnSuccess = cancelOnSucess; } -} +} \ No newline at end of file diff --git a/IDEHelper/NetManager.h b/IDEHelper/NetManager.h index 0b7aa101..623339d4 100644 --- a/IDEHelper/NetManager.h +++ b/IDEHelper/NetManager.h @@ -52,10 +52,10 @@ public: #else #endif mCancelling = false; - mFailed = false; + mFailed = false; mShowTracking = false; mResult = NULL; - mCancelOnSuccess = NULL; + mCancelOnSuccess = NULL; } ~NetRequest(); @@ -63,7 +63,7 @@ public: void Cleanup(); void Fail(const StringImpl& error); - bool Cancel() override; + bool Cancel() override; void Perform() override; void ShowTracking(); }; @@ -113,7 +113,7 @@ public: NetRequest* CreateGetRequest(const StringImpl& url, const StringImpl& destPath, bool useCache); NetResult* QueueGet(const StringImpl& url, const StringImpl& destPath, bool useCache); bool Get(const StringImpl& url, const StringImpl& destPath); - + void CancelAll(); void Clear(); void CancelCurrent(); diff --git a/IDEHelper/Profiler.cpp b/IDEHelper/Profiler.cpp index 123e144a..fc37608a 100644 --- a/IDEHelper/Profiler.cpp +++ b/IDEHelper/Profiler.cpp @@ -101,7 +101,7 @@ DbgProfiler::DbgProfiler(WinDebugger* debugger) : mShutdownEvent(true) mEndTick = 0; mDebugger->AddProfiler(this); - + mIdleSymbolNames.Add("NtUserGetMessage"); mIdleSymbolNames.Add("NtWaitForAlertByThreadId"); mIdleSymbolNames.Add("NtWaitForMultipleObjects"); @@ -167,7 +167,7 @@ ProfileProcId* DbgProfiler::Get(const StringImpl& str, bool* outIsNew) auto procId = new ProfileProcId(); procId->mProcName = str; procId->mIsIdle = false; - entryPtr->mProcId = procId; + entryPtr->mProcId = procId; if (outIsNew != NULL) *outIsNew = true; return procId; @@ -372,7 +372,7 @@ void DbgProfiler::ThreadProc() ProfileAddrEntry* insertedProfileEntry = AddToSet(mProfileAddrEntrySet, stackTrace, stackSize); if (insertedProfileEntry->mEntryIdx == -1) { - insertedProfileEntry->mEntryIdx = (int)mProfileAddrEntrySet.size(); // Starts at '1' + insertedProfileEntry->mEntryIdx = (int)mProfileAddrEntrySet.size(); // Starts at '1' mPendingProfileEntries.Add(*insertedProfileEntry); } @@ -652,7 +652,7 @@ void DbgProfiler::HandlePendingEntries() auto procEntry = AddToSet(mProfileProcEntrySet, procStackTraceHead, stackTraceProcIdx); if (procEntry->mEntryIdx == -1) { - procEntry->mEntryIdx = (int)mProfileProcEntrySet.size() - 1; // Start at '0' + procEntry->mEntryIdx = (int)mProfileProcEntrySet.size() - 1; // Start at '0' } mProfileAddrToProcMap[addrEntry->mEntryIdx] = procEntry->mEntryIdx; } @@ -681,7 +681,7 @@ void DbgProfiler::Process() for (auto threadKV : mThreadInfo) { auto threadInfo = threadKV.mValue; - + for (auto addrEntryIdx : threadInfo->mProfileAddrEntries) { if (addrEntryIdx < 0) @@ -691,10 +691,10 @@ void DbgProfiler::Process() int procEntryIdx = mProfileAddrToProcMap[addrEntryIdx]; auto procEntry = mProfileProcEntries[procEntryIdx]; - + auto curProc = procEntry->mData[0]; if (curProc->mIsIdle) - threadInfo->mTotalIdleSamples++; + threadInfo->mTotalIdleSamples++; } } } @@ -765,5 +765,4 @@ String DbgProfiler::GetCallTree(int threadId, bool reverse) //BF_ASSERT(childSampleCount == totalSampleCount); return str; -} - +} \ No newline at end of file diff --git a/IDEHelper/Profiler.h b/IDEHelper/Profiler.h index 018fa548..e567962d 100644 --- a/IDEHelper/Profiler.h +++ b/IDEHelper/Profiler.h @@ -48,7 +48,7 @@ struct ProfileDataListEquals class ProfileAddrEntry : public ProfileDataList { -public: +public: //int mSampleCount; int mEntryIdx; @@ -88,7 +88,7 @@ public: int mEntryIdx; bool mUsed; -public: +public: ProfileProcEntry() { mEntryIdx = -1; @@ -122,7 +122,7 @@ public: WinDebugger* mDebugger; volatile bool mIsRunning; bool mWantsClear; - SyncEvent mShutdownEvent; + SyncEvent mShutdownEvent; bool mNeedsProcessing; uint32 mStartTick; uint32 mEndTick; @@ -130,37 +130,37 @@ public: int mTotalVirtualSamples; int mTotalActualSamples; int mTotalActiveSamplingMS; - + BumpAllocator mAlloc; Dictionary mThreadInfo; Array mThreadIdList; - ProfileAddrEntrySet mProfileAddrEntrySet; + ProfileAddrEntrySet mProfileAddrEntrySet; Array mProfileAddrEntries; Array mPendingProfileEntries; ProfileProcEntrySet mProfileProcEntrySet; - Array mProfileProcEntries; + Array mProfileProcEntries; Array mProfileAddrToProcMap; - Dictionary mProcMap; // Keyed on either DwSubprogram or DwSymbol. Multiple pointers can reference the same ProfileProcId (in the case of inlined functions, for example) - HashSet mUniqueProcSet; + Dictionary mProcMap; // Keyed on either DwSubprogram or DwSymbol. Multiple pointers can reference the same ProfileProcId (in the case of inlined functions, for example) + HashSet mUniqueProcSet; HashSet mIdleSymbolNames; public: void ThreadProc(); - void AddEntries(String& str, Array& procEntries, int rangeStart, int rangeEnd, int stackIdx, ProfileProcId* findProc); + void AddEntries(String& str, Array& procEntries, int rangeStart, int rangeEnd, int stackIdx, ProfileProcId* findProc); template typename T::key_type* AddToSet(T& map, typename T::key_type::data_type* data, int size) { typedef T::key_type::data_type DataType; - + typename T::key_type entry; entry.mData = data; entry.mSize = size; - + typename T::key_type* entryPtr; if (map.TryAdd(entry, &entryPtr)) { @@ -187,7 +187,7 @@ public: bool IsSampling() override { return mIsRunning; } String GetOverview() override; - String GetThreadList() override; + String GetThreadList() override; String GetCallTree(int threadId, bool reverse) override; }; diff --git a/IDEHelper/RadixMap.h b/IDEHelper/RadixMap.h index 592d358e..c3ef7af8 100644 --- a/IDEHelper/RadixMap.h +++ b/IDEHelper/RadixMap.h @@ -28,13 +28,12 @@ public: { public: RadixMap32* mRadixMap; - int mRootIdx; + int mRootIdx; int mLeafIdx; public: Iterator() { - } Iterator& operator++() @@ -58,7 +57,7 @@ public: mRootIdx++; } } - + if (mRadixMap->mRoot[mRootIdx]->mValues[mLeafIdx] != NULL) return *this; @@ -86,7 +85,7 @@ public: struct Leaf { - T mValues[LEAF_LENGTH]; + T mValues[LEAF_LENGTH]; T GetFirst(int startLeaf = 0) { @@ -103,23 +102,23 @@ public: value = value->mNext; } return lowestValue; - } + } } return NULL; } }; Leaf* mRoot[ROOT_LENGTH]; // Pointers to 32 child nodes - typedef uint32 Number; + typedef uint32 Number; public: RadixMap32() { memset(mRoot, 0, sizeof(mRoot)); } - + ~RadixMap32() - { + { int leafCount = 0; for (int i = 0; i < ROOT_LENGTH; i++) { @@ -135,8 +134,8 @@ public: { Iterator itr; itr.mRadixMap = this; - itr.mRootIdx = -1; - itr.mLeafIdx = LEAF_LENGTH - 1; + itr.mRootIdx = -1; + itr.mLeafIdx = LEAF_LENGTH - 1; return ++itr; } @@ -144,17 +143,17 @@ public: { Iterator itr; itr.mRadixMap = this; - itr.mRootIdx = ROOT_LENGTH; + itr.mRootIdx = ROOT_LENGTH; itr.mLeafIdx = 0; return itr; } - + void Clear() - { + { for (int i = 0; i < ROOT_LENGTH; i++) { if (mRoot[i] != NULL) - { + { delete mRoot[i]; mRoot[i] = NULL; } @@ -181,18 +180,18 @@ public: return leaf->mValues[i2]; } - T Get(Number addr, int maxOffset = 0) const + T Get(Number addr, int maxOffset = 0) const { int blockOffsetsLeft = (maxOffset + (1 << BLOCK_SHIFT) - 1) >> BLOCK_SHIFT; int blockAddr = (int)(addr >> BLOCK_SHIFT); int i1 = (int)(blockAddr >> LEAF_BITS); int i2 = (int)(blockAddr & (LEAF_LENGTH - 1)); - + // Find closest entry to requested addr Leaf* leaf = mRoot[i1]; int bestDist = 0x7FFFFFFF; T bestValue = NULL; - if (leaf != NULL) + if (leaf != NULL) { T curValue = leaf->mValues[i2]; while (curValue != NULL) @@ -222,7 +221,7 @@ public: i1--; if (i1 < 0) break; - i2 = LEAF_LENGTH - 1; + i2 = LEAF_LENGTH - 1; } leaf = mRoot[i1]; if (leaf != NULL) @@ -244,7 +243,7 @@ public: return NULL; } - + T GetNext(T value) { const Number blockAddr = value->mAddress >> BLOCK_SHIFT; @@ -305,7 +304,7 @@ public: } return NULL; - } + } T GetUnordered(Number addr, int maxReverseOffset) const { @@ -331,7 +330,7 @@ public: blockOffsetsLeft--; } else - { + { i1++; blockOffsetsLeft -= LEAF_LENGTH; } @@ -359,7 +358,7 @@ public: int i2Start; int i2End; if (i1 == i1Start) - { + { i2Start = (int)(blockAddrStart & (LEAF_LENGTH - 1)); i2End = LEAF_LENGTH; } @@ -394,17 +393,17 @@ public: } curValue = curValue->mNext; } - *nextPtr = NULL; + *nextPtr = NULL; } } } void Insert(T value) { - const Number blockAddr = value->mAddress >> BLOCK_SHIFT; + const Number blockAddr = value->mAddress >> BLOCK_SHIFT; const Number i1 = blockAddr >> LEAF_BITS; const Number i2 = blockAddr & (LEAF_LENGTH - 1); - + Leaf* leaf = mRoot[i1]; if (leaf == NULL) { @@ -413,7 +412,7 @@ public: mRoot[i1] = leaf; } - T prevValue = leaf->mValues[i2]; + T prevValue = leaf->mValues[i2]; mRoot[i1]->mValues[i2] = value; value->mNext = prevValue; } @@ -432,14 +431,14 @@ public: { if (curValue == value) { - if (prevValue == NULL) + if (prevValue == NULL) leaf->mValues[i2] = curValue->mNext; else - prevValue->mNext = curValue->mNext; + prevValue->mNext = curValue->mNext; curValue->mNext = NULL; return; } - + prevValue = curValue; curValue = curValue->mNext; } @@ -470,19 +469,18 @@ public: RadixMap64* mRadixMap; int mRootIdx; int mMidIdx; - int mLeafIdx; + int mLeafIdx; public: Iterator() { - } Iterator& operator++() { mLeafIdx++; while (true) - { + { if (mLeafIdx == LEAF_LENGTH) { mLeafIdx = 0; @@ -494,7 +492,7 @@ public: { mMidIdx = 0; - mRootIdx++; + mRootIdx++; while (true) { if (mRootIdx == ROOT_LENGTH) @@ -512,7 +510,7 @@ public: mMidIdx++; } - } + } if (mRadixMap->mRoot[mRootIdx]->mLeafs[mMidIdx]->mValues[mLeafIdx] != NULL) return *this; @@ -563,7 +561,7 @@ public: return NULL; } }; - + struct Mid { Leaf* mLeafs[MID_LENGTH]; @@ -722,7 +720,7 @@ public: } i3 = LEAF_LENGTH - 1; } - + mid = mRoot[i1]; if (mid != NULL) { @@ -829,7 +827,7 @@ public: } void RemoveRange(Number startAddr, Number length) - { + { Number endAddr = BF_MIN(startAddr + length, 0x0001000000000000LL); startAddr = BF_MIN(startAddr, 0x0000FFFFFFFFFFFFLL); @@ -958,7 +956,7 @@ public: } } else - { + { // MID_LENGTH * LEAF_LENGTH is > 4GB, so a mRoot[i1] being NULL indicates no data return NULL; } @@ -992,7 +990,7 @@ public: sMidSize += sizeof(Mid); mRoot[i1] = mid; } - + BF_ASSERT((i2 >= 0) && (i2 < MID_LENGTH)); Leaf* leaf = mid->mLeafs[i2]; if (leaf == NULL) diff --git a/IDEHelper/SpellChecker.cpp b/IDEHelper/SpellChecker.cpp index b28de411..0ea44a59 100644 --- a/IDEHelper/SpellChecker.cpp +++ b/IDEHelper/SpellChecker.cpp @@ -26,9 +26,9 @@ BF_EXPORT SpellChecker* BF_CALLTYPE SpellChecker_Create(const char* langPath) return NULL; } - SpellChecker* spellChecker = new SpellChecker(); + SpellChecker* spellChecker = new SpellChecker(); spellChecker->mHunHandle = hunHandle; - + return spellChecker; } diff --git a/IDEHelper/StrBloomMap.h b/IDEHelper/StrBloomMap.h index 78bc92c4..85e8277a 100644 --- a/IDEHelper/StrBloomMap.h +++ b/IDEHelper/StrBloomMap.h @@ -13,7 +13,7 @@ public: Beefy::BumpAllocator mAlloc; struct Entry - { + { T mValue; Entry* mNext; }; @@ -30,7 +30,7 @@ public: { mMap = map; mCurBucket = 0; - mCurEntry = NULL; + mCurEntry = NULL; } Iterator& operator++() @@ -67,7 +67,7 @@ public: public: int GetHash(const char* str, const char* strEnd) - { + { if (str == NULL) return 0; @@ -83,20 +83,20 @@ public: return curHash & 0x7FFFFFFF; } -public: +public: Entry** mHashHeads; public: StrBloomMap() { - mHashHeads = NULL; + mHashHeads = NULL; } void InsertUnique(int hash, T value) { if (mHashHeads == NULL) mHashHeads = (Entry**)mAlloc.AllocBytes(sizeof(Entry*) * HashSize, alignof(Entry*)); - + int hashIdx = hash % HashSize; Entry* headEntry = mHashHeads[hashIdx]; @@ -116,12 +116,12 @@ public: } Entry* FindFirst(const char* name) - { + { if (mHashHeads == NULL) return NULL; int hash = GetHash(name, NULL) % HashSize; - return mHashHeads[hash]; + return mHashHeads[hash]; } Iterator begin() @@ -138,4 +138,3 @@ public: }; NS_BF_DBG_END - diff --git a/IDEHelper/StrHashMap.h b/IDEHelper/StrHashMap.h index 0677673e..d698bf35 100644 --- a/IDEHelper/StrHashMap.h +++ b/IDEHelper/StrHashMap.h @@ -8,10 +8,10 @@ NS_BF_DBG_BEGIN template class StrHashMap { -public: +public: struct Entry { - T mValue; + T mValue; Entry* mNext; int mHash; }; @@ -102,7 +102,7 @@ public: public: Beefy::BumpAllocator mAlloc; Entry** mHashHeads; - int mHashSize; + int mHashSize; int mCount; public: @@ -140,7 +140,7 @@ public: Entry* checkEntry = mHashHeads[hashIdx]; while (checkEntry != NULL) { - auto nextEntry = checkEntry->mNext; + auto nextEntry = checkEntry->mNext; int newHashIdx = checkEntry->mHash % newHashSize; checkEntry->mNext = newHashHeads[newHashIdx]; newHashHeads[newHashIdx] = checkEntry; @@ -197,5 +197,4 @@ public: } }; - NS_BF_DBG_END diff --git a/IDEHelper/Tests/src/Aliases.bf b/IDEHelper/Tests/src/Aliases.bf index bbf92e82..cac802a5 100644 --- a/IDEHelper/Tests/src/Aliases.bf +++ b/IDEHelper/Tests/src/Aliases.bf @@ -25,6 +25,15 @@ namespace Tests public delegate T Zag(); } + class ClassB + { + typealias AliasB0 = (T a, T2 b, int c); + + public static void MethodB0(List> val) + { + } + } + public static void Test() { T LocalA(int16 a) @@ -60,6 +69,8 @@ namespace Tests var t2 = (1.2f, 3.4); ClassA.AliasA6 v3 = t2; + + ClassB.MethodB0(scope List<(double a, float b, int c)>()); } } } diff --git a/IDEHelper/Tests/src/Append.bf b/IDEHelper/Tests/src/Append.bf index 6d166c47..ddeff8bc 100644 --- a/IDEHelper/Tests/src/Append.bf +++ b/IDEHelper/Tests/src/Append.bf @@ -76,6 +76,13 @@ namespace Tests } } + class ClassF + { + public int mA = 123; + public append String mB = .(1024); + public int mC = 234; + } + static void CheckData(Object obj, int lastAllocSize, uint8[] data) { int objSize = typeof(Object).InstanceSize; @@ -110,6 +117,17 @@ namespace Tests 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10 )); delete:trackedAlloc ce; + + int sizeDiff = Math.Abs(typeof(ClassF).InstanceSize - (1024 + sizeof(int)*5)); + Test.Assert(sizeDiff < 32); + + ClassF cf = scope .(); + cf.mB.Append("Abc"); + Test.Assert(cf.mA == 123); + Test.Assert(cf.mB == "Abc"); + Test.Assert(cf.mB.AllocSize == 1024); + Test.Assert(cf.mC == 234); + cf.mB.Append('!', 2048); } } } diff --git a/IDEHelper/Tests/src/Boxing.bf b/IDEHelper/Tests/src/Boxing.bf index d984c001..fd6e069a 100644 --- a/IDEHelper/Tests/src/Boxing.bf +++ b/IDEHelper/Tests/src/Boxing.bf @@ -1,6 +1,7 @@ #pragma warning disable 168 using System; +using System.Collections; namespace Tests { @@ -86,6 +87,9 @@ namespace Tests var scObjResult = scVariant.GetBoxed(); Test.Assert(scObjResult case .Err); scVariant.Dispose(); + + List l = scope .(); + IEnumerator e = (l != null) ? (.)null : l.GetEnumerator(); } [Test] diff --git a/IDEHelper/Tests/src/Comptime.bf b/IDEHelper/Tests/src/Comptime.bf index 2b2b418c..80c32d30 100644 --- a/IDEHelper/Tests/src/Comptime.bf +++ b/IDEHelper/Tests/src/Comptime.bf @@ -220,7 +220,7 @@ namespace Tests String serializeBuffer = new .(); - Compiler.Assert(!type.IsUnion); + Runtime.Assert(!type.IsUnion); for (let field in type.GetFields()) { diff --git a/IDEHelper/Tests/src/Enums.bf b/IDEHelper/Tests/src/Enums.bf index 5e2ba353..4492d688 100644 --- a/IDEHelper/Tests/src/Enums.bf +++ b/IDEHelper/Tests/src/Enums.bf @@ -137,6 +137,10 @@ namespace Tests EnumG eg = .A; eg.Set(66); Test.Assert(eg == .B); + + var ea = Enum.GetMaxValue(); + Test.Assert(ea == .B); + Test.Assert(Enum.GetCount() == 2); } } } diff --git a/IDEHelper/Tests/src/Expressions.bf b/IDEHelper/Tests/src/Expressions.bf index 4a397103..8c212e32 100644 --- a/IDEHelper/Tests/src/Expressions.bf +++ b/IDEHelper/Tests/src/Expressions.bf @@ -1,6 +1,8 @@ #pragma warning disable 168 using System; +using System.Interop; +using System.Collections; namespace Tests { @@ -24,5 +26,27 @@ namespace Tests inStr.Length > 1 || 2 == 3 }; } + + static void GetName(String str) + { + str.Append(nameof(T)); + } + + [Test] + public static void TestNameof() + { + var point = (x: 3, y: 4); + + Test.Assert(nameof(System) == "System"); + Test.Assert(nameof(System.Collections) == "Collections"); + Test.Assert(nameof(point) == "point"); + Test.Assert(nameof(point.x) == "x"); + Test.Assert(nameof(Tests.Expressions) == "Expressions"); + Test.Assert(nameof(c_int) == "c_int"); + Test.Assert(nameof(List) == "List"); + Test.Assert(nameof(List.Add) == "Add"); + Test.Assert(nameof(TestBasics) == "TestBasics"); + Test.Assert(GetName(.. scope .()) == "T"); + } } } diff --git a/IDEHelper/Tests/src/Extensions.bf b/IDEHelper/Tests/src/Extensions.bf index 6aef2980..961a2bae 100644 --- a/IDEHelper/Tests/src/Extensions.bf +++ b/IDEHelper/Tests/src/Extensions.bf @@ -204,7 +204,7 @@ namespace Tests return mTVal; } - public int GetB() + public new int GetB() { return 2; } @@ -267,6 +267,18 @@ namespace Tests } } + struct TestExtern + { + public extern void MethodA(); + } + + extension TestExtern where T : Char8 + { + public override void MethodA() + { + } + } + [Test] public static void TestBasics() { diff --git a/IDEHelper/Tests/src/FuncRefs.bf b/IDEHelper/Tests/src/FuncRefs.bf index ab01a406..961915ba 100644 --- a/IDEHelper/Tests/src/FuncRefs.bf +++ b/IDEHelper/Tests/src/FuncRefs.bf @@ -201,7 +201,7 @@ namespace Tests extension MethodRefHolder where T : Delegate { - public void Dispose() + public new void Dispose() { delete mVal; } diff --git a/IDEHelper/Tests/src/Generics2.bf b/IDEHelper/Tests/src/Generics2.bf index 7f42cba0..93eb8ee9 100644 --- a/IDEHelper/Tests/src/Generics2.bf +++ b/IDEHelper/Tests/src/Generics2.bf @@ -165,6 +165,36 @@ namespace Tests public static int GenClassMethodB(GenClass a) { return a.test++; } public static int GenClassMethodC(A a) where A : GenClass { return a.test += 1; } + public static TDerived AssertSubtype(TBase instance) + where TDerived : TBase + where TBase : class + { + if (instance == null) + Runtime.FatalError(); + if (TDerived derived = instance as TDerived) + { + return derived; + } + Runtime.FatalError(); + } + + public static int TestOverload(TProc proc) + where TProc : class, delegate void() + { + return 1; + } + + public static int TestOverload(TProc proc) + where TProc : delegate void() + { + return 2; + } + + public static int TestOverload2(function void() proc) + { + return 3; + } + [Test] public static void TestBasics() { @@ -191,6 +221,13 @@ namespace Tests Test.Assert(gci.test == 2); Test.Assert(GenClassMethodC(gci) == 3); Test.Assert(gci.test == 3); + + delegate void() dlg = scope () => {}; + function void() func = () => {}; + Test.Assert(TestOverload(dlg) == 1); + Test.Assert(TestOverload(() => {}) == 2); + Test.Assert(TestOverload(func) == 2); + Test.Assert(TestOverload2(func) == 3); } } } diff --git a/IDEHelper/Tests/src/LocalFunctions.bf b/IDEHelper/Tests/src/LocalFunctions.bf index 937afa99..ac9b283d 100644 --- a/IDEHelper/Tests/src/LocalFunctions.bf +++ b/IDEHelper/Tests/src/LocalFunctions.bf @@ -347,22 +347,29 @@ namespace Tests public static void TestL() { int a = 8; + int b; - int LocalA() + if (a == 8) { - return 9; + b = 9; + + int LocalA() + { + return 9; + } + + int LocalB() + { + int q = b; + return a; + } + + function int() func = => LocalA; + Test.Assert(func() == 9); + + delegate int() dlg = scope => LocalB; + Test.Assert(dlg() == 8); } - - int LocalB() - { - return a; - } - - function int() func = => LocalA; - Test.Assert(func() == 9); - - delegate int() dlg = scope => LocalB; - Test.Assert(dlg() == 8); } } } diff --git a/IDEHelper/Tests/src/MethodCalls.bf b/IDEHelper/Tests/src/MethodCalls.bf index b2a2a985..e48e3886 100644 --- a/IDEHelper/Tests/src/MethodCalls.bf +++ b/IDEHelper/Tests/src/MethodCalls.bf @@ -159,6 +159,47 @@ namespace Tests } + + static void InInt(in int a) + { + Test.Assert(a == 123); +#unwarn + int* aPtr = &a; + *aPtr = 234; + } + + static void CopyStructA(StructA sa) + { +#unwarn + StructA* saPtr = &sa; + saPtr.mA += 1000; + } + + static void InStructA(in StructA sa) + { +#unwarn + StructA* saPtr = &sa; + saPtr.mA += 1000; + } + + static int Named(int p1, float p2, int p3) + { + return 10000 + p1*100 + (int)p2*10 + p3; + } + + static int Named(int p0, int p1, float p2) + { + return 20000 + p0*100 + p1*10 + (.)p2; + } + + static int Named(int p0=1, int p1=2, double p2=3) + { + return 30000 + p0*100 + p1*10 + (.)p2; + } + + static int sIdx = 0; + static int GetNext() => ++sIdx; + [Test] public static void TestBasics() { @@ -206,6 +247,24 @@ namespace Tests var v = ObjMethod(.. scope String()); Test.Assert(v.GetType() == typeof(String)); + + int b = 123; + InInt(b); + Test.Assert(b == 234); + + StructA sa4 = .(400, 401); + CopyStructA(sa4); + Test.Assert(sa4.mA == 400); + InStructA(sa4); + Test.Assert(sa4.mA == 1400); + + Test.Assert(Named(1, 2, p3:3) == 10123); + Test.Assert(Named(p1: 1, 2, p3: 3) == 10123); + Test.Assert(Named(p0: 1, 2, 3) == 20123); + Test.Assert(Named(1, p1:2, 3) == 20123); + Test.Assert(Named(p3:GetNext(), p2:GetNext(), p1:GetNext()) == 10321); + Test.Assert(Named(p2:GetNext(), p1:GetNext(), p0:GetNext()) == 20654); + Test.Assert(Named(p1:9) == 30193); } } } diff --git a/IDEHelper/Tests/src/Mixins.bf b/IDEHelper/Tests/src/Mixins.bf index b7078cf3..2f6ffda9 100644 --- a/IDEHelper/Tests/src/Mixins.bf +++ b/IDEHelper/Tests/src/Mixins.bf @@ -73,6 +73,30 @@ namespace Tests total + 100 } + static mixin GetRef(var a) + { + a += 1000; + ref a + } + + static mixin Unwrap(var res) + { + res.Value + } + + static mixin DisposeIt(T val) where T : IDisposable + { + val?.Dispose(); + } + + class DispClass : IDisposable + { + void IDisposable.Dispose() + { + + } + } + [Test] public static void TestBasics() { @@ -103,6 +127,9 @@ namespace Tests Dictionary> test = scope .() {(1,null)}; int val = CircularMixin!(test); Test.Assert(val == 211); + + DispClass dc = scope .(); + DisposeIt!(dc); } [Test] @@ -125,6 +152,19 @@ namespace Tests AppendAndNullify!(str0); Test.Assert(str0 == null); Test.Assert(str1 == "AB"); + + int b = 12; + GetRef!(b) += 200; + Test.Assert(b == 1212); + + var c = { ref b }; + c = 99; + Test.Assert(b == 99); + + Result svRes = "ab "; + var sv2 = Unwrap!(svRes)..Trim(); + Test.Assert(svRes.Value == "ab "); + Test.Assert(sv2 == "ab"); } } diff --git a/IDEHelper/Tests/src/Nullable.bf b/IDEHelper/Tests/src/Nullable.bf index 852816f9..237d0542 100644 --- a/IDEHelper/Tests/src/Nullable.bf +++ b/IDEHelper/Tests/src/Nullable.bf @@ -1,4 +1,7 @@ +#pragma warning disable 168 + using System; +using System.Collections; namespace Tests { @@ -92,6 +95,25 @@ namespace Tests Test.Assert(DoAdd(iNull, iNull) == 200); Test.Assert(DoAdd(iNull, null) == null); + + String str = "Abc"; + StringView? svn = str; + + iNull = null; + int? iNull2 = 123; + List l = null; + List l2 = scope .(); + + int a = iNull2 ?? l.Count; + int b = iNull ?? l2.Count; + var c = iNull ?? iNull2; + + Test.Assert(a == 123); + Test.Assert(b == 0); + Test.Assert(typeof(decltype(c)) == typeof(int?)); + + iNull ??= iNull2; + Test.Assert(iNull == 123); } } } diff --git a/IDEHelper/Tests/src/Operators.bf b/IDEHelper/Tests/src/Operators.bf index f92600b2..f2b60715 100644 --- a/IDEHelper/Tests/src/Operators.bf +++ b/IDEHelper/Tests/src/Operators.bf @@ -2,6 +2,18 @@ using System; +namespace System +{ + extension RefCounted + { + public static RefCounted Attach(RefCounted val) + { + val.AddRef(); + return val; + } + } +} + namespace System { public extension Event @@ -471,6 +483,16 @@ namespace Tests } } + class ClassA + { + public String value = new .() ~ delete _; + + public void operator+=(StringView value) + { + this.value.Append(value); + } + } + public struct Vector2 : this(float x, float y); public static Event sEvent ~ _.Dispose(); // Workaround for the lack of auto-destructor in properties @@ -709,6 +731,18 @@ namespace Tests Test.Assert(sA == 222); Val += 1000; Test.Assert(sA == 1222); + + RefCounted rcStr = .Create("Abc"); + Test.Assert(rcStr->Length == 3); + rcStr->Clear(); + rcStr.Release(); + + //RefCounted rcB = .Create(); + + ClassA ca = scope .(); + ca += "ab"; + ca += "cd"; + Test.Assert(ca.value == "abcd"); } struct IntStruct @@ -740,8 +774,6 @@ namespace Tests } } - - [Test] public static void TestCompareWithCastOperator() { diff --git a/IDEHelper/Tests/src/Strings.bf b/IDEHelper/Tests/src/Strings.bf index 7cb111be..ce189508 100644 --- a/IDEHelper/Tests/src/Strings.bf +++ b/IDEHelper/Tests/src/Strings.bf @@ -28,6 +28,10 @@ namespace Tests Test.Assert(wStr[2] == 's'); Test.Assert(wStr[3] == 't'); Test.Assert(wStr[4] == '\0'); + + StringView sv = "Abcd"; + sv.Length--; + Test.Assert(sv == "Abc"); } } } diff --git a/IDEHelper/Tests/src/Structs.bf b/IDEHelper/Tests/src/Structs.bf index 241c7602..a0518aa0 100644 --- a/IDEHelper/Tests/src/Structs.bf +++ b/IDEHelper/Tests/src/Structs.bf @@ -298,5 +298,39 @@ namespace Tests Test.Assert(clr.R == 10); Test.Assert(clr.G == 20); } + + struct SplitStruct : this(int32 mA, float mB) + { + int16 mC = 123; + } + + [Test] + static void TestSplitList() + { + SplitList sl = scope .(); + sl.Add(.(1, 2)); + sl.Add(.(3, 4)); + + Test.Assert(sl[0].mA == 1); + Test.Assert(sl[0].mB == 2); + Test.Assert(sl[0].mC == 123); + Test.Assert(sl[1].mA == 3); + Test.Assert(sl[1].mB == 4); + Test.Assert(sl[1].mC == 123); + Test.Assert(sl.Data.mA[0] == 1); + Test.Assert(sl.Data.mA[1] == 3); + Test.Assert(sl.Data.mB[0] == 2); + Test.Assert(sl.Data.mB[1] == 4); + Test.Assert(sl.Data.mC[0] == 123); + Test.Assert(sl.Data.mC[1] == 123); + + SplitStruct s = sl[0]; + Test.Assert(s == .(1, 2)); + + for (var entry in sl) + { + Test.Assert(entry.mA == @entry.Index * 2 + 1); + } + } } } diff --git a/IDEHelper/Tests/src/UsingField.bf b/IDEHelper/Tests/src/UsingField.bf new file mode 100644 index 00000000..6fef581b --- /dev/null +++ b/IDEHelper/Tests/src/UsingField.bf @@ -0,0 +1,87 @@ +using System; + +namespace Tests +{ + class UsingField + { + class ClassA + { + public int mA0 = 1; + public static int sA0 = 2; + } + + class ClassB + { + public int mB0 = 3; + public static int sB0 = 4; + } + + class ClassC + { + public int mC0 = 12; + public int mC1 = 23; + + public int PropC0 => 123; + public int MethodC0() => 234; + + using public static ClassA sA = new .() ~ delete _; + ClassB sB = new .() ~ delete _; + + using public ClassB B => sB; + } + + class ClassD + { + public using protected append ClassC mC; + private using append ClassC mC2; + + public int mD0 = 34; + + public this() + { + mC.mC0 += 10000; + mC2.mC0 += 20000; + + } + } + + [Union] + struct Vector2 + { + public struct Coords + { + public float mX; + public float mY; + } + + public float[2] mValues; + public using Coords mCoords; + + public this(float x, float y) + { + mX = x; + mY = y; + } + } + + [Test] + public static void Test() + { + ClassD cd = scope .(); + cd.mC0 = 123; + Test.Assert(cd.PropC0 == 123); + Test.Assert(cd.MethodC0() == 234); + Test.Assert(cd.mD0 == 34); + + Test.Assert(ClassD.sA0 == 2); + Test.Assert(ClassD.sB0 == 4); + + Vector2 vec = .(1.2f, 2.3f); + Test.Assert(sizeof(Vector2) == 8); + Test.Assert(vec.mX == 1.2f); + Test.Assert(vec.mY == 2.3f); + Test.Assert(vec.mValues[0] == 1.2f); + Test.Assert(vec.mValues[1] == 2.3f); + } + } +} \ No newline at end of file diff --git a/IDEHelper/VSSupport.cpp b/IDEHelper/VSSupport.cpp index 262fc99e..a3bf55a7 100644 --- a/IDEHelper/VSSupport.cpp +++ b/IDEHelper/VSSupport.cpp @@ -56,7 +56,7 @@ struct Find_Result { int windows_sdk_version = 0; // Zero if no Windows SDK found. - wchar_t *windows_sdk_root = NULL; + wchar_t *windows_sdk_root = NULL; wchar_t* vs_version = NULL; wchar_t *vs_exe32_path = NULL; @@ -68,7 +68,7 @@ struct Find_Result { Find_Result find_visual_studio_and_windows_sdk(); void free_resources(Find_Result *result) { - free(result->windows_sdk_root); + free(result->windows_sdk_root); free(result->vs_version); free(result->vs_exe32_path); free(result->vs_exe64_path); @@ -95,10 +95,10 @@ void free_resources(Find_Result *result) { // I am not making this up: https://github.com/Microsoft/vswhere // // Several people have therefore found the need to solve this problem -// themselves. We referred to some of these other solutions when +// themselves. We referred to some of these other solutions when // figuring out what to do, most prominently ziglang's version, // by Ryan Saunderson. -// +// // I hate this kind of code. The fact that we have to do this at all // is stupid, and the actual maneuvers we need to go through // are just painful. If programming were like this all the time, @@ -148,7 +148,6 @@ public: #define defer const auto& CONCAT(defer__, __LINE__) = ExitScopeHelp() + [&]() - // COM objects for the ridiculous Microsoft craziness. struct DECLSPEC_UUID("B41463C3-8866-43B5-BC33-2B0676F7F42E") DECLSPEC_NOVTABLE ISetupInstance : public IUnknown @@ -178,7 +177,6 @@ struct DECLSPEC_UUID("42843719-DB4C-46C2-8E7C-64F1816EFD5B") DECLSPEC_NOVTABLE I STDMETHOD(GetInstanceForPath)(_In_z_ LPCWSTR wzPath, _Out_ ISetupInstance** ppInstance) = 0; }; - // The beginning of the actual code that does things. struct Version_Data { @@ -224,7 +222,6 @@ wchar_t *concat(wchar_t *a, wchar_t *b, wchar_t *c = nullptr, wchar_t *d = nullp typedef void(*Visit_Proc_W)(wchar_t *short_name, wchar_t *full_name, Version_Data *data); bool visit_files_w(wchar_t *dir_name, Version_Data *data, Visit_Proc_W proc) { - // Visit everything in one folder (non-recursively). If it's a directory // that doesn't start with ".", call the visit proc on it. The visit proc // will see if the filename conforms to the expected versioning pattern. @@ -253,7 +250,6 @@ bool visit_files_w(wchar_t *dir_name, Version_Data *data, Visit_Proc_W proc) { return true; } - wchar_t *find_windows_kit_root(HKEY key, wchar_t *version) { // Given a key to an already opened registry entry, // get the value stored under the 'version' subkey. @@ -340,7 +336,7 @@ void find_windows_kit_root(Find_Result *result) { // is stored in the same place in the registry. We open a key // to that place, first checking preferentially for a Windows 10 kit, // then, if that's not found, a Windows 8 kit. - + HKEY main_key; auto rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", @@ -386,7 +382,6 @@ void find_windows_kit_root(Find_Result *result) { // If we get here, we failed to find anything. } - void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) { // The name of this procedure is kind of cryptic. Its purpose is // to fight through Microsoft craziness. The things that the fine @@ -449,7 +444,7 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (!success) continue; auto version_bytes = (tools_file_size.QuadPart + 1) * 2; // Warning: This multiplication by 2 presumes there is no variable-length encoding in the wchars (wacky characters in the file could betray this expectation). - wchar_t *version = (wchar_t *)malloc(version_bytes); + wchar_t *version = (wchar_t *)malloc(version_bytes); auto read_result = fgetws(version, (int)version_bytes, f); if (!read_result) continue; @@ -465,15 +460,15 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res bool use = false; if ((os_file_exists(library_file)) && (os_file_exists(vs_exe64_link_path))) - { + { if (result->vs_version == NULL) { use = true; - } + } else if (wcscmp(version, result->vs_version) > 0) { use = true; - } + } } if (use) @@ -492,7 +487,7 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res free(library32_path); free(library64_path); } - + free(library_file); free(vs_exe64_link_path); @@ -562,7 +557,6 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res // If we get here, we failed to find anything. } - Find_Result find_visual_studio_and_windows_sdk() { Find_Result result; @@ -582,7 +576,7 @@ BF_EXPORT const char* BF_CALLTYPE VSSupport_Find() { Beefy::String& outString = *Beefy::gTLStrReturn.Get(); outString.clear(); - + Find_Result findResult = find_visual_studio_and_windows_sdk(); auto _AddPath = [&](wchar_t* str) @@ -593,11 +587,11 @@ BF_EXPORT const char* BF_CALLTYPE VSSupport_Find() outString += Beefy::UTF8Encode(str); } }; - + if (findResult.vs_exe32_path != NULL) outString += "TOOL32\t" + Beefy::UTF8Encode(findResult.vs_exe32_path) + "\n"; if (findResult.vs_exe64_path != NULL) - outString += "TOOL64\t" + Beefy::UTF8Encode(findResult.vs_exe64_path) + "\n"; + outString += "TOOL64\t" + Beefy::UTF8Encode(findResult.vs_exe64_path) + "\n"; if (findResult.windows_sdk_root != NULL) { @@ -630,7 +624,7 @@ BF_EXPORT const char* BF_CALLTYPE VSSupport_Find() outString += Beefy::UTF8Encode(findResult.vs_library64_path); outString += "\n"; } - + free_resources(&findResult); return outString.c_str(); diff --git a/IDEHelper/WinDebugger.cpp b/IDEHelper/WinDebugger.cpp index 3945753e..f1fabb59 100644 --- a/IDEHelper/WinDebugger.cpp +++ b/IDEHelper/WinDebugger.cpp @@ -118,7 +118,7 @@ void DbgEvaluationContext::Init(WinDebugger* winDebugger, DbgModule* dbgModule, mPassInstance = new BfPassInstance(winDebugger->mBfSystem); auto terminatedExpr = expr + ";"; mParser->SetSource(terminatedExpr.c_str(), terminatedExpr.length()); - mParser->Parse(mPassInstance); + mParser->Parse(mPassInstance); mReducer = new BfReducer(); mReducer->mAlloc = mParser->mAlloc; @@ -130,7 +130,7 @@ void DbgEvaluationContext::Init(WinDebugger* winDebugger, DbgModule* dbgModule, mReducer->mSource = mParser; mExprNode = mReducer->CreateExpression(mParser->mRootNode->GetFirst()); mParser->Close(); - mDbgExprEvaluator = new DbgExprEvaluator(winDebugger, dbgModule, mPassInstance, -1, -1); + mDbgExprEvaluator = new DbgExprEvaluator(winDebugger, dbgModule, mPassInstance, -1, -1); if ((formatInfo != NULL) && (mExprNode != NULL) && (mExprNode->GetSrcEnd() < (int) expr.length())) { @@ -140,7 +140,7 @@ void DbgEvaluationContext::Init(WinDebugger* winDebugger, DbgModule* dbgModule, { mPassInstance->FailAt(errorString, mParser->mSourceData, mExprNode->GetSrcEnd(), (int)expr.length() - mExprNode->GetSrcEnd()); formatFlags = ""; - } + } } if (formatInfo != NULL) @@ -157,20 +157,20 @@ bool DbgEvaluationContext::HasExpression() } DbgEvaluationContext::~DbgEvaluationContext() -{ - delete mParser; - delete mReducer; - delete mDbgExprEvaluator; +{ + delete mParser; + delete mReducer; + delete mDbgExprEvaluator; delete mPassInstance; } DbgTypedValue DbgEvaluationContext::EvaluateInContext(DbgTypedValue contextTypedValue) -{ +{ if (mExprNode == NULL) - return DbgTypedValue(); + return DbgTypedValue(); mPassInstance->ClearErrors(); if (contextTypedValue) - { + { mDbgExprEvaluator->mExplicitThis = contextTypedValue; if ((mDbgExprEvaluator->mExplicitThis.mType->IsPointer()) && (mDbgExprEvaluator->mExplicitThis.mType->mTypeParam->WantsRefThis())) { @@ -192,7 +192,7 @@ DbgTypedValue DbgEvaluationContext::EvaluateInContext(DbgTypedValue contextTyped if (contextTypedValue.mType != NULL) mDbgExprEvaluator->mDbgCompileUnit = contextTypedValue.mType->mCompileUnit; DbgTypedValue exprResult; - auto result = mDbgExprEvaluator->Resolve(mExprNode); + auto result = mDbgExprEvaluator->Resolve(mExprNode); return result; } @@ -287,7 +287,7 @@ static void CreateFilterName(String& name, const char* srcStr, DbgLanguage langu if (c == '<') chevronDepth++; if (inGeneric) // Bundle all generic instances together - continue; + continue; if (c == '[') // Bundle all arrays together name.clear(); if (c == '(') @@ -303,7 +303,7 @@ static void CreateFilterName(String& name, const char* srcStr, DbgLanguage langu } static void CreateFilterName(String& name, DbgSubprogram* subprogram) -{ +{ auto language = subprogram->GetLanguage(); if (subprogram->mName == NULL) { @@ -313,7 +313,7 @@ static void CreateFilterName(String& name, DbgSubprogram* subprogram) return; } name = BfDemangler::Demangle(subprogram->mLinkName, language); - // Strip off the params since we need to generate those ourselves + // Strip off the params since we need to generate those ourselves int parenPos = (int)name.IndexOf('('); if (parenPos != -1) name.RemoveToEnd(parenPos); @@ -323,22 +323,22 @@ static void CreateFilterName(String& name, DbgSubprogram* subprogram) { const char* cPtr = subprogram->mName; if (strncmp(cPtr, "_bf::", 5) == 0) - { - CreateFilterName(name, cPtr + 5, DbgLanguage_Beef); + { + CreateFilterName(name, cPtr + 5, DbgLanguage_Beef); name.Replace(".__BfStaticCtor", ".this$static"); name.Replace(".__BfCtorClear", ".this$clear"); name.Replace(".__BfCtor", ".this"); } else CreateFilterName(name, subprogram->mName, language); - + return; } else { if (subprogram->mParentType != NULL) { - String parentName = subprogram->mParentType->ToString(); + String parentName = subprogram->mParentType->ToString(); CreateFilterName(name, parentName.c_str(), language); if (!name.empty()) { @@ -380,11 +380,11 @@ static void CreateFilterName(String& name, DbgSubprogram* subprogram) ////////////////////////////////////////////////////////////////////////// DbgPendingExpr::DbgPendingExpr() -{ +{ mThreadId = -1; mCallStackIdx = -1; mParser = NULL; - mCursorPos = -1; + mCursorPos = -1; mExprNode = NULL; mIdleTicks = 0; mExplitType = NULL; @@ -394,8 +394,8 @@ DbgPendingExpr::DbgPendingExpr() } DbgPendingExpr::~DbgPendingExpr() -{ - delete mParser; +{ + delete mParser; } // conversion logic based on table at http://en.wikipedia.org/wiki/Extended_precision @@ -455,7 +455,7 @@ static double ConvertFloat80ToDouble(const byte fp80[10]) return s * HUGE_VAL; useExponent += 1023; - + BF_ASSERT((useExponent > 0) && (useExponent < 0x7ff)); // assume we've filtered for valid exponent range BF_ASSERT(m & bit63); // assume we've filtered out values that aren't normalized by now @@ -488,12 +488,12 @@ WinDebugger::WinDebugger(DebugManager* debugManager) : mDbgSymSrv(this) mStepInAssembly = false; mStepSP = 0; mStepIsRecursing = false; - mStepStopOnNextInstruction = false; + mStepStopOnNextInstruction = false; mDebugTarget = NULL; - mShuttingDown = false; - mBfSystem = new BfSystem(); + mShuttingDown = false; + mBfSystem = new BfSystem(); mAtBreakThread = NULL; - mActiveThread = NULL; + mActiveThread = NULL; mActiveBreakpoint = NULL; mSteppingThread = NULL; mExplicitStopThread = NULL; @@ -503,10 +503,10 @@ WinDebugger::WinDebugger(DebugManager* debugManager) : mDbgSymSrv(this) mContinueFromBreakpointFailed = false; mIsStepIntoSpecific = false; mDbgBreak = false; - mDebuggerWaitingThread = NULL; + mDebuggerWaitingThread = NULL; mStepType = StepType_None; mOrigStepType = StepType_None; - mLastValidStepIntoPC = 0; + mLastValidStepIntoPC = 0; mActiveSymSrvRequest = NULL; mStoredReturnValueAddr = 0; @@ -515,10 +515,10 @@ WinDebugger::WinDebugger(DebugManager* debugManager) : mDbgSymSrv(this) #else mCPU = gX86Target->mX64CPU; #endif - mRunState = RunState_NotStarted; - mIsRunning = false; + mRunState = RunState_NotStarted; + mIsRunning = false; mSavedAtBreakpointAddress = 0; - mSavedBreakpointAddressContinuing = 0; + mSavedBreakpointAddressContinuing = 0; mRequestedStackFrameIdx = 0; mShowPCOverride = 0; mCurNoInfoStepTries = 0; @@ -528,30 +528,30 @@ WinDebugger::WinDebugger(DebugManager* debugManager) : mDbgSymSrv(this) mDbgProcessId = 0; mDbgHeapData = NULL; mIsPartialCallStack = true; - + for (int i = 0; i < 4; i++) - { + { mFreeMemoryBreakIndices.push_back(i); } mMemoryBreakpointVersion = 0; SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); - mPageSize = systemInfo.dwPageSize; + mPageSize = systemInfo.dwPageSize; mEmptyDebugTarget = new DebugTarget(this); mEmptyDebugTarget->CreateEmptyTarget(); mEmptyDebugTarget->mIsEmpty = true; - mDebugTarget = mEmptyDebugTarget; + mDebugTarget = mEmptyDebugTarget; mDebugPendingExpr = NULL; mDebugEvalThreadInfo = WdThreadInfo(); - - mMemCacheAddr = 0; - mDebuggerThreadId = 0; + + mMemCacheAddr = 0; + mDebuggerThreadId = 0; } WinDebugger::~WinDebugger() -{ +{ mDestroying = true; delete gDbgPerfManager; @@ -561,7 +561,7 @@ WinDebugger::~WinDebugger() Detach(); for (auto breakpoint : mBreakpoints) - { + { auto checkBreakpoint = breakpoint->mLinkedSibling; while (checkBreakpoint != NULL) { @@ -575,7 +575,7 @@ WinDebugger::~WinDebugger() delete mEmptyDebugTarget; - delete mBfSystem; + delete mBfSystem; for (auto kv : mPendingProfilerMap) delete kv.mValue; for (auto profiler : mNewProfilerList) @@ -602,7 +602,7 @@ void WinDebugger::ThreadRestorePause(WdThreadInfo* onlyPauseThread, WdThreadInfo BfLogDbg("SuspendThread %d\n", threadInfo->mThreadId); ::SuspendThread(threadInfo->mHThread); - + threadInfo->mIsBreakRestorePaused = true; } } @@ -623,11 +623,11 @@ void WinDebugger::ThreadRestoreUnpause() } void WinDebugger::UpdateThreadDebugRegisters(WdThreadInfo* threadInfo) -{ +{ if (threadInfo->mMemoryBreakpointVersion == mMemoryBreakpointVersion) return; - auto threadId = threadInfo->mHThread; + auto threadId = threadInfo->mHThread; BF_CONTEXT lcContext; lcContext.ContextFlags = BF_CONTEXT_DEBUG_REGISTERS; @@ -679,11 +679,11 @@ void WinDebugger::PhysSetBreakpoint(addr_target address) BfLogDbg("PhysSetBreakpoint %p\n", address); uint8 newData = 0xCC; - + // This ensure that we have the orig image data cached DbgMemoryFlags flags = mDebugTarget->ReadOrigImageData(address, NULL, 1); if ((flags & DbgMemoryFlags_Execute) == 0) - { + { BfLogDbg("Breakpoint ignored - execute flag NOT set in breakpoint address\n", address); BfLogDbg("Memory Flags = %d\n", gDebugger->GetMemoryFlags(address)); @@ -708,7 +708,7 @@ void WinDebugger::PhysSetBreakpoint(addr_target address) } void WinDebugger::SetBreakpoint(addr_target address, bool fromRehup) -{ +{ int* countPtr = NULL; if (mPhysBreakpointAddrMap.TryAdd(address, NULL, &countPtr)) { @@ -716,7 +716,7 @@ void WinDebugger::SetBreakpoint(addr_target address, bool fromRehup) *countPtr = 1; } else - { + { if (fromRehup) { BfLogDbg("SetBreakpoint %p Count: %d. Rehup (ignored).\n", address, *countPtr); @@ -739,7 +739,7 @@ void WinDebugger::SetTempBreakpoint(addr_target address) } void WinDebugger::PhysRemoveBreakpoint(addr_target address) -{ +{ BfLogDbg("PhysRemoveBreakpoint %p\n", address); uint8 origData; @@ -760,7 +760,7 @@ void WinDebugger::PhysRemoveBreakpoint(addr_target address) } void WinDebugger::RemoveBreakpoint(addr_target address) -{ +{ int* countPtr = NULL; mPhysBreakpointAddrMap.TryGetValue(address, &countPtr); @@ -771,13 +771,13 @@ void WinDebugger::RemoveBreakpoint(addr_target address) BfLogDbg("RemoveBreakpoint %p FAILED\n", address); return; } - + BfLogDbg("RemoveBreakpoint %p count: %d\n", address, *countPtr); if (*countPtr > 1) { (*countPtr)--; return; - } + } mPhysBreakpointAddrMap.Remove(address); PhysRemoveBreakpoint(address); } @@ -816,10 +816,10 @@ bool WinDebugger::ContinueFromBreakpoint() mDebuggerWaitingThread->mIsAtBreakpointAddress = 0; return true; } - + mActiveThread = mDebuggerWaitingThread; - mActiveBreakpoint = NULL; - + mActiveBreakpoint = NULL; + BfLogDbg("ContinueFromBreakpoint. ActiveThread: %d\n", (mActiveThread != NULL) ? mActiveThread->mThreadId : -1); BfLogDbg("ResumeThread %d\n", mActiveThread->mThreadId); @@ -827,7 +827,7 @@ bool WinDebugger::ContinueFromBreakpoint() if (success) { // It's possible the active thread is suspended - possibly by the GC, so we would deadlock if we - // attempted to pause the other threads + // attempted to pause the other threads BfLogDbg("SuspendThread %d\n", mActiveThread->mThreadId); BfLogDbg("Thread already paused!\n"); ::SuspendThread(mActiveThread->mHThread); @@ -841,7 +841,7 @@ bool WinDebugger::ContinueFromBreakpoint() BF_CONTEXT lcContext; lcContext.ContextFlags = BF_CONTEXT_ALL; - BF_GetThreadContext(mActiveThread->mHThread, &lcContext); + BF_GetThreadContext(mActiveThread->mHThread, &lcContext); lcContext.EFlags |= 0x100; // Set trap flag, which raises "single-step" exception BF_SetThreadContext(mActiveThread->mHThread, &lcContext); @@ -853,11 +853,11 @@ bool WinDebugger::ContinueFromBreakpoint() } void WinDebugger::ValidateBreakpoints() -{ +{ HashSet usedBreakpoints; std::function _AddBreakpoint = [&](WdBreakpoint* breakpoint) - { + { if (breakpoint->mAddr != 0) { usedBreakpoints.Add(breakpoint->mAddr); @@ -880,12 +880,12 @@ void WinDebugger::ValidateBreakpoints() { _AddBreakpoint(checkSibling); checkSibling = (WdBreakpoint*)checkSibling->mLinkedSibling; - } + } }; for (auto breakpoint : mBreakpoints) _AddBreakpoint(breakpoint); - + for (auto& entry : mBreakpointAddrMap) { BF_ASSERT(usedBreakpoints.Contains(entry.mKey)); @@ -911,7 +911,7 @@ Breakpoint* WinDebugger::GetActiveBreakpoint() } void WinDebugger::DebugThreadProc() -{ +{ BpSetThreadName("DebugThread"); BfpThread_SetName(NULL, "DebugThread", NULL); @@ -929,9 +929,9 @@ void WinDebugger::DebugThreadProc() mRunState = RunState_Terminated; } } - + while (!mShuttingDown) - { + { DoUpdate(); } @@ -972,7 +972,7 @@ void WinDebugger::DebugThreadProc() mIsDebuggerWaiting = false; mDebuggerWaitingThread = NULL; } - } + } mDebuggerThreadId = 0; } @@ -1001,7 +1001,7 @@ bool WinDebugger::CanOpen(const StringImpl& fileName, DebuggerResult* outResult) *outResult = DebuggerResult_Ok; bool canRead = DbgModule::CanRead(&fs, outResult); - fclose(fp); + fclose(fp); return canRead; } @@ -1033,18 +1033,18 @@ bool WinDebugger::Attach(int processId, BfDbgAttachFlags attachFlags) return false; } - bool want32Bit = sizeof(intptr_target) == 4; + bool want32Bit = sizeof(intptr_target) == 4; if (want32Bit != (is32Bit != 0)) { mDbgProcessHandle = 0; ::CloseHandle(mDbgProcessHandle); - return false; + return false; } HMODULE mainModule = 0; DWORD memNeeded = 0; ::EnumProcessModules(mDbgProcessHandle, &mainModule, sizeof(HMODULE), &memNeeded); - + WCHAR fileName[MAX_PATH] = {0}; GetModuleFileNameExW(mDbgProcessHandle, mainModule, fileName, MAX_PATH); mLaunchPath = UTF8Encode(fileName); @@ -1060,16 +1060,16 @@ bool WinDebugger::Attach(int processId, BfDbgAttachFlags attachFlags) } void WinDebugger::Run() -{ +{ mIsRunning = true; DWORD localThreadId; HANDLE hThread = ::CreateThread(NULL, 64 * 1024, (LPTHREAD_START_ROUTINE) &DebugThreadProcThunk, (void*)this, 0, &localThreadId); - CloseHandle(hThread); + CloseHandle(hThread); } void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) -{ - AutoCrit autoCrit(mDebugManager->mCritSect); +{ + AutoCrit autoCrit(mDebugManager->mCritSect); if (mDebugTarget->mTargetBinary == NULL) { @@ -1083,20 +1083,20 @@ void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) return; } - BfLogDbg("WinDebugger::HotLoad Start %d\n", hotIdx); + BfLogDbg("WinDebugger::HotLoad Start %d\n", hotIdx); SetAndRestoreValue prevHotIdx(mActiveHotIdx, hotIdx); BF_ASSERT(mHotThreadStates.empty()); mHotThreadStates.Resize(mThreadList.size()); - for (int threadIdx = 0; threadIdx < (int)mThreadList.size(); threadIdx++) - { + for (int threadIdx = 0; threadIdx < (int)mThreadList.size(); threadIdx++) + { WdThreadInfo* threadInfo = mThreadList[threadIdx]; - SetAndRestoreValue prevActiveThread(mActiveThread, threadInfo); + SetAndRestoreValue prevActiveThread(mActiveThread, threadInfo); BfLogDbg("SuspendThread %d\n", threadInfo->mThreadId); ::SuspendThread(threadInfo->mHThread); mHotThreadStates[threadIdx].mThreadId = threadInfo->mThreadId; - PopulateRegisters(&mHotThreadStates[threadIdx].mRegisters); + PopulateRegisters(&mHotThreadStates[threadIdx].mRegisters); } for (auto address : mTempBreakpoint) @@ -1109,27 +1109,27 @@ void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) } int startingModuleIdx = (int)mDebugTarget->mDbgModules.size(); - + bool failed = false; for (auto fileName : objectFiles) { BfLogDbg("WinDebugger::HotLoad: %s\n", fileName.c_str()); - DbgModule* newBinary = mDebugTarget->HotLoad(fileName, hotIdx); + DbgModule* newBinary = mDebugTarget->HotLoad(fileName, hotIdx); if ((newBinary != NULL) && (newBinary->mFailed)) failed = true; } - + for (int moduleIdx = startingModuleIdx; moduleIdx < (int)mDebugTarget->mDbgModules.size(); moduleIdx++) { auto dbgModule = mDebugTarget->mDbgModules[moduleIdx]; BF_ASSERT(dbgModule->IsObjectFile()); BF_ASSERT(dbgModule->mHotIdx == hotIdx); dbgModule->FinishHotSwap(); - } + } for (auto dwarf : mDebugTarget->mDbgModules) dwarf->RevertWritingEnable(); - + int blockAllocSinceClean = mDebugTarget->mHotHeap->mBlockAllocIdx - mDebugTarget->mLastHotHeapCleanIdx; // Clean up the hot heap every 64MB int blocksBetweenCleans = (64 * 1024 * 1024) / HotHeap::BLOCK_SIZE; @@ -1149,7 +1149,7 @@ void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) { auto breakpoint = mBreakpoints[breakIdx]; CheckBreakpoint(breakpoint); - } + } for (int hotThreadIdx = 0; hotThreadIdx < (int)mHotThreadStates.size(); hotThreadIdx++) { @@ -1157,10 +1157,10 @@ void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) WdThreadInfo* threadInfo = NULL; if (!mThreadMap.TryGetValue((uint32)hotThreadState.mThreadId, &threadInfo)) continue; - + BfLogDbg("ResumeThread %d\n", threadInfo->mThreadId); ::ResumeThread(threadInfo->mHThread); - } + } mHotThreadStates.Clear(); @@ -1168,13 +1168,13 @@ void WinDebugger::HotLoad(const Array& objectFiles, int hotIdx) { ClearCallStack(); UpdateCallStack(); - } + } } void WinDebugger::InitiateHotResolve(DbgHotResolveFlags flags) { AutoCrit autoCrit(mDebugManager->mCritSect); - + delete mHotResolveData; mHotResolveData = NULL; @@ -1190,7 +1190,7 @@ intptr WinDebugger::GetDbgAllocHeapSize() { Beefy::String memName = StrFormat("BFGC_stats_%d", mProcessInfo.dwProcessId); - mDbgHeapData = new WinDbgHeapData(); + mDbgHeapData = new WinDbgHeapData(); mDbgHeapData->mFileMapping = ::OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, memName.c_str()); if (mDbgHeapData->mFileMapping == 0) { @@ -1198,8 +1198,8 @@ intptr WinDebugger::GetDbgAllocHeapSize() mDbgHeapData = NULL; return 0; } - - mDbgHeapData->mStats = (WinDbgHeapData::Stats*)MapViewOfFile(mDbgHeapData->mFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(WinDbgHeapData::Stats)); + + mDbgHeapData->mStats = (WinDbgHeapData::Stats*)MapViewOfFile(mDbgHeapData->mFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(WinDbgHeapData::Stats)); } if (mDbgHeapData->mStats == NULL) @@ -1221,10 +1221,10 @@ String WinDebugger::GetDbgAllocInfo() mHotResolveData = new DbgHotResolveData(); DbgHotScanner* hotScanner = new DbgHotScanner(this); hotScanner->Scan((DbgHotResolveFlags)(DbgHotResolveFlag_Allocations | DbgHotResolveFlag_KeepThreadState)); - delete hotScanner; + delete hotScanner; String result; - + if (mHotResolveData != NULL) { DbgExprEvaluator exprEvaluator(this, NULL, NULL, -1, -1); @@ -1259,26 +1259,26 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args, { BP_ZONE("WinDebugger::DoOpenFile"); - AutoCrit autoCrit(mDebugManager->mCritSect); + AutoCrit autoCrit(mDebugManager->mCritSect); //gDbgPerfManager->StartRecording(); STARTUPINFOW si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); - ZeroMemory(&mProcessInfo, sizeof(mProcessInfo)); + ZeroMemory(&mProcessInfo, sizeof(mProcessInfo)); if (mDbgProcessId != 0) { BOOL success = ::DebugActiveProcess(mDbgProcessId); if (!success) - return false; + return false; - mProcessInfo.dwProcessId = mDbgProcessId; + mProcessInfo.dwProcessId = mDbgProcessId; } else { BP_ZONE("DoOpenFile_CreateProcessW"); - + UTF16String envW; DWORD flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_DEFAULT_ERROR_MODE; @@ -1304,7 +1304,7 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args, String cmdLine = "\""; cmdLine += fileName; cmdLine += "\""; - + if (!args.IsEmpty()) { cmdLine += " "; @@ -1313,7 +1313,7 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args, BOOL worked = CreateProcessW(NULL, (WCHAR*)UTF8Decode(cmdLine).c_str(), NULL, NULL, FALSE, flags, envPtr, (WCHAR*)UTF8Decode(workingDir).c_str(), &si, &mProcessInfo); - + if (!worked) { auto lastError = ::GetLastError(); @@ -1334,9 +1334,9 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args, mThreadMap[mProcessInfo.dwThreadId] = threadInfo; mThreadList.push_back(threadInfo); } - + mRunState = RunState_Running; - + while (true) { BP_ZONE("DoOpenFile_WaitForImageBase"); @@ -1345,10 +1345,10 @@ bool WinDebugger::DoOpenFile(const StringImpl& fileName, const StringImpl& args, autoCrit.mCritSect->Lock(); ContinueDebugEvent(); - + if ((mDebugTarget->mLaunchBinary != NULL) && (mDebugTarget->mLaunchBinary->mOrigImageData != NULL)) break; - } + } RehupBreakpoints(true); @@ -1365,13 +1365,13 @@ void WinDebugger::StopDebugging() if (mActiveSymSrvRequest != NULL) mActiveSymSrvRequest->Cancel(); if ((mRunState == RunState_NotStarted) || (mRunState == RunState_Terminated) || (mRunState == RunState_Terminating)) - return; + return; - if ((mDbgProcessId != 0) && ((mDbgAttachFlags & BfDbgAttachFlag_ShutdownOnExit) == 0)) + if ((mDbgProcessId != 0) && ((mDbgAttachFlags & BfDbgAttachFlag_ShutdownOnExit) == 0)) { for (auto address : mTempBreakpoint) RemoveBreakpoint(address); - for (auto breakpoint : mBreakpoints) + for (auto breakpoint : mBreakpoints) DetachBreakpoint(breakpoint); BfLogDbg("StopDebugging\n"); @@ -1385,18 +1385,17 @@ void WinDebugger::StopDebugging() mRunState = RunState_Terminating; BfLogDbg("mRunState = RunState_Terminating\n"); } - } void WinDebugger::Terminate() { AutoCrit autoCrit(mDebugManager->mCritSect); - BfLogDbg("WinDebugger::Terminate\n"); + BfLogDbg("WinDebugger::Terminate\n"); if (mActiveSymSrvRequest != NULL) mActiveSymSrvRequest->Cancel(); if ((mRunState == RunState_NotStarted) || (mRunState == RunState_Terminated) || (mRunState == RunState_Terminating)) - return; - TerminateProcess(mProcessInfo.hProcess, 0); + return; + TerminateProcess(mProcessInfo.hProcess, 0); mRunState = RunState_Terminating; BfLogDbg("mRunState = RunState_Terminating\n"); } @@ -1404,7 +1403,7 @@ void WinDebugger::Terminate() static int gDebugUpdateCnt = 0; void WinDebugger::Detach() -{ +{ BfLogDbg("Debugger Detach\n"); mDebugManager->mNetManager->CancelAll(); @@ -1423,7 +1422,7 @@ void WinDebugger::Detach() for (auto profiler : mNewProfilerList) delete profiler; mNewProfilerList.Clear(); - + mPendingImageLoad.Clear(); mPendingDebugInfoLoad.Clear(); @@ -1432,7 +1431,7 @@ void WinDebugger::Detach() if (mDebugTarget != mEmptyDebugTarget) delete mDebugTarget; mDebugTarget = mEmptyDebugTarget; - + mShuttingDown = false; mStepSP = 0; ClearCallStack(); @@ -1446,7 +1445,7 @@ void WinDebugger::Detach() for (auto threadPair : mThreadMap) { - auto threadInfo = threadPair.mValue; + auto threadInfo = threadPair.mValue; delete threadInfo; } mThreadMap.Clear(); @@ -1473,30 +1472,30 @@ void WinDebugger::Detach() } } - ZeroMemory(&mProcessInfo, sizeof(mProcessInfo)); + ZeroMemory(&mProcessInfo, sizeof(mProcessInfo)); mStepBreakpointAddrs.Clear(); mIsRunning = false; - + mDbgAttachFlags = BfDbgAttachFlag_None; mDbgProcessId = 0; delete mDbgHeapData; mDbgHeapData = NULL; - mDbgProcessHandle = 0; - ClearCallStack(); + mDbgProcessHandle = 0; + ClearCallStack(); mWantsDebugContinue = false; mAtBreakThread = NULL; - mActiveThread = NULL; + mActiveThread = NULL; mActiveBreakpoint = NULL; mSteppingThread = NULL; - mExplicitStopThread = NULL; + mExplicitStopThread = NULL; mIsContinuingFromException = false; - mGotStartupEvent = false; - + mGotStartupEvent = false; + mIsDebuggerWaiting = false; mPhysBreakpointAddrMap.Clear(); mBreakpointAddrMap.Clear(); - - gDebugUpdateCnt = 0; + + gDebugUpdateCnt = 0; } Profiler* WinDebugger::StartProfiling() @@ -1509,7 +1508,7 @@ Profiler* WinDebugger::PopProfiler() AutoCrit autoCrit(mDebugManager->mCritSect); if (mNewProfilerList.IsEmpty()) return NULL; - auto profiler = (DbgProfiler*)mNewProfilerList[0]; + auto profiler = (DbgProfiler*)mNewProfilerList[0]; mNewProfilerList.erase(mNewProfilerList.begin()); return profiler; } @@ -1553,7 +1552,7 @@ bool WinDebugger::GetEmitSource(const StringImpl& filePath, String& outText) void WinDebugger::ModuleChanged(DbgModule* dbgModule) { - mDebugManager->mOutMessages.push_back(String("dbgInfoLoaded ") + dbgModule->mFilePath); + mDebugManager->mOutMessages.push_back(String("dbgInfoLoaded ") + dbgModule->mFilePath); } bool WinDebugger::DoUpdate() @@ -1564,12 +1563,12 @@ bool WinDebugger::DoUpdate() ::DebugSetProcessKillOnExit(TRUE); // - { + { AutoCrit autoCrit(mDebugManager->mCritSect); auto _ModuleChanged = [&](DbgModule* dbgModule) { ModuleChanged(dbgModule); - ClearCallStack(); // We may have actual dbgSubprograms and stuff now... + ClearCallStack(); // We may have actual dbgSubprograms and stuff now... }; for (auto dbgModule : mPendingImageLoad) @@ -1596,7 +1595,7 @@ bool WinDebugger::DoUpdate() for (auto kv : mPendingDebugInfoLoad) pendingList.Add(kv.mValue); mPendingDebugInfoLoad.Clear(); - + for (auto& entry : pendingList) { auto dbgModule = entry.mModule; @@ -1605,11 +1604,11 @@ bool WinDebugger::DoUpdate() // saying "" _ModuleChanged(entry.mModule); } - } + } } if (IsMiniDumpDebugger()) - { + { // { AutoCrit autoCrit(mDebugManager->mCritSect); @@ -1620,34 +1619,34 @@ bool WinDebugger::DoUpdate() } } - Sleep(20); + Sleep(20); return false; } if (mIsDebuggerWaiting) - { + { if ((IsInRunState()) || (mRunState == RunState_Terminating) || (mRunState == RunState_DebugEval)) ContinueDebugEvent(); if (mContinueEvent.WaitFor(8)) - { + { BF_ASSERT(!mWantsDebugContinue); // mWantsDebugContinue should already been reset BfLogDbg("::ContinueDebugEvent 1 ThreadId:%d\n", mDebuggerWaitingThread->mThreadId); BF_ASSERT_REL(mDebuggerWaitingThread->mIsAtBreakpointAddress == 0); ::ContinueDebugEvent(mDebuggerWaitingThread->mProcessId, mDebuggerWaitingThread->mThreadId, mIsContinuingFromException ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE); mIsContinuingFromException = false; mIsDebuggerWaiting = false; - mDebuggerWaitingThread = NULL; + mDebuggerWaitingThread = NULL; } else - return false; + return false; } - + if (!WaitForDebugEvent(&mDebugEvent, 8)) return false; - + gDebugUpdateCnt++; - static const char* eventNames[] = { "DBG_EVENT ?", + static const char* eventNames[] = { "DBG_EVENT ?", "EXCEPTION_DEBUG_EVENT", "CREATE_THREAD_DEBUG_EVENT", "CREATE_PROCESS_DEBUG_EVENT", @@ -1662,26 +1661,26 @@ bool WinDebugger::DoUpdate() BP_ZONE(eventNames[mDebugEvent.dwDebugEventCode]); - AutoCrit autoCrit(mDebugManager->mCritSect); + AutoCrit autoCrit(mDebugManager->mCritSect); mActiveBreakpoint = NULL; mIsDebuggerWaiting = true; mWantsDebugContinue = true; mRequestedStackFrameIdx = 0; mBreakStackFrameIdx = 0; - mShowPCOverride = 0; + mShowPCOverride = 0; WdThreadInfo* threadInfo = NULL; - + mThreadMap.TryGetValue(mDebugEvent.dwThreadId, &threadInfo); mDebuggerWaitingThread = threadInfo; mExplicitStopThread = mDebuggerWaitingThread; - + switch (mDebugEvent.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: - { + { if (threadInfo == NULL) { BF_ASSERT(mThreadMap.size() == 0); @@ -1700,7 +1699,7 @@ bool WinDebugger::DoUpdate() mThreadMap[mDebugEvent.dwThreadId] = newThreadInfo; mDebuggerWaitingThread = newThreadInfo; - mThreadList.push_back(mDebuggerWaitingThread); + mThreadList.push_back(mDebuggerWaitingThread); UpdateThreadDebugRegisters(); OutputMessage(StrFormat("Creating thread from CREATE_PROCESS_DEBUG_EVENT %d\n", mDebugEvent.dwThreadId)); @@ -1730,12 +1729,12 @@ bool WinDebugger::DoUpdate() launchBinary->mImageBase = gotImageBase; launchBinary->mImageSize = (int)launchBinary->GetImageSize(); launchBinary->mOrigImageData = new DbgModuleMemoryCache(launchBinary->mImageBase, launchBinary->mImageSize); - + if (launchBinary == mDebugTarget->mTargetBinary) mDebugTarget->SetupTargetBinary(); - + if (mDebugEvent.u.CreateProcessInfo.hFile != NULL) - CloseHandle(mDebugEvent.u.CreateProcessInfo.hFile); + CloseHandle(mDebugEvent.u.CreateProcessInfo.hFile); mDbgProcessHandle = mDebugEvent.u.CreateProcessInfo.hProcess; mDbgThreadHandle = mDebugEvent.u.CreateProcessInfo.hThread; @@ -1778,11 +1777,11 @@ bool WinDebugger::DoUpdate() mDebugManager->mOutMessages.push_back("modulesChanged"); } break; - case LOAD_DLL_DEBUG_EVENT: - { - WCHAR moduleNameStr[MAX_PATH] = { 0 }; + case LOAD_DLL_DEBUG_EVENT: + { + WCHAR moduleNameStr[MAX_PATH] = { 0 }; GetFinalPathNameByHandleW(mDebugEvent.u.LoadDll.hFile, moduleNameStr, MAX_PATH, FILE_NAME_NORMALIZED); - + std::wstring wow64Dir; std::wstring systemDir; @@ -1791,9 +1790,9 @@ bool WinDebugger::DoUpdate() if (wow64DirPtr != NULL) { wow64Dir = wow64DirPtr; - CoTaskMemFree(wow64DirPtr); + CoTaskMemFree(wow64DirPtr); } - + PWSTR systemDirPtr = NULL; SHGetKnownFolderPath(FOLDERID_System, KF_FLAG_NO_ALIAS, NULL, &systemDirPtr); if (systemDirPtr != NULL) @@ -1801,14 +1800,14 @@ bool WinDebugger::DoUpdate() systemDir = systemDirPtr; CoTaskMemFree(systemDirPtr); } - + if ((mDebugEvent.u.LoadDll.lpImageName != 0) && (mDebugEvent.u.LoadDll.fUnicode)) { addr_target strAddr = ReadMemory((addr_target)(intptr)mDebugEvent.u.LoadDll.lpImageName); for (int i = 0; i < MAX_PATH - 1; i++) { - WCHAR c = ReadMemory(strAddr + i*2); + WCHAR c = ReadMemory(strAddr + i*2); moduleNameStr[i] = (WCHAR)c; if (c == 0) break; @@ -1817,7 +1816,7 @@ bool WinDebugger::DoUpdate() String origModuleName = UTF8Encode(moduleNameStr); String moduleName = origModuleName; - + String loadMsg; HANDLE altFileHandle = INVALID_HANDLE_VALUE; if (moduleName != origModuleName) @@ -1840,7 +1839,7 @@ bool WinDebugger::DoUpdate() loadMsg += " - Skipped"; } #endif - + if (!skipLoad) { FileHandleStream stream; @@ -1849,7 +1848,7 @@ bool WinDebugger::DoUpdate() stream.mFileHandle = altFileHandle; if (mDebugTarget->SetupDyn(moduleName, &stream, (intptr)mDebugEvent.u.LoadDll.lpBaseOfDll) == NULL) loadMsg += " - Failed to load"; - stream.mFileHandle = 0; + stream.mFileHandle = 0; } OutputMessage(loadMsg + "\n"); @@ -1864,9 +1863,9 @@ bool WinDebugger::DoUpdate() } break; case UNLOAD_DLL_DEBUG_EVENT: - { + { bool needsBreakpointRehup = false; - + String name = "???"; DbgModule* dbgModule = mDebugTarget->FindDbgModuleForAddress((addr_target)(intptr)mDebugEvent.u.UnloadDll.lpBaseOfDll); if (dbgModule != NULL) @@ -1874,24 +1873,24 @@ bool WinDebugger::DoUpdate() name = dbgModule->mFilePath; for (int i = 0; i < (int)mBreakpoints.size(); i++) - { + { auto breakpoint = mBreakpoints[i]; auto checkBreakpoint = breakpoint; bool hasAddr = false; while (checkBreakpoint != NULL) { if ((checkBreakpoint->mAddr >= dbgModule->mImageBase) && (checkBreakpoint->mAddr < dbgModule->mImageBase + dbgModule->mImageSize)) - hasAddr = true; + hasAddr = true; checkBreakpoint = (WdBreakpoint*)checkBreakpoint->mLinkedSibling; } if (hasAddr) { - DetachBreakpoint(breakpoint); + DetachBreakpoint(breakpoint); needsBreakpointRehup = true; } } - + mDebugTarget->UnloadDyn(dbgModule->mImageBase); if (needsBreakpointRehup) RehupBreakpoints(true); @@ -1899,7 +1898,7 @@ bool WinDebugger::DoUpdate() mPendingDebugInfoLoad.Remove(dbgModule); mPendingDebugInfoRequests.Remove(dbgModule); mDebugManager->mOutMessages.push_back("modulesChanged"); - } + } if (!name.empty()) OutputMessage(StrFormat("Unloading DLL: %s @ %0s\n", name.c_str(), EncodeDataPtr((addr_target)(intptr)mDebugEvent.u.UnloadDll.lpBaseOfDll, true).c_str())); @@ -1907,8 +1906,8 @@ bool WinDebugger::DoUpdate() BfLogDbg("UNLOAD_DLL_DEBUG_EVENT %s\n", name.c_str()); } break; - case OUTPUT_DEBUG_STRING_EVENT: - { + case OUTPUT_DEBUG_STRING_EVENT: + { const int maxChars = 1024 * 1024; int len = BF_MIN(maxChars, (int)mDebugEvent.u.DebugString.nDebugStringLength); // 1MB max char* message = new char[len + 1]; @@ -1916,18 +1915,18 @@ bool WinDebugger::DoUpdate() message[0] = 0; message[len] = 0; ReadMemory((addr_target)(intptr)mDebugEvent.u.DebugString.lpDebugStringData, len, message); - + if ((mRunState == RunState_DebugEval) && (mDebuggerWaitingThread->mThreadId == mDebugEvalThreadInfo.mThreadId)) mDebugManager->mOutMessages.push_back(String("dbgEvalMsg ") + message); else mDebugManager->mOutMessages.push_back(String("msg ") + message); BfLogDbg("OUTPUT_DEBUG_STRING_EVENT (BreakAddr:%@): %s\n", threadInfo->mIsAtBreakpointAddress, message); - + BF_ASSERT_REL(threadInfo->mIsAtBreakpointAddress == 0); delete [] message; - } + } break; case CREATE_THREAD_DEBUG_EVENT: { @@ -1945,13 +1944,13 @@ bool WinDebugger::DoUpdate() mThreadMap[mDebugEvent.dwThreadId] = threadInfo; mDebuggerWaitingThread = threadInfo; - mThreadList.push_back(mDebuggerWaitingThread); + mThreadList.push_back(mDebuggerWaitingThread); UpdateThreadDebugRegisters(); OutputMessage(StrFormat("Creating thread %d\n", mDebugEvent.dwThreadId)); - } + } break; case EXIT_THREAD_DEBUG_EVENT: - { + { OutputMessage(StrFormat("Exiting thread %d\n", mDebugEvent.dwThreadId)); if (mSteppingThread == threadInfo) { @@ -1966,29 +1965,29 @@ bool WinDebugger::DoUpdate() { // Thread terminated while evaluating! Is there a more graceful way of handling this? CleanupDebugEval(false); - mRunState = RunState_Running; + mRunState = RunState_Running; } mThreadList.Remove(mDebuggerWaitingThread); delete mDebuggerWaitingThread; - mDebuggerWaitingThread = NULL; + mDebuggerWaitingThread = NULL; mThreadMap.Remove(mDebugEvent.dwThreadId); return true; - } + } break; case RIP_EVENT: OutputMessage("RIP Event\n"); break; - case EXCEPTION_DEBUG_EVENT: + case EXCEPTION_DEBUG_EVENT: { - auto exceptionRecord = &mDebugEvent.u.Exception.ExceptionRecord; + auto exceptionRecord = &mDebugEvent.u.Exception.ExceptionRecord; switch (exceptionRecord->ExceptionCode) { case STATUS_WX86_BREAKPOINT: - case EXCEPTION_BREAKPOINT: - { + case EXCEPTION_BREAKPOINT: + { if (mRunState == RunState_Terminating) { BfLogDbg("Ignoring event because of RunState_Terminating\n"); @@ -2007,8 +2006,8 @@ bool WinDebugger::DoUpdate() // Skip the initial Wow64 ntdll.dll!LdrpDoDebuggerBreak mRunState = RunState_Running; break; - } - isHighAddr = true; + } + isHighAddr = true; } #endif @@ -2016,11 +2015,11 @@ bool WinDebugger::DoUpdate() if (isHighAddr) pcAddress = (addr_target)-1; //mStoppedAtAddress = pcAddress; - + bool isStepOut = false; if ((mStepType == StepType_StepOut) || (mStepType == StepType_StepOut_ThenInto)) - { + { isStepOut = mStepBreakpointAddrs.Contains(pcAddress); } @@ -2043,12 +2042,12 @@ bool WinDebugger::DoUpdate() dwSubprogram = mDebugTarget->FindSubProgram(pcAddress, DbgOnDemandKind_LocalOnly); } - bool isLineStart = (dwLineData != NULL) && (dwSubprogram->GetLineAddr(*dwLineData) == pcAddress); + bool isLineStart = (dwLineData != NULL) && (dwSubprogram->GetLineAddr(*dwLineData) == pcAddress); bool isNonDebuggerBreak = false; if (wasDebugBreakpoint) - { - // Go ahead and set EIP back one instruction + { + // Go ahead and set EIP back one instruction BF_CONTEXT_IP(lcContext)--; BF_SetThreadContext(threadInfo->mHThread, &lcContext); @@ -2061,10 +2060,10 @@ bool WinDebugger::DoUpdate() PhysRemoveBreakpoint(pcAddress); break; } - } + } else { - // This was an actual "break" instruction + // This was an actual "break" instruction BfLogDbg("Non-debugger break\n"); isNonDebuggerBreak = true; @@ -2080,14 +2079,14 @@ bool WinDebugger::DoUpdate() BF_ASSERT((prevState == RunState_Running) || (prevState == RunState_DebugEval)); mRunState = prevState; break; // Continue as if nothing happened - } + } if (prevState == RunState_DebugEval) mRequestedStackFrameIdx = -1; // Don't show a rolled back stack idx if a debug eval fails ClearStep(); } - + if (threadInfo->mIsBreakRestorePaused) { // The thread is supposed to be paused, but the IP has been reset @@ -2106,14 +2105,14 @@ bool WinDebugger::DoUpdate() { mNeedsRehupBreakpoints = true; RemoveBreakpoint(breakpoint->mLineData.GetAddress()); - } + } break; } bool isDeeper = false; int stepBreakAddrIdx = (int)mStepBreakpointAddrs.IndexOf(pcAddress); - + WdBreakpoint* breakpoint = NULL; bool ignoreBreakpoint = false; @@ -2137,7 +2136,7 @@ bool WinDebugger::DoUpdate() if (!isStepOut) breakpoint = (WdBreakpoint*)FindBreakpointAt(pcAddress); - // Ignore breakpoint if it's on the line we're stepping off of + // Ignore breakpoint if it's on the line we're stepping off of if ((breakpoint != NULL) && (breakpoint->mAddr == mStepPC) && (mStepSP == BF_CONTEXT_SP(lcContext))) { @@ -2154,8 +2153,8 @@ bool WinDebugger::DoUpdate() BfLogDbg("Ignoring step break (old breakpoint)\n"); if ((mSteppingThread == mAtBreakThread) && (mStepSwitchedThreads)) - { - SetupStep(mStepType); + { + SetupStep(mStepType); } break; } @@ -2166,8 +2165,8 @@ bool WinDebugger::DoUpdate() ThreadRestorePause(mSteppingThread, mActiveThread); threadInfo->mIsAtBreakpointAddress = pcAddress; break; - } - + } + isDeeper = mStepSP > BF_CONTEXT_SP(lcContext); if ((mStepType == StepType_StepOut) || (mStepType == StepType_StepOut_ThenInto)) { @@ -2184,11 +2183,11 @@ bool WinDebugger::DoUpdate() threadInfo->mIsAtBreakpointAddress = pcAddress; break; // Don't fall through, we don't want to set mIsAtBreakpointAddress } - + if (isStepOut) - { + { threadInfo->mIsAtBreakpointAddress = pcAddress; - + if (mStepType == StepType_StepOut_ThenInto) { dwLineData = FindLineDataAtAddress(pcAddress, &dwSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly); @@ -2230,7 +2229,7 @@ bool WinDebugger::DoUpdate() SetupStep(StepType_StepOut); break; } - } + } ClearStep(); mRunState = RunState_Paused; @@ -2238,7 +2237,7 @@ bool WinDebugger::DoUpdate() break; } - + mRunState = RunState_Paused; if (breakpoint != NULL) { @@ -2246,8 +2245,8 @@ bool WinDebugger::DoUpdate() threadInfo->mIsAtBreakpointAddress = breakpoint->mAddr; // Ignore breakpoint on return statement if we're return-stepping - mRunState = RunState_Breakpoint; - } + mRunState = RunState_Breakpoint; + } if ((mStepType == StepType_StepInto) && (dwSubprogram != NULL)) { @@ -2259,7 +2258,7 @@ bool WinDebugger::DoUpdate() mRunState = RunState_Running; SetupStep(StepType_StepOut_ThenInto); break; - } + } } if ((mStepType == StepType_StepOver) && (stepBreakAddrIdx == 0) && (mStepBreakpointAddrs[0] != 0) && (mStepBreakpointAddrs.size() > 1)) @@ -2278,19 +2277,19 @@ bool WinDebugger::DoUpdate() if ((mStepType == StepType_StepOver) && (stepBreakAddrIdx > 0) && (mStepBreakpointAddrs[0] != 0) && (isDeeper)) { - // This is the first time we've hit the target breakpoint. + // This is the first time we've hit the target breakpoint. if (HasSteppedIntoCall()) { - mStepIsRecursing = true; + mStepIsRecursing = true; RemoveBreakpoint(mStepBreakpointAddrs[0]); mStepBreakpointAddrs[0] = 0; - //mStepBreakpointAddrs.erase(mStepBreakpointAddrs.begin()); - } + //mStepBreakpointAddrs.erase(mStepBreakpointAddrs.begin()); + } } if ((mStepType == StepType_StepOver) && (mStepIsRecursing) && (stepBreakAddrIdx != -1) && (isDeeper)) { - // Decrement so the equality test on "step out" marks us as not being deeper when we + // Decrement so the equality test on "step out" marks us as not being deeper when we // hit the expected SP BfLogDbg("Converting StepOver to StepOut\n"); mStepSP--; @@ -2308,7 +2307,7 @@ bool WinDebugger::DoUpdate() // mTempBreakpoints will have 2 entries if we are on a 'call' line. If we have an inlined call immediately following a call, then we // assume we're hitting a return break /*if ((dwSubprogram != NULL) && (dwSubprogram->mInlineParent != NULL) && (pcAddress == dwSubprogram->mBlock.mLowPC) && (mTempBreakpoint.size() < 2)) - { + { BfLogDbg("Attempting StepOver of inlined method\n"); SetupStep(StepType_StepOut); mRunState = RunState_Running; @@ -2318,14 +2317,14 @@ bool WinDebugger::DoUpdate() //TODO: The previous logic with the "(mTempBreakpoint.size() < 2)" was causing Try!(Method()); stepovers to enter into Try!. What did we mean by // "assume we're hitting a return break"? if ((dwSubprogram != NULL) && (dwSubprogram->mInlineeInfo != NULL) && (pcAddress == dwSubprogram->mBlock.mLowPC)) - { + { RemoveTempBreakpoints(); BfLogDbg("Attempting StepOver of inlined method\n"); SetupStep(StepType_StepOut); mRunState = RunState_Running; break; - } - } + } + } if (mStepType == StepType_StepOut_Inline) { @@ -2336,7 +2335,7 @@ bool WinDebugger::DoUpdate() auto origLineData = FindLineDataAtAddress(mStepStartPC, &origSubprogram); DbgSubprogram* curSubprogram = NULL; auto curLineData = FindLineDataAtAddress(pcAddress, &curSubprogram); - if ((origLineData != NULL) && + if ((origLineData != NULL) && ((origLineData == curLineData) || ((origSubprogram == curSubprogram) && (origLineData->mLine == curLineData->mLine)))) { @@ -2345,11 +2344,11 @@ bool WinDebugger::DoUpdate() break; } } - + ClearStep(); break; } - + if ((mStepType != StepType_None) && (ignoreBreakpoint) && (!mStepInAssembly) && (stepBreakAddrIdx == -1)) { // Ignore breakpoint by just continuing... @@ -2358,15 +2357,15 @@ bool WinDebugger::DoUpdate() } RemoveTempBreakpoints(); - + if ((mStepType != StepType_None) && (!mStepInAssembly) && (!isLineStart) && (stepBreakAddrIdx != -1)) { - SetupStep(mStepType); + SetupStep(mStepType); mRunState = RunState_Running; - } + } else { - //if (mStepType != StepType_Return) + //if (mStepType != StepType_Return) if (stepBreakAddrIdx != -1) { // Even if we've detected we're at a breakpoint, we mark ourselves as just stepping if we also @@ -2376,7 +2375,7 @@ bool WinDebugger::DoUpdate() if (mRunState == RunState_Paused) ClearStep(); - } + } if (ignoreBreakpoint) { @@ -2390,7 +2389,7 @@ bool WinDebugger::DoUpdate() CheckConditionalBreakpoint(breakpoint, dwSubprogram, pcAddress); } } - else + else { breakpoint = (WdBreakpoint*)FindBreakpointAt((uintptr_t)exceptionRecord->ExceptionAddress); if ((breakpoint != NULL) && (!CheckConditionalBreakpoint(breakpoint, dwSubprogram, pcAddress))) @@ -2402,7 +2401,7 @@ bool WinDebugger::DoUpdate() break; } if (breakpoint != NULL) - { + { BfLogDbg("Breakpoint hit. mIsAtBreakpointAddress = %p\n", breakpoint->mAddr); threadInfo->mIsAtBreakpointAddress = breakpoint->mAddr; mRunState = RunState_Breakpoint; @@ -2425,15 +2424,15 @@ bool WinDebugger::DoUpdate() } } else - { + { BfLogDbg("Ignoring break (old or ignored breakpoint)\n"); - mRunState = RunState_Running; + mRunState = RunState_Running; } } if ((breakpoint != NULL) && (!ignoreBreakpoint)) { - mActiveBreakpoint = breakpoint; + mActiveBreakpoint = breakpoint; mBreakStackFrameIdx = -1; } @@ -2442,8 +2441,8 @@ bool WinDebugger::DoUpdate() } break; case STATUS_WX86_SINGLE_STEP: - case EXCEPTION_SINGLE_STEP: - { + case EXCEPTION_SINGLE_STEP: + { if (mRunState == RunState_Terminating) { BfLogDbg("Ignoring event because of RunState_Terminating\n"); @@ -2458,18 +2457,18 @@ bool WinDebugger::DoUpdate() if (mRunState == RunState_HotStep) { - BF_ASSERT(mActiveThread == mDebuggerWaitingThread); + BF_ASSERT(mActiveThread == mDebuggerWaitingThread); mRunState = RunState_Paused; break; } - + mActiveThread = mDebuggerWaitingThread; BF_CONTEXT lcContext; lcContext.ContextFlags = BF_CONTEXT_ALL; - BF_GetThreadContext(mActiveThread->mHThread, &lcContext); + BF_GetThreadContext(mActiveThread->mHThread, &lcContext); addr_target pcAddress = BF_CONTEXT_IP(lcContext); - + bool wasUnfilteredStep = mStepType == StepType_StepInto_Unfiltered; if (mStepType == StepType_StepInto_UnfilteredSingle) { @@ -2491,10 +2490,10 @@ bool WinDebugger::DoUpdate() break; } } - + BF_ASSERT(foundBreakpoint != NULL); - DbgSubprogram* subprogram = mDebugTarget->FindSubProgram(pcAddress); + DbgSubprogram* subprogram = mDebugTarget->FindSubProgram(pcAddress); if (CheckConditionalBreakpoint(foundBreakpoint, subprogram, pcAddress)) { if (foundBreakpoint != NULL) @@ -2530,15 +2529,15 @@ bool WinDebugger::DoUpdate() BfLogDbg("Continuing breakpoint at %p WantsReset:%d\n", threadInfo->mBreakpointAddressContinuing, wantsBreakpoint); if (wantsBreakpoint) - { + { PhysSetBreakpoint(threadInfo->mBreakpointAddressContinuing); } threadInfo->mBreakpointAddressContinuing = NULL; hadBreakpointContinue = true; - ThreadRestoreUnpause(); + ThreadRestoreUnpause(); } - + if ((mSteppingThread != NULL) && (mSteppingThread != mActiveThread)) { // This SINGLE_STEP happened in the wrong thread - we need the stepping thread to do the stepping! @@ -2547,23 +2546,23 @@ bool WinDebugger::DoUpdate() SingleStepX86(); break; } - + bool isDeeper = mStepSP > BF_CONTEXT_SP(lcContext); if ((mStepSwitchedThreads) && (mStepType == StepType_StepOver) && (isDeeper)) { if (HasSteppedIntoCall()) - { - // Since we switched threads, we needed to do a hardware step which has placed us inside a + { + // Since we switched threads, we needed to do a hardware step which has placed us inside a // call, so we need to step out of that now... - SetupStep(StepType_StepOut_NoFrame); + SetupStep(StepType_StepOut_NoFrame); break; } } - // If we don't have a mStepBreakpointAddrs set, that means we're stepping through individual instructions -- - // so process the new location here + // If we don't have a mStepBreakpointAddrs set, that means we're stepping through individual instructions -- + // so process the new location here if (((mStepType == StepType_StepInto) || (mStepType == StepType_StepInto_Unfiltered) || (mStepType == StepType_StepOver)) && (mStepBreakpointAddrs.size() == 0)) - { + { DbgSubprogram* dwSubprogram = NULL; DbgLineData* dwLineData = FindLineDataAtAddress(pcAddress, &dwSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly); @@ -2587,11 +2586,11 @@ bool WinDebugger::DoUpdate() } // Column of -1 means "Illegal", keep stepping! - if ((mStepInAssembly) || + if ((mStepInAssembly) || ((dwLineData != NULL) && (dwLineData->IsStackFrameSetup()) && (dwLineData->mColumn >= 0) && ((dwSubprogram->GetLineAddr(*dwLineData) == pcAddress) || (mStepStopOnNextInstruction)))) - { - // Hit a line while stepping, we're done! + { + // Hit a line while stepping, we're done! mRunState = RunState_Paused; StepLineTryPause(pcAddress, false); if (mRunState == RunState_Paused) @@ -2616,20 +2615,20 @@ bool WinDebugger::DoUpdate() SetupStep(mStepType); } else if (dwSubprogram != NULL) - { + { if ((dwSubprogram->mHotReplaceKind == DbgSubprogram::HotReplaceKind_Replaced) && ((mStepType == StepType_StepInto) || (mStepType == StepType_StepInto_Unfiltered))) { SingleStepX86(); } else { - // Inside a line's instruction, keep going + // Inside a line's instruction, keep going SetupStep(mStepType); mCurNoInfoStepTries = 0; // Reset } } else if (mStepType == StepType_StepInto_Unfiltered) - { + { CPUInst inst; if (mDebugTarget->DecodeInstruction(pcAddress, &inst)) { @@ -2655,7 +2654,7 @@ bool WinDebugger::DoUpdate() } else { - // No debug info! + // No debug info! bool doStepOut = false; if (mCurNoInfoStepTries < 16) { @@ -2687,7 +2686,7 @@ bool WinDebugger::DoUpdate() break; default: { - bool isSystemException = + bool isSystemException = (exceptionRecord->ExceptionCode >= STATUS_ACCESS_VIOLATION) && (exceptionRecord->ExceptionCode <= STATUS_ASSERTION_FAILURE); @@ -2710,7 +2709,7 @@ bool WinDebugger::DoUpdate() }; THREADNAME_INFO* threadNameInfo = (THREADNAME_INFO*)exceptionRecord->ExceptionInformation; - + DwFormatInfo formatInfo; formatInfo.mRawString = true; String nameStr = ReadString(DbgType_SChar, (intptr)threadNameInfo->szName, false, 1024, formatInfo, false); @@ -2726,7 +2725,7 @@ bool WinDebugger::DoUpdate() { namingThreadInfo->mName = nameStr; FilterThreadName(namingThreadInfo->mName); - } + } } else if (((int32)exceptionRecord->ExceptionInformation[0] == 0x1001) && ((int32)exceptionRecord->ExceptionInformation[1] == 0x1002)) { @@ -2739,12 +2738,12 @@ bool WinDebugger::DoUpdate() addr_target mErrorStr; }; - FailMessage failMessage = ReadMemory(exceptionRecord->ExceptionInformation[2]); + FailMessage failMessage = ReadMemory(exceptionRecord->ExceptionInformation[2]); DwFormatInfo formatInfo; String failStr = ReadString(DbgType_SChar16, failMessage.mErrorStr, false, 8192, formatInfo, false); - mDebugManager->mOutMessages.push_back(StrFormat("error Run-Time Check Failure %d - %s", exceptionRecord->ExceptionInformation[6], failStr.c_str())); - mRunState = RunState_Paused; + mDebugManager->mOutMessages.push_back(StrFormat("error Run-Time Check Failure %d - %s", exceptionRecord->ExceptionInformation[6], failStr.c_str())); + mRunState = RunState_Paused; mRequestedStackFrameIdx = -2; // -2 = "auto" handled = true; } @@ -2758,28 +2757,28 @@ bool WinDebugger::DoUpdate() } } else - { + { BfLogDbg("EXCEPTION in thread %d at %p\n", threadInfo->mThreadId, exceptionRecord->ExceptionAddress); OutputDebugStrF("EXCEPTION\n"); mActiveThread = threadInfo; - memcpy(&mCurException, exceptionRecord, sizeof(EXCEPTION_RECORD)); - - if (mRunState == RunState_DebugEval) + memcpy(&mCurException, exceptionRecord, sizeof(EXCEPTION_RECORD)); + + if (mRunState == RunState_DebugEval) { if ((intptr)mCurException.ExceptionAddress == 42) - { + { BfLogDbg("RunState_DebugEval_Done\n"); OutputDebugStrF(" RunState_DebugEval_Done\n"); } else - { + { BfLogDbg("Exception at 0x%@ in thread %d, exception code 0x%08X", mCurException.ExceptionAddress, mActiveThread->mThreadId, mCurException.ExceptionCode); mDebugPendingExpr->mException = StrFormat("Exception at 0x%@ in thread %d, exception code 0x%08X", mCurException.ExceptionAddress, mActiveThread->mThreadId, mCurException.ExceptionCode); } mRunState = RunState_DebugEval_Done; - + mExplicitStopThread = mActiveThread; mRequestedStackFrameIdx = mDebugPendingExpr->mCallStackIdx; } @@ -2790,14 +2789,14 @@ bool WinDebugger::DoUpdate() } } break; - } + } } break; } if ((mDebugEvalThreadInfo.mThreadId != 0) && (mRunState != RunState_DebugEval) && (mRunState != RunState_DebugEval_Done)) { - CleanupDebugEval(); + CleanupDebugEval(); } // Stepping done? @@ -2824,11 +2823,11 @@ void WinDebugger::Update() if (mDebugPendingExpr->mIdleTicks >= 2) { BfLogDbg("Finishing pending expr in thread %d\n", mDebugEvalThreadInfo.mThreadId); - + mRunState = RunState_Paused; - CleanupDebugEval(); - } - } + CleanupDebugEval(); + } + } } else if (mDebugPendingExpr != NULL) { @@ -2879,21 +2878,20 @@ void WinDebugger::ContinueDebugEvent() mContinueEvent.Set(); return; } - } + } if ((mRunState == RunState_Breakpoint) || (mRunState == RunState_Paused)) - { + { ClearCallStack(); mRunState = RunState_Running; } - + mDebuggerWaitingThread->mStoppedAtAddress = 0; mWantsDebugContinue = false; BF_ASSERT_REL(mDebuggerWaitingThread->mIsAtBreakpointAddress == 0); - mContinueEvent.Set(); + mContinueEvent.Set(); } - static BOOL CALLBACK WdEnumWindowsProc(HWND hwnd, LPARAM lParam) { HWND owner = GetWindow(hwnd, GW_OWNER); @@ -2926,17 +2924,17 @@ DbgLineData* WinDebugger::FindLineDataAtAddress(addr_target address, DbgSubprogr auto dwSubprogram = mDebugTarget->FindSubProgram((addr_target)address, onDemandKind); if (dwSubprogram == NULL) return NULL; - + FixupLineDataForSubprogram(dwSubprogram); auto lineData = dwSubprogram->FindClosestLine(address, outSubProgram, outSrcFile, outLineIdx); - + return lineData; } DbgLineData* WinDebugger::FindLineDataInSubprogram(addr_target address, DbgSubprogram* dwSubprogram) { auto dwCompileUnit = dwSubprogram->mCompileUnit; - + FixupLineDataForSubprogram(dwSubprogram); auto lineData = dwSubprogram->FindClosestLine(address); return lineData; @@ -2957,11 +2955,11 @@ bool WinDebugger::IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgL StepFilter* stepFilterPtr; if (mDebugManager->mStepFilters.TryGetValue(filterName, &stepFilterPtr)) - { + { switch (stepFilterPtr->mFilterKind) { case BfStepFilterKind_Default: - doDefault = true; + doDefault = true; break; case BfStepFilterKind_Filtered: dbgSubprogram->mIsStepFiltered = true; @@ -2973,7 +2971,7 @@ bool WinDebugger::IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgL } else { - doDefault = true; + doDefault = true; } if (doDefault) @@ -2994,9 +2992,9 @@ bool WinDebugger::IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgL dbgSrcFile->mFileExistKind = dbgSubprogram->mCompileUnit->mDbgModule->CheckSourceFileExist(dbgSrcFile->GetLocalPath()); dbgSrcFile->mStepFilterVersion = mDebugManager->mStepFilterVersion; } - + switch (dbgSrcFile->mFileExistKind) - { + { case DbgFileExistKind_NotFound: return true; case DbgFileExistKind_HasOldSourceCommand: @@ -3023,16 +3021,16 @@ void WinDebugger::RemoveTempBreakpoints() // else // { // BfLogDbg("Ignoring remove on temp breakpoint %p\n", address); -// } +// } } mTempBreakpoint.Clear(); mStepBreakpointAddrs.Clear(); } void WinDebugger::RehupBreakpoints(bool doFlush) -{ +{ BfLogDbg("RehupBreakpoints\n"); - + // First pass- detach breakpoints that need to be rebound for (int i = 0; i < (int)mBreakpoints.size(); i++) { @@ -3044,9 +3042,9 @@ void WinDebugger::RehupBreakpoints(bool doFlush) { // This breakpoint was already bound, but we loaded a debug module that also had this file so rebind it DetachBreakpoint(breakpoint); - } - - breakpoint = (WdBreakpoint*)breakpoint->mLinkedSibling; + } + + breakpoint = (WdBreakpoint*)breakpoint->mLinkedSibling; } } @@ -3055,8 +3053,8 @@ void WinDebugger::RehupBreakpoints(bool doFlush) { auto breakpoint = mBreakpoints[i]; while (breakpoint != NULL) - { - CheckBreakpoint(breakpoint); + { + CheckBreakpoint(breakpoint); if (breakpoint->mAddr != 0) SetBreakpoint(breakpoint->mAddr, true); breakpoint = (WdBreakpoint*)breakpoint->mLinkedSibling; @@ -3067,18 +3065,18 @@ void WinDebugger::RehupBreakpoints(bool doFlush) } bool WinDebugger::WantsBreakpointAt(addr_target address) -{ +{ if (mTempBreakpoint.Contains(address)) return true; for (auto breakpoint : mBreakpoints) - { + { WdBreakpoint* checkBreakpoint = breakpoint; while (checkBreakpoint != NULL) { if (address == checkBreakpoint->mAddr) return true; checkBreakpoint = (WdBreakpoint*)checkBreakpoint->mLinkedSibling; - } + } } return false; } @@ -3096,7 +3094,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil bool foundInSequence = false; DbgSubprogram* lastFoundSubprogram = NULL; - + int highestHotIdx = -1; bool foundLine = false; @@ -3104,9 +3102,9 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil int bestLineOffset = 0x7FFFFFFF; auto _CheckLineInfo = [&](DbgSubprogram* dbgSubprogram, DbgLineInfo* dbgLineInfo) - { + { // Scan first so we can determine if we want to do fix up line data or not. - bool hasNear = false; + bool hasNear = false; int maxLineDist = 6; for (int lineIdx = 0; lineIdx < dbgLineInfo->mLines.mSize; lineIdx++) @@ -3130,7 +3128,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil { //TODO: Do fixup lineData... ? auto lineData = &dbgLineInfo->mLines[lineIdx]; - auto& ctx = dbgLineInfo->mContexts[lineData->mCtxIdx]; + auto& ctx = dbgLineInfo->mContexts[lineData->mCtxIdx]; if (ctx.mSrcFile != srcFile) continue; @@ -3143,7 +3141,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil // { // // Use the later entry (same logic from DisassembleAt) // continue; -// } +// } // } // } @@ -3160,7 +3158,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil auto subProgram = mDebugTarget->FindSubProgram(address); if (subProgram->mNeedLineDataFixup) FixupLineDataForSubprogram(subProgram); - + if (subProgram != NULL) highestHotIdx = BF_MAX(highestHotIdx, subProgram->mCompileUnit->mDbgModule->mHotIdx); @@ -3193,7 +3191,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil wdBreakpoint->mRequestedLineNum = headBreakpoint->mRequestedLineNum; wdBreakpoint->mLineNum = headBreakpoint->mLineNum; wdBreakpoint->mColumn = headBreakpoint->mColumn; - wdBreakpoint->mInstrOffset = headBreakpoint->mInstrOffset; + wdBreakpoint->mInstrOffset = headBreakpoint->mInstrOffset; wdBreakpoint->mIsLinkedSibling = true; wdBreakpoint->mHead = headBreakpoint; } @@ -3212,7 +3210,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil wdBreakpoint->mSrcFile = ctx.mSrcFile; wdBreakpoint->mLineData = DbgLineDataEx(lineData, subProgram); wdBreakpoint->mBreakpointType = BreakpointType_User; - wdBreakpoint->mAddr = address; + wdBreakpoint->mAddr = address; if ((mDebuggerWaitingThread != NULL) && (mDebuggerWaitingThread->mStoppedAtAddress == address)) { @@ -3242,7 +3240,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil bestLineNum = lineData->mLine; bestLineOffset = lineOffset; } - } + } } }; @@ -3252,10 +3250,10 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil break; bestLineNum = -1; - bestLineOffset = 0x7FFFFFFF; - + bestLineOffset = 0x7FFFFFFF; + if (hotIdx >= 0) - { + { if (hotIdx >= srcFile->mHotReplacedDbgLineInfo.size()) return; @@ -3270,7 +3268,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil for (auto subprogram : srcFile->mLineDataRefs) _CheckLineInfo(subprogram, subprogram->mLineInfo); } - + if (foundLine) break; @@ -3290,7 +3288,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint, DbgSrcFile* srcFil highestCheckHotIdx = hotIdx - 1; for (int hotFileIdx = highestCheckHotIdx; hotFileIdx >= 0; hotFileIdx--) - { + { auto& hotReplacedDbgLineData = wdBreakpoint->mSrcFile->mHotReplacedDbgLineInfo; // Only try to bind to an old hot version if we haven't unloaded the hot module if ((hotFileIdx < (int)hotReplacedDbgLineData.size()) && (hotReplacedDbgLineData[hotFileIdx]->mEntries.size() > 0)) @@ -3368,13 +3366,13 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) wdBreakpoint->mMemoryBreakpointInfo->mMemoryWatchSlotBitmap |= 1<mAddr != 0) return; - + if (!wdBreakpoint->mSymbolName.IsEmpty()) { auto headBreakpoint = wdBreakpoint->GetHeadBreakpoint(); @@ -3388,7 +3386,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) } for (auto dbgModule : mDebugTarget->mDbgModules) - { + { dbgModule->ParseSymbolData(); addr_target targetAddr = -1; @@ -3415,7 +3413,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) wdBreakpoint->mAddr = targetAddr; wdBreakpoint->mBreakpointType = BreakpointType_User; mBreakpointAddrMap.ForceAdd(wdBreakpoint->mAddr, wdBreakpoint); - SetBreakpoint(wdBreakpoint->mAddr); + SetBreakpoint(wdBreakpoint->mAddr); } else { @@ -3423,7 +3421,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) // Insert at head wdBreakpoint->mLinkedSibling = headBreakpoint->mLinkedSibling; headBreakpoint->mLinkedSibling = wdBreakpoint; - wdBreakpoint->mSymbolName = headBreakpoint->mSymbolName; + wdBreakpoint->mSymbolName = headBreakpoint->mSymbolName; wdBreakpoint->mIsLinkedSibling = true; wdBreakpoint->mHead = headBreakpoint; } @@ -3431,7 +3429,7 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) if (onlyBindFirst) break; } - } + } return; } @@ -3440,23 +3438,22 @@ void WinDebugger::CheckBreakpoint(WdBreakpoint* wdBreakpoint) // Rehup if we load a DLL that also uses this file we bound to (thus the mDeferredRefs check) if (wdBreakpoint->mSrcFile == NULL) { - DbgSrcFile* srcFile = mDebugTarget->GetSrcFile(wdBreakpoint->mFilePath); + DbgSrcFile* srcFile = mDebugTarget->GetSrcFile(wdBreakpoint->mFilePath); if (srcFile == NULL) return; for (auto& deferredSrcFileRef : srcFile->mDeferredRefs) { deferredSrcFileRef.mDbgModule->ParseCompileUnit(deferredSrcFileRef.mCompileUnitId); - } srcFile->mDeferredRefs.Clear(); - CheckBreakpoint(wdBreakpoint, srcFile, wdBreakpoint->mRequestedLineNum, -1); + CheckBreakpoint(wdBreakpoint, srcFile, wdBreakpoint->mRequestedLineNum, -1); } } bool WinDebugger::IsMemoryBreakpointSizeValid(addr_target addr, int size) -{ +{ int wantBindCount = 0; int bytesLeft = size; addr_target curAddr = addr; @@ -3467,7 +3464,7 @@ bool WinDebugger::IsMemoryBreakpointSizeValid(addr_target addr, int size) #ifdef BF_DBG_64 if ((bytesLeft >= 8) && ((curAddr & 7) == 0)) curByteCount = 8; - else + else #endif if ((bytesLeft >= 4) && ((curAddr & 3) == 0)) curByteCount = 4; @@ -3503,16 +3500,16 @@ Breakpoint* WinDebugger::CreateBreakpoint(const StringImpl& fileName, int lineNu BfLogDbg("CreateBreakpoint %s %d %d\n", fileName.c_str(), lineNum, wantColumn); WdBreakpoint* wdBreakpoint = new WdBreakpoint(); - wdBreakpoint->mFilePath = FixPathAndCase(fileName); + wdBreakpoint->mFilePath = FixPathAndCase(fileName); wdBreakpoint->mRequestedLineNum = lineNum; - wdBreakpoint->mLineNum = lineNum; + wdBreakpoint->mLineNum = lineNum; wdBreakpoint->mColumn = wantColumn; wdBreakpoint->mInstrOffset = instrOffset; - mBreakpoints.push_back(wdBreakpoint); + mBreakpoints.push_back(wdBreakpoint); BfLogDbg("CreateBreakpoint Created %p\n", wdBreakpoint); - return wdBreakpoint; + return wdBreakpoint; } void WinDebugger::CheckBreakpoint(Breakpoint* checkBreakpoint) @@ -3528,7 +3525,7 @@ Breakpoint* WinDebugger::CreateMemoryBreakpoint(intptr addr, int byteCount) BfLogDbg("CreateMemoryBreakpoint %p %d\n", addr, byteCount); - WdBreakpoint* wdBreakpoint = new WdBreakpoint(); + WdBreakpoint* wdBreakpoint = new WdBreakpoint(); WdMemoryBreakpointInfo* memoryBreakInfo = new WdMemoryBreakpointInfo(); memoryBreakInfo->mMemoryAddress = addr; @@ -3570,12 +3567,12 @@ Breakpoint* WinDebugger::CreateAddressBreakpoint(intptr inAddress) mDebuggerWaitingThread->mIsAtBreakpointAddress = address; } - mBreakpoints.push_back(wdBreakpoint); + mBreakpoints.push_back(wdBreakpoint); return wdBreakpoint; } void WinDebugger::DeleteBreakpoint(Breakpoint* breakpoint) -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); WdBreakpoint* wdBreakpoint = (WdBreakpoint*)breakpoint; @@ -3638,7 +3635,7 @@ void WinDebugger::DeleteBreakpoint(Breakpoint* breakpoint) void WinDebugger::DetachBreakpoint(Breakpoint* breakpoint) { AutoCrit autoCrit(mDebugManager->mCritSect); - + BfLogDbg("WinDebugger::DetachBreakpoint %p\n", breakpoint); WdBreakpoint* wdBreakpoint = (WdBreakpoint*)breakpoint; @@ -3652,7 +3649,7 @@ void WinDebugger::DetachBreakpoint(Breakpoint* breakpoint) if ((mDebuggerWaitingThread != NULL) && (mDebuggerWaitingThread->mBreakpointAddressContinuing == wdBreakpoint->mAddr)) mDebuggerWaitingThread->mBreakpointAddressContinuing = NULL; wdBreakpoint->mLineData = DbgLineDataEx(); - wdBreakpoint->mAddr = 0; + wdBreakpoint->mAddr = 0; } if (wdBreakpoint->mCondition != NULL) @@ -3666,7 +3663,7 @@ void WinDebugger::DetachBreakpoint(Breakpoint* breakpoint) for (int memoryWatchSlot = 0; memoryWatchSlot < 4; memoryWatchSlot++) { if (mMemoryBreakpoints[memoryWatchSlot].mBreakpoint == wdBreakpoint) - { + { mFreeMemoryBreakIndices.push_back(memoryWatchSlot); mMemoryBreakpoints[memoryWatchSlot] = WdMemoryBreakpointBind(); mMemoryBreakpointVersion++; @@ -3694,8 +3691,8 @@ void WinDebugger::MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantCo AutoCrit autoCrit(mDebugManager->mCritSect); DetachBreakpoint(wdBreakpoint); - - //TODO: This doesn't actually rebind correctly while the app is running + + //TODO: This doesn't actually rebind correctly while the app is running if ((lineNum != -1) && (wantColumn != -1)) { wdBreakpoint->mRequestedLineNum = lineNum; @@ -3703,7 +3700,7 @@ void WinDebugger::MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantCo wdBreakpoint->mColumn = wantColumn; } if (rebindNow) - CheckBreakpoint(wdBreakpoint); + CheckBreakpoint(wdBreakpoint); } void WinDebugger::MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount) @@ -3711,21 +3708,21 @@ void WinDebugger::MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int AutoCrit autoCrit(mDebugManager->mCritSect); WdBreakpoint* wdBreakpoint = (WdBreakpoint*)breakpoint; - DetachBreakpoint(wdBreakpoint); + DetachBreakpoint(wdBreakpoint); wdBreakpoint->mMemoryBreakpointInfo->mMemoryAddress = addr; wdBreakpoint->mMemoryBreakpointInfo->mByteCount = byteCount; CheckBreakpoint(wdBreakpoint); } void WinDebugger::DisableBreakpoint(Breakpoint* breakpoint) -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); WdBreakpoint* wdBreakpoint = (WdBreakpoint*)breakpoint; DetachBreakpoint(wdBreakpoint); delete wdBreakpoint->mMemoryBreakpointInfo; - wdBreakpoint->mMemoryBreakpointInfo = NULL; + wdBreakpoint->mMemoryBreakpointInfo = NULL; } void WinDebugger::SetBreakpointCondition(Breakpoint* breakpoint, const StringImpl& conditionExpr) @@ -3736,10 +3733,10 @@ void WinDebugger::SetBreakpointCondition(Breakpoint* breakpoint, const StringImp BF_ASSERT(!wdBreakpoint->mIsLinkedSibling); if (conditionExpr.empty()) - { + { delete wdBreakpoint->mCondition; WdBreakpoint* curBreakpoint = wdBreakpoint; - wdBreakpoint->mCondition = NULL; + wdBreakpoint->mCondition = NULL; } else { @@ -3747,7 +3744,7 @@ void WinDebugger::SetBreakpointCondition(Breakpoint* breakpoint, const StringImp auto condition = new WdBreakpointCondition(); condition->mExpr = conditionExpr; wdBreakpoint->mCondition = condition; - } + } } void WinDebugger::SetBreakpointLogging(Breakpoint* breakpoint, const StringImpl& logging, bool breakAfterLogging) @@ -3772,7 +3769,7 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro if ((mActiveThread != NULL) && (mActiveThread->mThreadId != headBreakpoint->mThreadId)) return false; } - + auto _SplitExpr = [&](const StringImpl& expr, StringImpl& outExpr, StringImpl& outSubject) { int crPos = expr.IndexOf('\n'); @@ -3836,8 +3833,8 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro PopulateRegisters(&wdStackFrame->mRegisters); mCallStack.Add(wdStackFrame); DbgTypedValue result = conditional->mDbgEvaluationContext->EvaluateInContext(DbgTypedValue()); - ClearCallStack(); - + ClearCallStack(); + if ((result.mType != NULL) && (result.mType->mTypeCode == DbgType_Bitfield)) result.mType = result.mType->mTypeParam; @@ -3848,7 +3845,6 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro { if (!error->mIsWarning) errorStr = error->mError; - } String condError = StrFormat("error Conditional breakpoint expression '%s' failed: %s", conditional->mExpr.c_str(), errorStr.c_str()); mDebugManager->mOutMessages.push_back(condError); @@ -3866,7 +3862,6 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro } else if (!result.mBool) return false; - } headBreakpoint->mHitCount++; @@ -3893,7 +3888,7 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro ClearCallStack(); DwFormatInfo formatInfo; - formatInfo.mCallStackIdx = 0; + formatInfo.mCallStackIdx = 0; DbgCompileUnit* dbgCompileUnit = NULL; if (dbgSubprogram == NULL) @@ -3901,13 +3896,13 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro if (dbgSubprogram != NULL) { dbgCompileUnit = dbgSubprogram->mCompileUnit; - formatInfo.mLanguage = dbgSubprogram->GetLanguage(); + formatInfo.mLanguage = dbgSubprogram->GetLanguage(); } auto prevRunState = mRunState; mRunState = RunState_Paused; // We need to be paused to avoid certain errors in the eval String displayString; - + String expr; _SplitExpr(headBreakpoint->mLogging, expr, formatInfo.mSubjectExpr); if (expr.StartsWith("@Beef:")) @@ -3923,7 +3918,7 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro ProcessEvalString(dbgCompileUnit, DbgTypedValue(), expr, displayString, formatInfo, NULL, false); mRunState = prevRunState; - + displayString.Insert(0, "log "); displayString.Append("\n"); @@ -3997,7 +3992,7 @@ bool WinDebugger::HasLineInfoAt(addr_target address) } void WinDebugger::StepLineTryPause(addr_target address, bool requireExactMatch) -{ +{ if (mStepInAssembly) return; @@ -4017,17 +4012,17 @@ void WinDebugger::StepLineTryPause(addr_target address, bool requireExactMatch) } // If we're on the same line but a different column or a <= address then keep it keep looking - if ((dbgSrcFile == mStepLineData.GetSrcFile()) && + if ((dbgSrcFile == mStepLineData.GetSrcFile()) && ((!requireExactMatch) || (dwLineData != mStepLineData.mLineData) || (address <= mStepStartPC)) && (dwLineData->mLine == mStepLineData.mLineData->mLine)) - { + { SetupStep(mStepType); mRunState = RunState_Running; return; } } } - + mRunState = RunState_Paused; } @@ -4038,7 +4033,7 @@ void WinDebugger::BreakAll() } void WinDebugger::StepInto(bool inAssembly) -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); if (!TryRunContinue()) @@ -4067,7 +4062,7 @@ void WinDebugger::StepIntoSpecific(intptr inAddr) mCurNoInfoStepTries = 0; // Reset mStepInAssembly = false; - SetupStep(StepType_StepInto); + SetupStep(StepType_StepInto); mIsStepIntoSpecific = true; mStepType = StepType_StepInto_Unfiltered; if (mStepStartPC != addr) @@ -4090,7 +4085,7 @@ void WinDebugger::PushValue(CPURegisters* registers, int64 val) void WinDebugger::PushValue(CPURegisters* registers, const DbgTypedValue& typedValue) { addr_target* regSP = registers->GetSPRegisterRef(); - + int byteCount = typedValue.mType->GetByteCount(); if ((byteCount == 8) || (sizeof(addr_target) == 8)) { @@ -4108,7 +4103,7 @@ void WinDebugger::PushValue(CPURegisters* registers, const DbgTypedValue& typedV if (typedValue.mType->IsCompositeType()) val = typedValue.mSrcAddress; WriteMemory(*regSP, val); - } + } } void WinDebugger::SetThisRegister(CPURegisters* registers, addr_target val) @@ -4125,9 +4120,9 @@ void WinDebugger::AddParamValue(int paramIdx, bool hadThis, CPURegisters* regist #if BF_DBG_32 PushValue(registers, typedValue); #else - int regIdx = paramIdx + (hadThis ? 1 : 0); + int regIdx = paramIdx + (hadThis ? 1 : 0); if (typedValue.mType->IsFloat()) - { + { PushValue(registers, typedValue); if (regIdx < 4) { @@ -4144,7 +4139,7 @@ void WinDebugger::AddParamValue(int paramIdx, bool hadThis, CPURegisters* regist else { PushValue(registers, typedValue); - if (regIdx < 4) + if (regIdx < 4) { int64 val; if (typedValue.mType->IsCompositeType()) @@ -4165,7 +4160,7 @@ void WinDebugger::AddParamValue(int paramIdx, bool hadThis, CPURegisters* regist } bool WinDebugger::CheckNeedsSRetArgument(DbgType* retType) -{ +{ if (!retType->IsCompositeType()) return false; @@ -4183,7 +4178,6 @@ bool WinDebugger::CheckNeedsSRetArgument(DbgType* retType) return true; } - DbgTypedValue WinDebugger::ReadReturnValue(CPURegisters* registers, DbgType* type) { DbgTypedValue retValue; @@ -4191,7 +4185,7 @@ DbgTypedValue WinDebugger::ReadReturnValue(CPURegisters* registers, DbgType* typ if (type->IsFloat()) { retValue.mType = type; -#if BF_DBG_32 +#if BF_DBG_32 retValue.mDouble = ConvertFloat80ToDouble(registers->mFpMmRegsArray[0].fp.fp80); if (type->mSize == 4) retValue.mSingle = (float)retValue.mDouble; @@ -4201,7 +4195,7 @@ DbgTypedValue WinDebugger::ReadReturnValue(CPURegisters* registers, DbgType* typ else retValue.mDouble = registers->mXmmDRegsArray[0].d[0]; #endif - } + } else if (type->IsCompositeType()) { retValue.mType = type; @@ -4223,12 +4217,12 @@ DbgTypedValue WinDebugger::ReadReturnValue(CPURegisters* registers, DbgType* typ } } else - { + { #ifdef BF_DBG_32 retValue.mType = type; retValue.mInt32 = registers->mIntRegs.eax; - if (type->mSize == 8) - (&retValue.mInt32)[1] = registers->mIntRegs.edx; + if (type->mSize == 8) + (&retValue.mInt32)[1] = registers->mIntRegs.edx; #else retValue.mType = type; retValue.mInt64 = registers->mIntRegs.rax; @@ -4241,12 +4235,12 @@ DbgTypedValue WinDebugger::ReadReturnValue(CPURegisters* registers, DbgType* typ bool WinDebugger::SetRegisters(CPURegisters* registers) { - BF_CONTEXT lcContext; - lcContext.ContextFlags = BF_CONTEXT_CONTROL | BF_CONTEXT_INTEGER | BF_CONTEXT_FLOATING_POINT | BF_CONTEXT_EXTENDED_REGISTERS | BF_CONTEXT_SEGMENTS; + BF_CONTEXT lcContext; + lcContext.ContextFlags = BF_CONTEXT_CONTROL | BF_CONTEXT_INTEGER | BF_CONTEXT_FLOATING_POINT | BF_CONTEXT_EXTENDED_REGISTERS | BF_CONTEXT_SEGMENTS; lcContext.ContextFlags |= BF_CONTEXT_EXCEPTION_REQUEST; BF_GetThreadContext(mActiveThread->mHThread, &lcContext); - + #ifdef BF_DBG_32 lcContext.Eax = registers->mIntRegs.eax; lcContext.Ecx = registers->mIntRegs.ecx; @@ -4296,13 +4290,13 @@ bool WinDebugger::SetRegisters(CPURegisters* registers) //lcContext.ContextFlags |= BF_CONTEXT_EXCEPTION_REQUEST; - BF_SetThreadContext(mActiveThread->mHThread, &lcContext); + BF_SetThreadContext(mActiveThread->mHThread, &lcContext); return (lcContext.ContextFlags & (BF_CONTEXT_EXCEPTION_ACTIVE | BF_CONTEXT_SERVICE_ACTIVE)) == 0; } void WinDebugger::SaveAllRegisters() -{ +{ BfLogDbg("SaveAllRegisters setting mSavedAtBreakpointAddress = %p\n", mActiveThread->mIsAtBreakpointAddress); mSavedAtBreakpointAddress = mActiveThread->mIsAtBreakpointAddress; mSavedBreakpointAddressContinuing = mActiveThread->mBreakpointAddressContinuing; @@ -4311,7 +4305,7 @@ void WinDebugger::SaveAllRegisters() } void WinDebugger::RestoreAllRegisters() -{ +{ BfLogDbg("RestoreAllRegisters setting mIsAtBreakpointAddress = %p\n", mSavedAtBreakpointAddress); mActiveThread->mIsAtBreakpointAddress = mSavedAtBreakpointAddress; mActiveThread->mBreakpointAddressContinuing = mSavedBreakpointAddressContinuing; @@ -4356,17 +4350,17 @@ void WinDebugger::SetRunState(RunState runState) } bool WinDebugger::TryRunContinue() -{ +{ if (mRunState == RunState_Exception) { mIsContinuingFromException = true; - mRunState = RunState_Paused; + mRunState = RunState_Paused; } if (((mRunState == RunState_Paused) || (mRunState == RunState_Breakpoint)) && (mNeedsRehupBreakpoints)) RehupBreakpoints(true); - return true; + return true; } void WinDebugger::ClearStep() @@ -4378,7 +4372,7 @@ void WinDebugger::ClearStep() mStepType = StepType_None; mStepStartPC = 0; mStepSP = 0; - mStepPC = 0; + mStepPC = 0; mIsStepIntoSpecific = false; mStepIsRecursing = false; mStepStopOnNextInstruction = false; @@ -4386,20 +4380,20 @@ void WinDebugger::ClearStep() } bool WinDebugger::SetupStep(StepType stepType) -{ +{ BP_ZONE("SetupStep"); RemoveTempBreakpoints(); if (mNeedsRehupBreakpoints) RehupBreakpoints(true); - + if (mOrigStepType == StepType_None) mOrigStepType = stepType; mStepType = stepType; mSteppingThread = mActiveThread; mStepSwitchedThreads = false; mContinueFromBreakpointFailed = false; - + CPURegisters registers; PopulateRegisters(®isters); addr_target pcAddress = registers.GetPC(); @@ -4411,30 +4405,30 @@ bool WinDebugger::SetupStep(StepType stepType) mStepLineData = DbgLineDataEx(dbgLineData, dbgSubprogram); mStepStartPC = registers.GetPC(); } - + bool isDeeper = mStepSP > registers.GetSP(); BfLogDbg("SetupStep %d PC:%p SP:%p StepStartSP:%p Thread:%d\n", stepType, (addr_target)registers.GetPC(), (addr_target)registers.GetSP(), (addr_target)mStepSP, mSteppingThread->mThreadId); - + mStepSP = registers.GetSP(); mStepPC = registers.GetPC(); if ((mStepType == StepType_StepOut) || (mStepType == StepType_StepOut_NoFrame) || (mStepType == StepType_StepOut_ThenInto)) - { + { if (mStepType != StepType_StepOut_NoFrame) { // Test for stepping out of an inline method DbgSubprogram* dwSubprogram = mDebugTarget->FindSubProgram(pcAddress); if ((dwSubprogram != NULL) && (dwSubprogram->mInlineeInfo != NULL)) - { + { DbgSubprogram* topSubprogram = dwSubprogram->GetRootInlineParent(); - + if ((mOrigStepType == StepType_StepInto) || (mOrigStepType == StepType_StepInto_Unfiltered)) { mStepType = mOrigStepType; } else - { + { mStepType = StepType_StepOut_Inline; // Set up pcAddress to detect recursion //TODO: We can't set a physical breakpoint here because we will immediately hit it when attempting to step over an inlined method. @@ -4446,7 +4440,7 @@ bool WinDebugger::SetupStep(StepType stepType) addr_target endAddress = dwSubprogram->mBlock.mHighPC; if (dwSubprogram->mHasLineAddrGaps) - { + { // Keep bumping out the address as long as we can find lines that contain the nextPC addr_target nextAddr = pcAddress; for (auto& lineInfo : topSubprogram->mLineInfo->mLines) @@ -4464,7 +4458,7 @@ bool WinDebugger::SetupStep(StepType stepType) if (nextAddr != pcAddress) endAddress = nextAddr; } - + BfLogDbg("Stepping out of inlined method, end address: %p\n", endAddress); SetTempBreakpoint(endAddress); mStepBreakpointAddrs.push_back(endAddress); @@ -4472,13 +4466,13 @@ bool WinDebugger::SetupStep(StepType stepType) addr_target decodeAddress = dwSubprogram->mBlock.mLowPC; while (decodeAddress < endAddress) { - CPUInst inst; + CPUInst inst; if (!mDebugTarget->DecodeInstruction(decodeAddress, &inst)) break; addr_target targetAddress = inst.GetTarget(); // We need to find a targetAddress - if ((targetAddress != 0) && + if ((targetAddress != 0) && !((targetAddress >= dwSubprogram->mBlock.mLowPC) && (targetAddress < dwSubprogram->mBlock.mHighPC)) && ((targetAddress >= topSubprogram->mBlock.mLowPC) && (targetAddress < topSubprogram->mBlock.mHighPC))) { @@ -4489,7 +4483,7 @@ bool WinDebugger::SetupStep(StepType stepType) decodeAddress += inst.GetLength(); } - + return true; } } @@ -4513,7 +4507,7 @@ bool WinDebugger::SetupStep(StepType stepType) mStepSP = 0; } else - { + { addr_target oldAddress = pcAddress; CPUInst inst; @@ -4528,7 +4522,7 @@ bool WinDebugger::SetupStep(StepType stepType) #ifdef BF_DBG_32 if (!inst.StackAdjust(mStepSP)) break; -#endif +#endif DbgSubprogram* checkSubprogram = NULL; auto checkLineData = FindLineDataAtAddress(pcAddress, &checkSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly); if (checkLineData == NULL) @@ -4546,7 +4540,7 @@ bool WinDebugger::SetupStep(StepType stepType) BfLogDbg("SetupStep Stepout SetTempBreakpoint %p\n", pcAddress); SetTempBreakpoint(pcAddress); - mStepBreakpointAddrs.push_back(pcAddress); + mStepBreakpointAddrs.push_back(pcAddress); if (mStepType != StepType_StepOut_ThenInto) mStepType = StepType_StepOut; } @@ -4573,7 +4567,7 @@ bool WinDebugger::SetupStep(StepType stepType) // Just do stepovers until we eventually step out //BF_DBG_FATAL("StepOut Failed"); BfLogDbg("StepOut Failed\n"); - + if (mLastValidStepIntoPC != 0) { BfLogDbg("Using mLastValidStepIntoPC: %p\n", mLastValidStepIntoPC); @@ -4591,11 +4585,11 @@ bool WinDebugger::SetupStep(StepType stepType) { BfLogDbg("Stopping"); mStepType = StepType_None; - mRunState = RunState_Paused; + mRunState = RunState_Paused; return true; } - } - } + } + } } if ((mStepType != StepType_StepOut) && (mStepType != StepType_StepOut_ThenInto)) @@ -4609,7 +4603,7 @@ bool WinDebugger::SetupStep(StepType stepType) // if the current PC is actually at an instruction start, so we do a single step with a // slower stack call check to see if we need to step out after a "step over" BfLogDbg("Step - switched threads mIsAtBreakpointAddress:%p\n", mSteppingThread->mIsAtBreakpointAddress); - mStepSwitchedThreads = true; + mStepSwitchedThreads = true; SingleStepX86(); return true; } @@ -4621,19 +4615,19 @@ bool WinDebugger::SetupStep(StepType stepType) { bool isAtLine = false; DbgSubprogram* dwSubprogram = NULL; - + auto dwLineData = FindLineDataAtAddress(pcAddress, &dwSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly); isAtLine = (instIdx > 0) && (dwLineData != NULL) && (dwLineData->IsStackFrameSetup()) && (dwSubprogram->GetLineAddr(*dwLineData) == pcAddress); // "Never step into" line if ((dwLineData != NULL) && (dwLineData->mColumn == -2) && (stepType == StepType_StepInto)) - stepType = StepType_StepOver; + stepType = StepType_StepOver; - CPUInst inst; + CPUInst inst; if (!mDebugTarget->DecodeInstruction(pcAddress, &inst)) { BfLogDbg("Decode failed, set up SingleStepX86 %p\n", pcAddress); - SingleStepX86(); + SingleStepX86(); mStepStopOnNextInstruction = true; return true; } @@ -4661,9 +4655,9 @@ bool WinDebugger::SetupStep(StepType stepType) { // Continue - sets a breakpoint on the call line to detect recursion. // The next loop through will set a breakpoint on the line after the return - BfLogDbg("StepHadCall\n"); + BfLogDbg("StepHadCall\n"); breakOnNext = true; - + BfLogDbg("StepHadCall setting mIsAtBreakpointAddress = %p\n", pcAddress); mSteppingThread->mIsAtBreakpointAddress = pcAddress; @@ -4675,7 +4669,7 @@ bool WinDebugger::SetupStep(StepType stepType) if (inst.IsCall()) { if ((mLastValidStepIntoPC == 0) || (dwSubprogram != NULL)) - mLastValidStepIntoPC = pcAddress + inst.mSize; + mLastValidStepIntoPC = pcAddress + inst.mSize; } if ((dwLineData != NULL) && (inst.IsBranch())) @@ -4698,7 +4692,7 @@ bool WinDebugger::SetupStep(StepType stepType) { if (nextInst.IsBranch()) { - // repne jmp - this appears in __chkstk (for example) + // repne jmp - this appears in __chkstk (for example) // We don't have a good way to "step over" this one, so just do a single step } else @@ -4738,7 +4732,7 @@ bool WinDebugger::SetupStep(StepType stepType) SetTempBreakpoint(pcAddress); mStepBreakpointAddrs.push_back(pcAddress); break; - } + } } // Not an interesting instruction - move to next @@ -4764,12 +4758,12 @@ bool WinDebugger::SetupStep(StepType stepType) } void WinDebugger::CheckNonDebuggerBreak() -{ +{ enum MessageType { MessageType_None = 0, MessageType_Error = 1, - MessageType_ProfilerCmd = 2 + MessageType_ProfilerCmd = 2 }; CPURegisters registers; @@ -4799,7 +4793,7 @@ void WinDebugger::CheckNonDebuggerBreak() llvm::SmallVector strBuf; int strLen = messageData.mBufParamLen; strBuf.resize(strLen + 1); - + char* str = &strBuf[0]; str[strLen] = 0; if (ReadMemory(messageData.mBufParam, strLen, str)) @@ -4847,7 +4841,7 @@ void WinDebugger::CheckNonDebuggerBreak() mDebugManager->mOutMessages.push_back("newProfiler"); mNewProfilerList.push_back(profiler); - } + } } } else if (strcmp(cmd, "StopSampling") == 0) @@ -4859,17 +4853,17 @@ void WinDebugger::CheckNonDebuggerBreak() Profiler* profiler; if (mPendingProfilerMap.Remove(sessionId, &profiler)) - { + { if (profiler->IsSampling()) { // Need to unlock so we don't deadlock mDebugManager->mCritSect.Unlock(); profiler->Stop(); - mDebugManager->mCritSect.Lock(); + mDebugManager->mCritSect.Lock(); } } } - } + } else if (strcmp(cmd, "ClearSampling") == 0) { for (auto& kv : mPendingProfilerMap) @@ -4914,7 +4908,7 @@ void WinDebugger::CheckNonDebuggerBreak() { if ((symbol == "DbgBreakPoint") || (symbol == "RtlUserThreadStart") || (symbol == "RtlUserThreadStart@8")) { - showMainThread = true; + showMainThread = true; } } #ifdef BF_DBG_32 @@ -4969,13 +4963,13 @@ void WinDebugger::StepOver(bool inAssembly) mCurNoInfoStepTries = 0; // Reset mStepInAssembly = inAssembly; - + SetupStep(StepType_StepOver); ContinueDebugEvent(); } void WinDebugger::StepOut(bool inAssembly) -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); BfLogDbg("StepOut\n"); @@ -4983,8 +4977,8 @@ void WinDebugger::StepOut(bool inAssembly) if (!TryRunContinue()) return; - mCurNoInfoStepTries = 0; // Reset - mStepInAssembly = inAssembly; + mCurNoInfoStepTries = 0; // Reset + mStepInAssembly = inAssembly; SetupStep(StepType_StepOut); @@ -4995,7 +4989,7 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, { AutoCrit autoCrit(mDebugManager->mCritSect); - DbgSubprogram* subProgram = NULL; + DbgSubprogram* subProgram = NULL; if (!inAssembly) { if (mCallStack.size() == 0) @@ -5019,7 +5013,7 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, DbgSrcFile* srcFile = NULL; if (!fileName.IsEmpty()) - { + { srcFile = mDebugTarget->GetSrcFile(fileName); if (srcFile == NULL) return; @@ -5033,7 +5027,7 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, else { int lineNum = (int)lineNumOrAsmAddr; - + addr_target bestAddr[2] = { 0, 0 }; int checkLineNum[2] = { lineNum - 1, lineNum }; @@ -5066,7 +5060,7 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, for (int checkHotIdx = -1; checkHotIdx < (int)srcFile->mHotReplacedDbgLineInfo.size(); checkHotIdx++) { if (checkHotIdx >= 0) - { + { auto hotReplacedLineInfo = srcFile->mHotReplacedDbgLineInfo[checkHotIdx]; for (auto& hotReplacedEntry : hotReplacedLineInfo->mEntries) { @@ -5077,7 +5071,7 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, { for (auto subprogram : srcFile->mLineDataRefs) _CheckLineInfo(subprogram, subprogram->mLineInfo); - } + } if (bestAddr[1] != 0) break; @@ -5087,24 +5081,24 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, { const int kMaxAddrDist = 64; // within reasonable range if ((bestAddr[0] != 0) && (bestAddr[1] - bestAddr[0] <= kMaxAddrDist)) - { + { addr_target addrStart = bestAddr[0]; addr_target addrEnd = bestAddr[1]; addr_target addr = addrStart; - + BF_ASSERT(addrEnd - addr <= kMaxAddrDist); addr_target lastOp = 0; while (addr < addrEnd) { - CPUInst inst; + CPUInst inst; if (!mDebugTarget->DecodeInstruction(addr, &inst)) break; lastOp = addr; addr += inst.GetLength(); - } + } } - + pcAddress = (uint64)bestAddr[1]; } } @@ -5118,13 +5112,13 @@ void WinDebugger::SetNextStatement(bool inAssembly, const StringImpl& fileName, if (mCallStack.size() == 0) UpdateCallStack(); - CPURegisters* regs = &mCallStack.front()->mRegisters; + CPURegisters* regs = &mCallStack.front()->mRegisters; *regs->GetPCRegisterRef() = pcAddress; SetRegisters(regs); WdBreakpoint* breakpoint = (WdBreakpoint*)FindBreakpointAt(pcAddress); - if (breakpoint != NULL) + if (breakpoint != NULL) { BfLogDbg("SetNextStatement setting mIsAtBreakpointAddress = %p\n", breakpoint->mAddr); mActiveThread->mIsAtBreakpointAddress = breakpoint->mAddr; @@ -5151,7 +5145,7 @@ bool WinDebugger::PopulateRegisters(CPURegisters* registers, BF_CONTEXT& lcConte BF_ASSERT(sizeof(registers->mXmmRegsArray) == 32 * sizeof(float)); memcpy(registers->mXmmRegsArray, &lcContext.ExtendedRegisters[160], sizeof(registers->mXmmRegsArray)); -#else +#else registers->mIntRegs.rax = lcContext.Rax; registers->mIntRegs.rcx = lcContext.Rcx; registers->mIntRegs.rdx = lcContext.Rdx; @@ -5205,14 +5199,14 @@ bool WinDebugger::PopulateRegisters(CPURegisters* registers) lcContext.ContextFlags = BF_CONTEXT_ALL | BF_CONTEXT_EXCEPTION_REQUEST; BF_GetThreadContext(mActiveThread->mHThread, &lcContext); - return PopulateRegisters(registers, lcContext); + return PopulateRegisters(registers, lcContext); } bool WinDebugger::RollBackStackFrame(CPURegisters* registers, bool isStackStart) { BF_ASSERT(registers != nullptr); - return mDebugTarget->RollBackStackFrame(registers, NULL, isStackStart); + return mDebugTarget->RollBackStackFrame(registers, NULL, isStackStart); } bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget, int newTargetSize) @@ -5224,7 +5218,7 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget addr_target jmpInstStart = oldSubprogram->mBlock.mLowPC; addr_target jmpInstEnd = jmpInstStart + sizeof(HotJumpOp); - + if (jmpInstEnd > oldSubprogram->mBlock.mHighPC) { if ((oldSubprogram->mBlock.mHighPC - oldSubprogram->mBlock.mLowPC == 1) && @@ -5234,9 +5228,9 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget Fail(err); return false; } - + if (oldSubprogram->mHotReplaceKind != DbgSubprogram::HotReplaceKind_Replaced) - { + { for (int hotThreadIdx = 0; hotThreadIdx < (int)mHotThreadStates.size(); hotThreadIdx++) { auto& hotThreadState = mHotThreadStates[hotThreadIdx]; @@ -5253,12 +5247,12 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget Fail("Failed to hot replace method, can't move past prelude"); return false; } - + BfLogDbg("SetHotJump skipping through %p\n", hotThreadState.mRegisters.GetPC()); bool removedBreakpoint = false; - mActiveThread = threadInfo; + mActiveThread = threadInfo; if ((mActiveThread->mStoppedAtAddress >= jmpInstStart) && (mActiveThread->mStoppedAtAddress < jmpInstEnd)) { for (addr_target addr = jmpInstStart; addr < jmpInstEnd; addr++) @@ -5271,14 +5265,14 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget } } - RunState oldRunState = mRunState; + RunState oldRunState = mRunState; mRunState = RunState_HotStep; if (mWantsDebugContinue) { mWantsDebugContinue = false; BF_ASSERT_REL(mActiveThread->mIsAtBreakpointAddress == 0); - mContinueEvent.Set(); + mContinueEvent.Set(); } BF_CONTEXT lcContext; @@ -5286,13 +5280,13 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget BF_GetThreadContext(mActiveThread->mHThread, &lcContext); lcContext.EFlags |= 0x100; // Set trap flag, which raises "single-step" exception BF_SetThreadContext(mActiveThread->mHThread, &lcContext); - + ::ResumeThread(mActiveThread->mHThread); BfLogDbg("ResumeThread %d\n", mActiveThread->mThreadId); while (mRunState != RunState_Terminated) { - mDebugManager->mCritSect.Unlock(); + mDebugManager->mCritSect.Unlock(); Sleep(0); mDebugManager->mCritSect.Lock(); if (IsPaused()) @@ -5303,15 +5297,15 @@ bool WinDebugger::SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget mWantsDebugContinue = false; BF_ASSERT_REL(mActiveThread->mIsAtBreakpointAddress == 0); - mContinueEvent.Set(); + mContinueEvent.Set(); } } BF_GetThreadContext(mActiveThread->mHThread, &lcContext); - ::SuspendThread(mActiveThread->mHThread); + ::SuspendThread(mActiveThread->mHThread); BfLogDbg("SuspendThread %d\n", mActiveThread->mThreadId); - mRunState = oldRunState; + mRunState = oldRunState; if ((mRunState != RunState_Terminated) && (mRunState != RunState_Terminating)) { @@ -5351,7 +5345,7 @@ DbgSubprogram* WinDebugger::TryFollowHotJump(DbgSubprogram* subprogram, addr_tar if (jumpOp.mOpCode != 0xE9) return subprogram; addr_target jumpAddr = addr + jumpOp.mRelTarget + sizeof(HotJumpOp); - + auto jumpSubprogram = mDebugTarget->FindSubProgram(jumpAddr); if (jumpSubprogram == NULL) return subprogram; @@ -5361,15 +5355,15 @@ DbgSubprogram* WinDebugger::TryFollowHotJump(DbgSubprogram* subprogram, addr_tar bool WinDebugger::ShouldShowStaticMember(DbgType* dbgType, DbgVariable* member) { - // If locationData is non-null, that means it was added in addition to the static declaration in the CV type info, + // If locationData is non-null, that means it was added in addition to the static declaration in the CV type info, // so only add the names from the type definition auto flavor = dbgType->mCompileUnit->mDbgModule->mDbgFlavor; - return ((((dbgType->IsNamespace()) || (flavor != DbgFlavor_MS)) && ((member->mLocationData != NULL) || member->mIsConst)) || + return ((((dbgType->IsNamespace()) || (flavor != DbgFlavor_MS)) && ((member->mLocationData != NULL) || member->mIsConst)) || ((flavor == DbgFlavor_MS) && (member->mLocationData == NULL))); } String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool isPtr, bool isStatic, bool forceCast, bool isSplat, bool isReadOnly) -{ +{ auto dbgModule = dbgType->GetDbgModule(); dbgType->PopulateType(); auto language = dbgType->GetLanguage(); @@ -5381,11 +5375,11 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool bool isBfObject = false; if (dbgType->IsBfObjectPtr()) - { - isBfObject = true; + { + isBfObject = true; dbgType = dbgType->mTypeParam; } - + int baseIdx = 0; for (auto baseTypeEntry : dbgType->mBaseTypes) { @@ -5409,9 +5403,9 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool baseIdx++; } - - String thisExpr = expr; - String castString; + + String thisExpr = expr; + String castString; if (dbgType->IsBfObject()) { auto ptrType = dbgType->GetDbgModule()->GetPointerType(dbgType); @@ -5420,11 +5414,11 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool else castString = dbgType->ToStringRaw(language); - bool hadStatics = false; + bool hadStatics = false; for (auto member : dbgType->mMemberList) { if (member->mMemberOffset < 0) - continue; + continue; if (member->mIsStatic) { @@ -5441,14 +5435,14 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool (strncmp(member->mName, "_vptr$", 6) == 0)) ignoreMember = true; } - + if (!ignoreMember) - { + { if (needsNewline) retVal += "\n"; if (member->mName == NULL) - { + { retVal += GetMemberList(member->mType, expr, isPtr, isStatic, forceCast, isSplat, isReadOnly); } else @@ -5463,7 +5457,7 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool retVal += ", ne";*/ } else - { + { if (forceCast) retVal += "\t((" + castString + ")this)." + String(member->mName); else if ((member->mName[0] >= '0') && (member->mName[0] <= '9')) // Numbered tuple member? @@ -5478,7 +5472,7 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool } needsNewline = true; } - } + } } if (hadStatics) { @@ -5490,17 +5484,17 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool } else { - if (dbgType->IsBfObjectPtr()) - dbgType = dbgType->mTypeParam; + if (dbgType->IsBfObjectPtr()) + dbgType = dbgType->mTypeParam; - String retVal; + String retVal; String memberPrefix = expr; bool needsNewline = false; - bool hadStatics = false; + bool hadStatics = false; for (auto member : dbgType->mMemberList) { - if (member->mIsStatic) + if (member->mIsStatic) { if (ShouldShowStaticMember(dbgType, member)) { @@ -5509,8 +5503,8 @@ String WinDebugger::GetMemberList(DbgType* dbgType, const StringImpl& expr, bool retVal += String(member->mName) + "\t" + memberPrefix + "." + String(member->mName); needsNewline = true; } - } - } + } + } return retVal; } return ""; @@ -5529,7 +5523,7 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format break; if (formatFlags[0] != ',') { - return false; + return false; } else { @@ -5540,7 +5534,7 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format int nextQuotePos = formatFlags.IndexOf('"', quotePos + 1); if (nextQuotePos != -1) nextComma = formatFlags.IndexOf(',', nextQuotePos + 1); - } + } if (nextComma == -1) nextComma = formatFlags.length(); @@ -5562,12 +5556,12 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format if (errorString != NULL) *errorString = dbgEvaluationContext.GetErrorStr(); return false; - } + } formatFlags = thisExpr.Substring(dbgEvaluationContext.mExprNode->GetSrcEnd()); continue; } else if (strncmp(formatCmd.c_str(), "count=", 6) == 0) - { + { formatCmd = formatFlags.Substring(1); formatCmd = Trim(formatCmd); String countExpr = formatCmd.Substring(6); @@ -5578,11 +5572,11 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format if ((countValue) && (countValue.mType->IsInteger())) formatInfo->mOverrideCount = (intptr)countValue.GetInt64(); if (dbgEvaluationContext.HadError()) - { + { if (errorString != NULL) *errorString = dbgEvaluationContext.GetErrorStr(); return false; - } + } formatFlags = countExpr.Substring(dbgEvaluationContext.mExprNode->GetSrcEnd()); continue; } @@ -5625,7 +5619,7 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format } formatFlags = countExpr.Substring(dbgEvaluationContext.mExprNode->GetSrcEnd()); continue; - } + } else if (strncmp(formatCmd.c_str(), "assign=", 7) == 0) { formatCmd = formatFlags.Substring(1); @@ -5633,7 +5627,7 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format String assignExpr = formatCmd.Substring(7); if (assignExpr.empty()) break; - DbgEvaluationContext dbgEvaluationContext(this, dbgModule, assignExpr, formatInfo); + DbgEvaluationContext dbgEvaluationContext(this, dbgModule, assignExpr, formatInfo); if (dbgEvaluationContext.HadError()) { if (errorString != NULL) @@ -5735,10 +5729,10 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format else if (formatCmd == "rawStr") { formatInfo->mRawString = true; - } + } else if (((!formatCmd.IsEmpty()) && ((formatCmd[0] >= '0') && (formatCmd[0] <= '9'))) || (formatCmd.StartsWith("("))) - { + { String countExpr = formatCmd; if (countExpr.empty()) break; @@ -5757,7 +5751,7 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format } else hadError = true; - + if (hadError) { if (errorString != NULL) @@ -5798,7 +5792,7 @@ DbgTypedValue WinDebugger::EvaluateInContext(DbgCompileUnit* dbgCompileUnit, con dbgEvaluationContext.mDbgExprEvaluator->mLanguage = formatInfo->mLanguage; dbgEvaluationContext.mDbgExprEvaluator->mSubjectExpr = formatInfo->mSubjectExpr; } - dbgEvaluationContext.mDbgExprEvaluator->mReferenceId = outReferenceId; + dbgEvaluationContext.mDbgExprEvaluator->mReferenceId = outReferenceId; auto result = dbgEvaluationContext.EvaluateInContext(contextTypedValue); if ((formatInfo != NULL) && (dbgEvaluationContext.mDbgExprEvaluator->mCountResultOverride != -1)) formatInfo->mOverrideCount = dbgEvaluationContext.mDbgExprEvaluator->mCountResultOverride; @@ -5808,7 +5802,7 @@ DbgTypedValue WinDebugger::EvaluateInContext(DbgCompileUnit* dbgCompileUnit, con { int errIdx = 0; for (auto err : dbgEvaluationContext.mPassInstance->mErrors) - { + { if (errIdx > 0) (*outErrors) += "\n"; (*outErrors) += err->mError; @@ -5821,10 +5815,10 @@ DbgTypedValue WinDebugger::EvaluateInContext(DbgCompileUnit* dbgCompileUnit, con } void WinDebugger::DbgVisFailed(DebugVisualizerEntry* debugVis, const StringImpl& evalString, const StringImpl& errors) -{ +{ bool onlyMemError = errors.StartsWith("Failed to read") && !errors.Contains('\n'); if ((!debugVis->mShowedError) && (!onlyMemError)) - { + { debugVis->mShowedError = true; String errStr = StrFormat("DbgVis '%s' failed while evaluating condition '%s'\n", debugVis->mName.c_str(), evalString.c_str()); String spacedErrors = errors; @@ -5848,7 +5842,7 @@ bool WinDebugger::EvalCondition(DebugVisualizerEntry* debugVis, DbgCompileUnit* { if (formatInfo.mRawString) return false; - + errorStr += ""; DbgVisFailed(debugVis, conditionStr, errors); return false; @@ -5858,16 +5852,16 @@ bool WinDebugger::EvalCondition(DebugVisualizerEntry* debugVis, DbgCompileUnit* } String WinDebugger::GetArrayItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData) -{ +{ DbgEvaluationContext conditionEvaluationContext(this, dbgCompileUnit, debugVis->mCondition); String addrs; bool checkLeft = true; - int usedCount = 0; + int usedCount = 0; while (usedCount < count) - { + { DbgTypedValue condVal = conditionEvaluationContext.EvaluateInContext(curNode); if (!condVal) break; @@ -5904,19 +5898,19 @@ String WinDebugger::GetLinkedListItems(DbgCompileUnit* dbgCompileUnit, DebugVisu { DbgEvaluationContext nextEvaluationContext(this, dbgCompileUnit, debugVis->mNextPointer); DbgEvaluationContext valueEvaluationContext(this, dbgCompileUnit, debugVis->mValuePointer); - + String addrs; bool checkLeft = true; - + int mapIdx; for (mapIdx = 0; mapIdx < count; mapIdx++) - { + { if (curNode.mPtr == endNodePtr) break; - DbgTypedValue val = valueEvaluationContext.EvaluateInContext(curNode); + DbgTypedValue val = valueEvaluationContext.EvaluateInContext(curNode); if (!val) - break; + break; if (val.mPtr == 0) break; @@ -5927,17 +5921,17 @@ String WinDebugger::GetLinkedListItems(DbgCompileUnit* dbgCompileUnit, DebugVisu typeAddr.Append(' ', sizeof(addr_target)*2 - typeAddr.length()); addrs += typeAddr; } - + String addr = EncodeDataPtr(val.mPtr, false); addrs += addr; - - curNode = nextEvaluationContext.EvaluateInContext(curNode); + + curNode = nextEvaluationContext.EvaluateInContext(curNode); } count = mapIdx; if (outContinuationData != NULL) { - *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(endNodePtr, false) + EncodeDataPtr(valueType, false) + + *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(endNodePtr, false) + EncodeDataPtr(valueType, false) + EncodeDataPtr(curNode.mType, false) + EncodeDataPtr(curNode.mPtr, false); } @@ -5949,7 +5943,7 @@ String WinDebugger::GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisu //DbgEvaluationContext bucketsEvaluationContext(this, dbgModule, debugVis->mBuckets); DbgEvaluationContext nextEvaluationContext(this, dbgCompileUnit->mDbgModule, debugVis->mNextPointer); - DbgTypedValue bucketsPtr = EvaluateInContext(dbgCompileUnit, dictValue, debugVis->mBuckets); + DbgTypedValue bucketsPtr = EvaluateInContext(dbgCompileUnit, dictValue, debugVis->mBuckets); DbgTypedValue entriesPtr = EvaluateInContext(dbgCompileUnit, dictValue, debugVis->mEntries); if ((!bucketsPtr) || (!entriesPtr)) { @@ -5973,7 +5967,7 @@ String WinDebugger::GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisu entryValue.mType = entriesPtr.mType->mTypeParam; addrs += EncodeDataPtr(entryValue.mSrcAddress, false); - + DbgTypedValue nextValue = nextEvaluationContext.EvaluateInContext(entryValue); if ((!nextValue) || (!nextValue.mType->IsInteger())) { @@ -5984,7 +5978,7 @@ String WinDebugger::GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisu encodeCount++; } else - { + { if (bucketIdxSize == 4) nodeIdx = ReadMemory(bucketsPtr.mPtr + bucketIdx * sizeof(int32)); else @@ -5992,13 +5986,13 @@ String WinDebugger::GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisu bucketIdx++; } } - + count = encodeCount; //count = mapIdx; if (outContinuationData != NULL) { - *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(dictValue.mType, false) + EncodeDataPtr(dictValue.mSrcAddress, false) + + *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(dictValue.mType, false) + EncodeDataPtr(dictValue.mSrcAddress, false) + EncodeDataPtr((addr_target)bucketIdx, false) + EncodeDataPtr((addr_target)nodeIdx, false); } @@ -6012,9 +6006,9 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer DbgEvaluationContext valueEvaluationContext(this, dbgCompileUnit, debugVis->mValuePointer); DbgEvaluationContext conditionEvaluationContext(this, dbgCompileUnit, debugVis->mCondition); - + String addrs; - + bool checkLeft = true; if ((curNode.mPtr & 2) != 0) // Flag from continuation @@ -6024,17 +6018,17 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer } HashSet seenAddrs; - + for (int mapIdx = 0; mapIdx < count; mapIdx++) { DbgTypedValue readNode; while (true) - { - bool checkNode = (curNode.mPtr & 1) == 0; + { + bool checkNode = (curNode.mPtr & 1) == 0; readNode = curNode; readNode.mPtr &= (addr_target)~1; - + if (checkLeft) { DbgTypedValue leftValue = leftEvaluationContext.EvaluateInContext(readNode); @@ -6050,7 +6044,7 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer checkLeft = false; break; // Handle node } - + parentList.push_back(curNode.mPtr); curNode = leftValue; } @@ -6080,7 +6074,7 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer // Failed break; } - + curNode.mPtr = parentList.back(); parentList.pop_back(); continue; // Don't check against seenAddrs @@ -6091,13 +6085,13 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer { // Failed! return ""; - } + } } DbgTypedValue val = valueEvaluationContext.EvaluateInContext(readNode); if (valueType == NULL) valueType = val.mType; - + String addr = EncodeDataPtr(val.mPtr, false); addrs += addr; @@ -6108,7 +6102,7 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer curNode.mPtr |= 2; if (outContinuationData != NULL) - { + { *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(valueType, false) + EncodeDataPtr(curNode.mType, false) + EncodeDataPtr(curNode.mPtr, false); for (auto parent : parentList) *outContinuationData += EncodeDataPtr(parent, false); @@ -6147,21 +6141,21 @@ String WinDebugger::GetCollectionContinuation(const StringImpl& continuationData { addr_target endNodePtr = DecodeTargetDataPtr(dataPtr); DbgType* valueType = (DbgType*) DecodeLocalDataPtr(dataPtr); - DbgTypedValue curNode; + DbgTypedValue curNode; curNode.mType = (DbgType*)DecodeLocalDataPtr(dataPtr); curNode.mPtr = DecodeTargetDataPtr(dataPtr); - - String newContinuationData; - if (count < 0) - count = 3; + String newContinuationData; + + if (count < 0) + count = 3; String retVal = GetLinkedListItems(dbgCompileUnit, debugVis, endNodePtr, valueType, curNode, count, &newContinuationData); retVal += "\n" + newContinuationData; return retVal; } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Array) - { + { DbgType* valueType = (DbgType*)DecodeLocalDataPtr(dataPtr); DbgTypedValue curNode; curNode.mType = (DbgType*)DecodeLocalDataPtr(dataPtr); @@ -6181,16 +6175,16 @@ String WinDebugger::GetCollectionContinuation(const StringImpl& continuationData DbgTypedValue dictValue; dictValue.mType = (DbgType*)DecodeLocalDataPtr(dataPtr); dictValue.mSrcAddress = DecodeTargetDataPtr(dataPtr); - + int bucketIdx = (int)DecodeTargetDataPtr(dataPtr); int nodeIdx = (int)DecodeTargetDataPtr(dataPtr); - - String newContinuationData; + + String newContinuationData; String retVal = GetDictionaryItems(dbgCompileUnit, debugVis, dictValue, bucketIdx, nodeIdx, count, &newContinuationData); retVal += "\n" + newContinuationData; return retVal; } - + return ""; } @@ -6217,7 +6211,6 @@ static String IntTypeToString(T val, const StringImpl& name, DwDisplayInfo* disp binary = "'" + binary; binary = ((val & ((T)1 << i)) ? "1" : "0") + binary; - } return StrFormat("0b'%s\n%s", binary.c_str(), name.c_str()); } @@ -6238,7 +6231,7 @@ static String IntTypeToString(T val, const StringImpl& name, DwDisplayInfo* disp { String format; if (sizeof(T) == 8) - { + { format = StrFormat("0x%%l@\n%s", name.c_str()); } else @@ -6251,14 +6244,14 @@ static String IntTypeToString(T val, const StringImpl& name, DwDisplayInfo* disp { String format; if (sizeof(T) == 8) - { + { format = StrFormat("0x%%l@\n%s", name.c_str()); } else format = StrFormat("0x%%0%dX\n%s", sizeof(val) * 2, name.c_str()); return StrFormat(format.c_str(), (std::make_unsigned::type)(val)); } - + if (std::is_unsigned::value) { if (sizeof(T) == 8) @@ -6289,7 +6282,7 @@ DwDisplayInfo* WinDebugger::GetDisplayInfo(const StringImpl& referenceId) { DwDisplayInfo* displayInfo = &mDebugManager->mDefaultDisplayInfo; if (!referenceId.empty()) - { + { if (!mDebugManager->mDisplayInfos.TryGetValue(referenceId, &displayInfo)) { int dollarIdx = referenceId.LastIndexOf('$'); @@ -6308,7 +6301,7 @@ static String WrapWithModifiers(const StringImpl& origName, DbgType* dbgType, Db if (language == DbgLanguage_Unknown) language = dbgType->GetLanguage(); - String name = origName; + String name = origName; while (true) { if (dbgType->mTypeCode == DbgType_Const) @@ -6330,15 +6323,15 @@ static String WrapWithModifiers(const StringImpl& origName, DbgType* dbgType, Db } else if (dbgType->mTypeCode == DbgType_Ref) { - if (language == DbgLanguage_Beef) - name = "ref " + name; - else + if (language == DbgLanguage_Beef) + name = "ref " + name; + else name = name + "&"; dbgType = dbgType->mTypeParam; } else if (dbgType->mTypeCode == DbgType_Bitfield) { - return dbgType->ToString(language); + return dbgType->ToString(language); } else return name; @@ -6348,7 +6341,7 @@ static String WrapWithModifiers(const StringImpl& origName, DbgType* dbgType, Db DebugVisualizerEntry* WinDebugger::FindVisualizerForType(DbgType* dbgType, Array* wildcardCaptures) { auto entry = mDebugManager->mDebugVisualizers->FindEntryForType(dbgType->ToString(DbgLanguage_Unknown, true), dbgType->mCompileUnit->mDbgModule->mDbgFlavor, wildcardCaptures); - + if (entry == NULL) { dbgType = dbgType->GetPrimaryType(); @@ -6358,16 +6351,16 @@ DebugVisualizerEntry* WinDebugger::FindVisualizerForType(DbgType* dbgType, Array entry = FindVisualizerForType(baseTypeEntry->mBaseType, wildcardCaptures); if (entry != NULL) break; - } + } } - + return entry; } #define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1) String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAddr, intptr maxLength, DwFormatInfo& formatInfo, bool wantStringView) -{ +{ int origMaxLength = maxLength; if (addr == 0) return ""; @@ -6376,9 +6369,9 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd String retVal = "\""; bool wasTerminated = false; - String valString; + String valString; intptr maxShowSize = 255; - + if (maxLength == -1) maxLength = formatInfo.mOverrideCount; else if (formatInfo.mOverrideCount != -1) @@ -6387,7 +6380,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd maxLength = BF_MIN(formatInfo.mMaxCount, maxLength); if (maxLength == -1) - maxLength = 8 * 1024 * 1024; // Is 8MB crazy? + maxLength = 8 * 1024 * 1024; // Is 8MB crazy? if ((!formatInfo.mRawString) && (!wantStringView)) maxLength = BF_MIN(maxLength, maxShowSize); @@ -6417,7 +6410,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd int i; for (i = 0; i < maxLength; i++) - { + { if (bufPtr >= bufEnd) { while (true) @@ -6430,14 +6423,14 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd if (ReadMemory(strPtr, readSize, buf, isLocalAddr)) break; - - readSize /= 2; + + readSize /= 2; } if (readFailed) break; - + bufPtr = buf; - bufEnd = buf + readSize; + bufEnd = buf + readSize; } switch (charLen) @@ -6492,7 +6485,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd if ((wasTerminated) || (readFailed)) { break; - } + } strPtr += charLen; } //DisableMemCache(); @@ -6514,7 +6507,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd // // Our encoding for retVal is already assumed to be UTF8, so the special case here actually Ascii // valString = UTF8Encode(ToWString(valString)); // } - + if ((formatInfo.mRawString) || (wantStringView)) { if ((formatInfo.mDisplayType == DwDisplayType_Utf8) || (!hasHighAscii)) @@ -6539,7 +6532,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd return "< Failed to read string >"; retVal += SlashString(valString, true, true, formatInfo.mLanguage == DbgLanguage_Beef); - + // We could go over 'maxShowSize' if we have a lot of slashed chars. An uninitialized string can be filled with '\xcc' chars if ((!formatInfo.mRawString) && (!wantStringView) && ((int)retVal.length() > maxShowSize)) { @@ -6578,7 +6571,7 @@ void WinDebugger::ProcessEvalString(DbgCompileUnit* dbgCompileUnit, DbgTypedValu DwFormatInfo displayStrFormatInfo = formatInfo; displayStrFormatInfo.mTotalSummaryLength = formatInfo.mTotalSummaryLength + (int)displayString.length(); displayStrFormatInfo.mHidePointers = false; - + if ((limitLength) && (displayStrFormatInfo.mTotalSummaryLength > 255)) { displayString += "..."; @@ -6668,7 +6661,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c DbgType* origValueType = typedValue.mType; bool origHadRef = false; - DbgType* dwValueType = typedValue.mType->RemoveModifiers(&origHadRef); + DbgType* dwValueType = typedValue.mType->RemoveModifiers(&origHadRef); if (dwValueType == NULL) dwValueType = dbgModule->GetPrimitiveType(DbgType_Void, language); @@ -6687,7 +6680,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if ((dwValueType->mTypeCode != DbgType_Struct) && (dwValueType->mTypeCode != DbgType_Class) && (dwValueType->mTypeCode != DbgType_Ptr) && (dwValueType->mTypeCode != DbgType_SizedArray)) return ""; } - + auto _ShowArraySummary = [&](String& retVal, addr_target ptrVal, int64 arraySize, DbgType* innerType) { String displayString; @@ -6743,7 +6736,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c { retVal = EncodeDataPtr(ptrVal, true) + " "; retVal += dwValueType->mTypeParam->ToString(language); - retVal += StrFormat("[%lld] ", (int64)formatInfo.mArrayLength); + retVal += StrFormat("[%lld] ", (int64)formatInfo.mArrayLength); } _ShowArraySummary(retVal, ptrVal, formatInfo.mArrayLength, dwValueType->mTypeParam); @@ -6751,7 +6744,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c String idxStr = "[{0}]"; DbgType* innerType = dwValueType->mTypeParam; - + retVal += "\n" + dwValueType->ToString(language); String evalStr = "*((" + typedValue.mType->ToStringRaw(language) + ")" + EncodeDataPtr(ptrVal, true) + " + {0})"; @@ -6773,13 +6766,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c return retVal; } } - + switch (dwValueType->mTypeCode) { case DbgType_Void: return "\nvoid"; case DbgType_Bool: - { + { if (typedValue.mUInt8 == 0) return "false\n" + WrapWithModifiers("bool", origValueType, language); else if (typedValue.mUInt8 == 1) @@ -6792,7 +6785,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (language != DbgLanguage_Beef) return IntTypeToString(typedValue.mUInt8, WrapWithModifiers("uint8_t", origValueType, language), displayInfo, formatInfo); case DbgType_SChar: - { + { if (typedValue.mInt8 != 0) { char str[2] = {(char)typedValue.mInt8}; @@ -6812,7 +6805,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (language != DbgLanguage_Beef) return IntTypeToString(typedValue.mUInt8, WrapWithModifiers("uint16_t", origValueType, language), displayInfo, formatInfo); case DbgType_SChar16: - { + { if (typedValue.mInt16 != 0) { u8_toutf8(str, 8, typedValue.mUInt32); @@ -6829,41 +6822,41 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c break; case DbgType_UChar32: case DbgType_SChar32: - { + { if (typedValue.mInt32 != 0) - { + { u8_toutf8(str, 8, typedValue.mUInt32); - result = SlashString(str, true, true); - if (!IsNormalChar(typedValue.mUInt32)) + result = SlashString(str, true, true); + if (!IsNormalChar(typedValue.mUInt32)) result = StrFormat("'%s' (0x%02X)\n", result.c_str(), typedValue.mUInt32); else - result = StrFormat("'%s'\n", result.c_str()); + result = StrFormat("'%s'\n", result.c_str()); } else result = "'\\0'\n"; return result + WrapWithModifiers(isBeef ? "char32" : "int32_t", origValueType, language); } break; - case DbgType_i8: + case DbgType_i8: return IntTypeToString(typedValue.mInt8, WrapWithModifiers(isBeef ? "int8" : "int8_t", origValueType, language), displayInfo, formatInfo); case DbgType_u8: return IntTypeToString(typedValue.mUInt8, WrapWithModifiers(isBeef ? "uint8" : "uint8_t", origValueType, language), displayInfo, formatInfo); - case DbgType_i16: + case DbgType_i16: return IntTypeToString(typedValue.mInt16, WrapWithModifiers(isBeef ? "int16" : "int16_t", origValueType, language), displayInfo, formatInfo); - case DbgType_u16: + case DbgType_u16: return IntTypeToString(typedValue.mUInt16, WrapWithModifiers(isBeef ? "uint16" : "uint16_t", origValueType, language), displayInfo, formatInfo); - case DbgType_i32: + case DbgType_i32: return IntTypeToString(typedValue.mInt32, WrapWithModifiers(isBeef ? "int32" : "int32_t", origValueType, language), displayInfo, formatInfo); - case DbgType_u32: + case DbgType_u32: return IntTypeToString(typedValue.mUInt32, WrapWithModifiers(isBeef ? "uint32" : "uint32_t", origValueType, language), displayInfo, formatInfo); - case DbgType_i64: + case DbgType_i64: return IntTypeToString(typedValue.mInt64, WrapWithModifiers(isBeef ? "int64" : "int64_t", origValueType, language), displayInfo, formatInfo); - case DbgType_u64: + case DbgType_u64: return IntTypeToString(typedValue.mUInt64, WrapWithModifiers(isBeef ? "uint64" : "uint64_t", origValueType, language), displayInfo, formatInfo); case DbgType_RegGroup: - { + { if ((typedValue.mRegNum >= CPUReg_M128_XMMREG_FIRST) && (typedValue.mRegNum <= CPUReg_M128_XMMREG_LAST)) - { + { int callStackIdx = formatInfo.mCallStackIdx; FixCallStackIdx(callStackIdx); @@ -6883,7 +6876,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c (regForm == RegForm_Long) || (regForm == RegForm_Long2) || (regForm == RegForm_ULong) || (regForm == RegForm_ULong2)) xmmCount = 2; - //TODO: add byte, short, int, etc... + //TODO: add byte, short, int, etc... if (optEvaluator) { @@ -6895,7 +6888,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c else if (regForm == RegForm_Int4) mmDwMmDisplayType = DwMmDisplayType_Int32; } - + if (mmDwMmDisplayType == DwMmDisplayType_Double) { xmmType = "__m128d"; @@ -6923,7 +6916,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c BF_ASSERT(xmmReg.mRegNum == CPUReg_XMMREG_FIRST + (xmmMajor * 4) + xmmMinor); xmmRegVals[xmmMinor] = xmmReg.mInt32; } - headerStr = StrFormat("(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", + headerStr = StrFormat("(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", xmmRegVals[0] & 0xFF, (xmmRegVals[0] >> 8) & 0xFF, (xmmRegVals[0] >> 16) & 0xFF, (xmmRegVals[0] >> 24) & 0xFF, xmmRegVals[1] & 0xFF, (xmmRegVals[1] >> 8) & 0xFF, (xmmRegVals[1] >> 16) & 0xFF, (xmmRegVals[1] >> 24) & 0xFF, xmmRegVals[2] & 0xFF, (xmmRegVals[2] >> 8) & 0xFF, (xmmRegVals[2] >> 16) & 0xFF, (xmmRegVals[2] >> 24) & 0xFF, @@ -6941,7 +6934,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c BF_ASSERT(xmmReg.mRegNum == CPUReg_XMMREG_FIRST + (xmmMajor * 4) + xmmMinor); xmmRegVals[xmmMinor] = xmmReg.mInt32; } - headerStr = StrFormat("(%d, %d, %d, %d, %d, %d, %d, %d)", + headerStr = StrFormat("(%d, %d, %d, %d, %d, %d, %d, %d)", xmmRegVals[0] & 0xFFFF, (xmmRegVals[0] >> 16) & 0xFFFF, xmmRegVals[1] & 0xFFFF, (xmmRegVals[1] >> 16) & 0xFFFF, xmmRegVals[2] & 0xFFFF, (xmmRegVals[2] >> 16) & 0xFFFF, @@ -6960,7 +6953,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c xmmRegVals[xmmMinor] = xmmReg.mInt32; } headerStr = StrFormat("(%d, %d, %d, %d)", xmmRegVals[0], xmmRegVals[1], xmmRegVals[2], xmmRegVals[3]); - } + } else if (mmDwMmDisplayType == DwMmDisplayType_Int64) { int64 xmmRegVals[2]; @@ -6988,7 +6981,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c xmmRegVals[xmmMinor] = xmmReg.mSingle; } headerStr = StrFormat("(%f, %f, %f, %f)", xmmRegVals[0], xmmRegVals[1], xmmRegVals[2], xmmRegVals[3]); - } + } } else { @@ -7046,7 +7039,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c (uint64)regs->mIntRegs.rip, (uint64)regs->mIntRegs.r8, (uint64)regs->mIntRegs.r9, (uint64)regs->mIntRegs.r10, (uint64)regs->mIntRegs.r11, (uint64)regs->mIntRegs.r12, (uint64)regs->mIntRegs.r13, (uint64)regs->mIntRegs.r14, (uint64)regs->mIntRegs.r15, - (uint32)regs->mIntRegs.efl); + (uint32)regs->mIntRegs.efl); } else { @@ -7130,7 +7123,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (optEvaluator) { CPURegisters* regs = optEvaluator->GetRegisters(); -#ifdef BF_DBG_32 +#ifdef BF_DBG_32 #define FLAGVAR(abbr, name) int flag##abbr = ((regs->mIntRegs.efl & ((uint64)1 << CPURegisters::GetFlagBitForRegister(X86Reg_FLAG_##abbr##_##name))) != 0) ? 1 : 0 FLAGVAR(CF, CARRY); FLAGVAR(PF, PARITY); @@ -7187,7 +7180,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c sprintf(str, "0x%04x", typedValue.mUInt32); return StrFormat("%s\n%s", str, WrapWithModifiers("float", origValueType, language).c_str()); } - case DbgType_Double: + case DbgType_Double: { DwFloatDisplayType floatDisplayType = displayInfo->mFloatDisplayType; if (floatDisplayType == DwFloatDisplayType_Default) @@ -7208,15 +7201,15 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c else return "\nfunc"; case DbgType_RawText: - return StrFormat("%s\nrawtext", typedValue.mCharPtr); + return StrFormat("%s\nrawtext", typedValue.mCharPtr); case DbgType_Ptr: { - addr_target ptrVal = (addr_target)typedValue.mPtr; - String retVal; - DbgType* innerType = dwValueType->mTypeParam; + addr_target ptrVal = (addr_target)typedValue.mPtr; + String retVal; + DbgType* innerType = dwValueType->mTypeParam; if (innerType == NULL) - return EncodeDataPtr(ptrVal, true) + "\nvoid*"; - + return EncodeDataPtr(ptrVal, true) + "\nvoid*"; + bool isChar = false; DbgType* unmodInnerType = innerType->RemoveModifiers(); @@ -7235,11 +7228,11 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c (unmodInnerType->mTypeCode == DbgType_SChar16) || (unmodInnerType->mTypeCode == DbgType_SChar32)) isChar = true; - } + } } if ((isChar) && (formatInfo.mArrayLength == -1)) - { + { if ((!typedValue.mIsLiteral) && (!formatInfo.mHidePointers)) retVal = EncodeDataPtr(ptrVal, true); @@ -7274,10 +7267,10 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } return retVal; } - else if ((unmodInnerType != NULL) && + else if ((unmodInnerType != NULL) && ((unmodInnerType->mTypeCode == DbgType_Class) || (unmodInnerType->mTypeCode == DbgType_Struct) || (unmodInnerType->mTypeCode == DbgType_Union))) { - isCompositeType = true; + isCompositeType = true; } else if ((unmodInnerType != NULL) && (unmodInnerType->mTypeCode == DbgType_SizedArray)) { @@ -7311,8 +7304,8 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c else { auto dbgModule = mDebugTarget->FindDbgModuleForAddress(funcPtr); - if (dbgModule != NULL) - demangledName += dbgModule->GetLinkedModule()->mDisplayName + "!"; + if (dbgModule != NULL) + demangledName += dbgModule->GetLinkedModule()->mDisplayName + "!"; demangledName += StrFormat("0x%@", funcPtr); } @@ -7344,7 +7337,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c retVal += "}"; } } - + retVal += "\n" + origValueType->ToString(language); return retVal; @@ -7356,7 +7349,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c addr_target ptrVal = (addr_target)typedValue.mPtr; String retVal; if ((!typedValue.mIsLiteral) && (!formatInfo.mHidePointers)) - retVal = EncodeDataPtr(ptrVal, true); + retVal = EncodeDataPtr(ptrVal, true); if (ptrVal != 0) { @@ -7383,17 +7376,17 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c else { retVal += "{ ??? }"; - } + } } } retVal += "\n" + origValueType->ToString(language); innerType->PopulateType(); - + if ((ptrVal != 0) && ((!innerType->mMemberList.IsEmpty()) || (innerType->mSize > 0) || (innerType->mTypeParam != NULL))) { - String ptrDataStr = StrFormat("(%s)", dwValueType->ToStringRaw(language).c_str()) + EncodeDataPtr(typedValue.mPtr, true); + String ptrDataStr = StrFormat("(%s)", dwValueType->ToStringRaw(language).c_str()) + EncodeDataPtr(typedValue.mPtr, true); retVal += "\n*\t"; // Why did we have this? It messed up a pointer to sized array /*if (language == DbgLanguage_Beef) @@ -7409,22 +7402,22 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c return retVal; } - break; + break; } case DbgType_Union: case DbgType_Class: - case DbgType_Struct: + case DbgType_Struct: isCompositeType = true; - break; + break; case DbgType_Enum: enumVal = typedValue.GetInt64(); isEnum = true; - break; + break; case DbgType_SizedArray: { - isSizedArray = true; + isSizedArray = true; } - break; + break; default: break; } @@ -7451,7 +7444,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c retVal = EncodeDataPtr(ptrVal, true) + " "; } if (ptrVal == 0) - ptrVal = typedValue.mPtr; + ptrVal = typedValue.mPtr; intptr arraySize = 0; intptr innerSize = innerType->GetStride(); @@ -7459,7 +7452,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c arraySize = arrayType->GetStride() / innerSize; else { - // Failure! + // Failure! } String idxStr = "[{0}]"; @@ -7478,13 +7471,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c _ShowArraySummary(retVal, ptrVal, arraySize, innerType); } - + retVal += "\n" + origValueType->ToString(language); String referenceId = dwValueType->ToString(language); String evalStr; - // Why did we have the "na"? Do we not want to show addresses for all members? + // Why did we have the "na"? Do we not want to show addresses for all members? evalStr = "((" + innerType->ToStringRaw(language) + "*)" + EncodeDataPtr(ptrVal, true) + ")[{0}], refid=" + MaybeQuoteFormatInfoParam(referenceId + ".[]"); if (typedValue.mIsReadOnly) evalStr += ", ne"; @@ -7494,13 +7487,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } dwValueType->PopulateType(); - + if (isEnum) - { + { String retVal; int64 bitsLeft = enumVal; int valueCount = 0; - + String editVal; dwValueType = dwValueType->GetPrimaryType(); @@ -7510,7 +7503,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c while ((bitsLeft != 0) || (valueCount == 0)) { DbgVariable* bestMatch = NULL; - + for (auto member : dwValueType->mMemberList) { if (member->mConstValue == bitsLeft) @@ -7521,13 +7514,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } if (bestMatch == NULL) - { + { for (auto member : dwValueType->mMemberList) { - if ((member->mConstValue != 0) && + if ((member->mConstValue != 0) && ((member->mConstValue & bitsLeft) == member->mConstValue)) { - bestMatch = member; + bestMatch = member; break; } } @@ -7542,7 +7535,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (language == DbgLanguage_C) editVal += " | "; } - + if (language == DbgLanguage_Beef) retVal += "."; retVal += bestMatch->mName; @@ -7574,7 +7567,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c editVal += StrFormat("%lld", bitsLeft); } } - + retVal += "\n" + origValueType->ToString(); if (language == DbgLanguage_C) { @@ -7592,12 +7585,12 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c ptrVal = (addr_target)typedValue.mPtr; else ptrVal = (addr_target)typedValue.mSrcAddress; - String retVal; + String retVal; if ((!typedValue.mIsLiteral) && (dwValueType->IsPointer()) && - ((!formatInfo.mHidePointers) || (ptrVal == 0))) - retVal = EncodeDataPtr(ptrVal, true); - - DbgType* innerType = dwValueType; + ((!formatInfo.mHidePointers) || (ptrVal == 0))) + retVal = EncodeDataPtr(ptrVal, true); + + DbgType* innerType = dwValueType; bool wasPtr = false; if (innerType->mTypeCode == DbgType_Ptr) { @@ -7610,7 +7603,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c addr_target dataPtr = wasPtr ? typedValue.mPtr : typedValue.mSrcAddress; DbgType* actualType = NULL; bool useActualRawType = false; - + bool isBfObject = innerType->IsBfObject(); bool hasCPPVTable = false; if (!isBfObject) @@ -7632,10 +7625,10 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c int tagIdx = 0; if (dataPtr == -1) - { + { DbgEvaluationContext dbgEvaluationContext(this, dbgModule, "(int)" + expr, &formatInfo); auto dscValue = dbgEvaluationContext.EvaluateInContext(DbgTypedValue()); - tagIdx = dscValue.mInt32; + tagIdx = dscValue.mInt32; } else if (!ReadMemory((intptr)ptrVal + tagMember->mMemberOffset, tagMember->mType->mSize, (void*)&tagIdx)) { @@ -7658,7 +7651,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (strncmp(member->mName, findStr, len) == 0) { retVal += "."; - retVal += member->mName + len; + retVal += member->mName + len; String tupleExpr; @@ -7681,7 +7674,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c displayStrFormatInfo.mTotalSummaryLength = formatInfo.mTotalSummaryLength + (int)retVal.length(); displayStrFormatInfo.mExpandItemDepth++; displayStrFormatInfo.mHidePointers = false; - retVal += DbgTypedValueToString(tupleVal, tupleExpr, displayStrFormatInfo, NULL); + retVal += DbgTypedValueToString(tupleVal, tupleExpr, displayStrFormatInfo, NULL); int idx = (int)retVal.IndexOf('\n'); if (idx != -1) { @@ -7708,22 +7701,22 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (mDebugTarget->mBfObjectHasFlags) { bfObjectFlags = ((int)classVDataPtr) & 0xFF; - + if ((bfObjectFlags & BfObjectFlag_Deleted) != 0) isDeletedBfObject = true; if ((bfObjectFlags & BfObjectFlag_AppendAlloc) != 0) - isAppendBfObject = true; + isAppendBfObject = true; if ((bfObjectFlags & (BfObjectFlag_StackAlloc | BfObjectFlag_Allocated)) == BfObjectFlag_StackAlloc) isStackBfObject = true; classVDataPtr &= ~0xFF; } } - + if (!formatInfo.mIgnoreDerivedClassInfo) { if (isBfObject) - { + { dbgModule->ParseSymbolData(); String symbolName; @@ -7743,9 +7736,9 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c symEndLen = strlen(symEnd); if (((int) symbolName.length() > symEndLen) && (strstr(symbolName.c_str(), symEnd) != NULL)) mangledClassName = symbolName; - + if (mangledClassName.length() > 0) - { + { String className = BfDemangler::Demangle(mangledClassName, innerType->GetLanguage(), BfDemangler::Flag_RawDemangle); for (int i = 0; i < className.length() - 3; i++) @@ -7787,13 +7780,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (typeEntry != NULL) { actualType = typeEntry->mValue; - if (!actualType->IsBfObject()) - { + if (!actualType->IsBfObject()) + { if (actualType->mTypeCode == DbgType_Ptr) { actualType = actualType->mTypeParam; - } - } + } + } } } } @@ -7834,7 +7827,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (!DbgExprEvaluator::TypeIsSubTypeOf(actualType, innerType, &thisOffset)) { // This catches virtual inheritance cases where we can't downcast - actualType = NULL; + actualType = NULL; } } } @@ -7845,17 +7838,17 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c DbgType* displayType = origValueType; - String displayString; + String displayString; bool wantsCustomExpandedItems = false; DebugVisualizerEntry* debugVis = NULL; Array dbgVisWildcardCaptures; - DbgType* dwUseType = (actualType != NULL) ? actualType : innerType; + DbgType* dwUseType = (actualType != NULL) ? actualType : innerType; //auto ptrDataType = dwValueType; //TODO: Changed this from the above to account for COFF types where 'this' is always a fwd reference, does this cause any issues? - auto ptrDataType = innerType; + auto ptrDataType = innerType; String ptrDataStr; if (/*(!innerType->IsBfObject()) &&*/ (!ptrDataType->IsPointer())) - { + { if ((dataPtr != 0) || (ptrDataType->GetByteCount() > sizeof(addr_target))) { bool wantsRefThis = ptrDataType->WantsRefThis(); @@ -7870,7 +7863,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c dataPtr = typedValue.mPtr; } } - String ptrDataTypeStr = ptrDataType->ToStringRaw(); + String ptrDataTypeStr = ptrDataType->ToStringRaw(); ptrDataStr += StrFormat("(%s)", ptrDataTypeStr.c_str()) + EncodeDataPtr(dataPtr, true); DbgType* dwUsePtrType = dwUseType; @@ -7882,7 +7875,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (wantsRefThis) ptrUseDataStr += "*"; } - String ptrUseDataTypeStr = dwUsePtrType->ToStringRaw(); + String ptrUseDataTypeStr = dwUsePtrType->ToStringRaw(); ptrUseDataStr += StrFormat("(%s)", ptrUseDataTypeStr.c_str()) + EncodeDataPtr(dataPtr, true); if ((origTypedValue.mSrcAddress == -1) && (origTypedValue.mVariable != NULL)) @@ -7907,7 +7900,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c ptrDataStr = "(" + dwUseType->ToStringRaw() + ")"; ptrDataStr += DbgTypedValueToString(rawVal, expr, formatInfo, optEvaluator, fullPrecision); - + int editValIdx = ptrDataStr.IndexOf(":editVal"); if (editValIdx != -1) ptrDataStr.Remove(0, editValIdx + 9); @@ -7928,8 +7921,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } else if ((ptrVal == 0) && (dwValueType->IsCompositeType())) { - - } + } DbgTypedValue useTypedValue = typedValue; if ((origHadRef) || ((typedValue.mType->HasPointer()) && (!dwUseType->HasPointer()))) @@ -7944,7 +7936,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c { ReadMemory(useTypedValue.mSrcAddress, byteCount, &useTypedValue.mPtr); } - } + } } useTypedValue.mType = dwUseType; if ((!formatInfo.mNoVisualizers) && (!isNull) && (!isBadSrc)) @@ -7953,10 +7945,10 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c dwUseType->FixName(); debugVis = FindVisualizerForType(dwUseType, &dbgVisWildcardCaptures); } - + bool hadCustomDisplayString = false; if (debugVis != NULL) - { + { auto& displayStringList = (formatInfo.mRawString || wantStringView) ? debugVis->mStringViews : debugVis->mDisplayStrings; for (auto displayEntry : displayStringList) @@ -7979,12 +7971,12 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c ProcessEvalString(dbgCompileUnit, useTypedValue, displayStr, stringViewData, strFormatInfo, debugVis, true); } else - ProcessEvalString(dbgCompileUnit, useTypedValue, displayStr, displayString, formatInfo, debugVis, true); + ProcessEvalString(dbgCompileUnit, useTypedValue, displayStr, displayString, formatInfo, debugVis, true); if (formatInfo.mRawString) return displayString; - + break; - } + } if ((!debugVis->mExpandItems.empty()) || (debugVis->mCollectionType != DebugVisualizerEntry::CollectionType_None)) { @@ -8007,7 +7999,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c String firstRet; String bigRet = isTuple ? "(" : "{ "; - + int memberIdx = 0; DbgType* summaryType = dwUseType; bool summaryDone = false; @@ -8022,8 +8014,8 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c while (summaryType != NULL) { summaryType->PopulateType(); - - if ((summaryType->IsTypedPrimitive()) && + + if ((summaryType->IsTypedPrimitive()) && ((summaryType->mBaseTypes.IsEmpty()) || (!summaryType->mBaseTypes.front()->mBaseType->IsTypedPrimitive()))) { if (formatInfo.mTotalSummaryLength + (int)displayString.length() > 255) @@ -8033,15 +8025,15 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c bigRet += "..."; } else - { + { DwFormatInfo displayStrFormatInfo = formatInfo; displayStrFormatInfo.mExpandItemDepth = 1; displayStrFormatInfo.mTotalSummaryLength += (int)displayString.length(); displayStrFormatInfo.mHidePointers = false; - + DbgType* primType = summaryType->mTypeParam; String result; - + if (primType->IsInteger()) formatInfo.mTypeKindFlags = (DbgTypeKindFlags)(formatInfo.mTypeKindFlags | DbgTypeKindFlag_Int); @@ -8058,7 +8050,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c evalResult.mType = primType; String evalString = "(" + primType->ToString() + ")" + expr; result = DbgTypedValueToString(evalResult, evalString, displayStrFormatInfo, NULL); - } + } if (formatInfo.mRawString) return result; @@ -8070,7 +8062,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (memberIdx == 0) firstRet = result; - bigRet += result; + bigRet += result; memberIdx++; } } @@ -8110,7 +8102,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } DwFormatInfo displayStrFormatInfo = formatInfo; - displayStrFormatInfo.mExpandItemDepth = 1; + displayStrFormatInfo.mExpandItemDepth = 1; displayStrFormatInfo.mHidePointers = false; displayStrFormatInfo.mTotalSummaryLength = formatInfo.mTotalSummaryLength + retVal.length() + bigRet.length(); @@ -8150,13 +8142,13 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (formatInfo.mRawString) return result; - + if (memberIdx == 0) - firstRet = result; - + firstRet = result; + bigRet += result; //formatInfo.mEmbeddedDisplayCount = displayStrFormatInfo.mEmbeddedDisplayCount; - memberIdx++; + memberIdx++; } else { @@ -8178,11 +8170,11 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if ((checkBaseType->GetByteCount() > 0) || (checkBaseType->IsPrimitiveType())) { if (!splatStr.empty()) - { + { splatStr = "(" + checkBaseType->ToString() + ")" + splatStr; } else - { + { summaryTypedValue.mType = checkBaseType; } nextSummaryType = checkBaseType; @@ -8214,10 +8206,10 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if ((memberIdx == 1) && (!truncatedMemberList) && (firstRet.IndexOf('{') == -1) && (!isTuple)) displayString += "{ " + firstRet + " }"; else - displayString += bigRet; + displayString += bigRet; } - - DbgType* memberListType = actualType; + + DbgType* memberListType = actualType; bool memberListForceCast = false; if (actualType != NULL) { @@ -8230,12 +8222,12 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if (useActualRawType) actualUseTypeName = actualType->ToStringRaw(); - + if (displayString.empty()) { // Nothing to display } - else + else { if (!retVal.empty()) retVal += " "; @@ -8245,28 +8237,28 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c retVal += "\n" + valTypeName; if ((innerType->IsBaseBfObject()) || (innerType->IsInterface())) - { + { if (actualType != innerType) { - retVal += " {" + actualTypeName + "}"; + retVal += " {" + actualTypeName + "}"; memberListForceCast = true; - } + } } else - { + { if (actualType != innerType) { retVal += " {" + actualTypeName + "}"; retVal += "\n"; if (!wantsCustomExpandedItems) { - retVal += "[" + actualTypeName + "]\t((" + actualUseTypeName; + retVal += "[" + actualTypeName + "]\t((" + actualUseTypeName; if (!actualType->IsBfObject()) retVal += "*"; - retVal += ")this), nd, na, nv, this=" + ptrDataStr; + retVal += ")this), nd, na, nv, this=" + ptrDataStr; memberListType = innerType; } - } + } } } else @@ -8293,7 +8285,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c retVal += "\n" + displayType->ToString(DbgLanguage_Unknown, true); memberListType = innerType; } - + if ((isBfObject) && (mDebugTarget->mBfObjectHasFlags) && (!formatInfo.mNoVisualizers) && (!formatInfo.mRawString)) { int stackTraceLen = 1; @@ -8326,7 +8318,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c HandleCustomExpandedItems(retVal, dbgCompileUnit, debugVis, dwUseType, dwValueType, ptrUseDataStr, ptrDataStr, useTypedValue, dbgVisWildcardCaptures, formatInfo); } else if ((!isNull) && (!isBadSrc)) - { + { if (dataPtr == -1) { //String splatName = ((origTypedValue.mSrcAddress == -1) && (origTypedValue.mVariable != NULL)) ? origTypedValue.mVariable->mName : expr; @@ -8340,7 +8332,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c } if (formatInfo.mExpandItemDepth > 0) - return retVal; + return retVal; if (isAppendBfObject) retVal += "\n:appendAlloc"; if (isStackBfObject) @@ -8363,7 +8355,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c if ((!typedValue.mIsLiteral) && (dwValueType->IsPointer())) { - retVal += "\n:editVal\t" + EncodeDataPtr(ptrVal, true); + retVal += "\n:editVal\t" + EncodeDataPtr(ptrVal, true); } if (((debugVis != NULL) && (!debugVis->mStringViews.IsEmpty())) || (wantStringView)) @@ -8388,7 +8380,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC if (formatInfo.mExpandItemDepth > 10) // Avoid crashing on circular ExpandItems return; - + auto language = formatInfo.mLanguage; bool isReadOnly = false; @@ -8414,7 +8406,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC String referenceId = dwUseType->ToString(); if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_ExpandedItem) - { + { DbgTypedValue itemValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures), &formatInfo); if (itemValue) { @@ -8428,11 +8420,11 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC crIdx = (int)itemRetVal.IndexOf('\n', crIdx + 1); if (crIdx != -1) retVal += itemRetVal.Substring(crIdx); - } + } } } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Array) - { + { DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); Array lowerDimSizes; for (auto lowerDim : debugVis->mLowerDimSizes) @@ -8510,7 +8502,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC { int dimSize1 = lowerDimSizes[0]; - String evalStr = "(" + debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures) + + String evalStr = "(" + debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures) + StrFormat(" + {0} * %d), arraysize=%d, na, this=", dimSize1, dimSize1) + ptrUseDataStr; evalStr += ", refid=\"" + referenceId + ".[]\""; if (isReadOnly) @@ -8526,7 +8518,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC DbgTypedValue headPointer = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures), &formatInfo); if ((headPointer.mType != NULL) && (headPointer.mType->IsPointer())) { - String evalStr = StrFormat("((%s[%d]*)", headPointer.mType->mTypeParam->ToStringRaw(language).c_str(), dimSize2) + debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures) + + String evalStr = StrFormat("((%s[%d]*)", headPointer.mType->mTypeParam->ToStringRaw(language).c_str(), dimSize2) + debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures) + StrFormat(" + {0} * %d), arraysize=%d, na, this=", dimSize1, dimSize1) + ptrUseDataStr; evalStr += ", refid=\"" + referenceId + ".[]\""; if (isReadOnly) @@ -8554,7 +8546,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC } } else - { + { String evalStr = "*(" + debugVisualizers->DoStringReplace(debugVis->mValuePointer, dbgVisWildcardCaptures) + " + {0}), this=" + ptrUseDataStr; evalStr += ", refid=\"" + referenceId + ".[]${0}\""; if (isReadOnly) @@ -8565,11 +8557,11 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC } } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_IndexItems) - { + { DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); - + if ((sizeValue) && (sizeValue.mType->IsInteger()) && (sizeValue.GetInt64() > 0)) - { + { String evalStr = debugVis->mValuePointer + ", this=" + ptrUseDataStr; evalStr.Replace("$i", "{0}"); @@ -8577,7 +8569,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC if (isReadOnly) evalStr += ", ne"; retVal += "\n:repeat" + StrFormat("\t%d\t%lld\t%d", 0, sizeValue.GetInt64(), 50000) + - "\t[{0}]\t" + evalStr; + "\t[{0}]\t" + evalStr; } } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_LinkedList) @@ -8619,7 +8611,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC { const char* addrsPtr = addrs.c_str(); firstAddr = addrs.Substring(0, sizeof(addr_target)*2); - if (hasSecondAddr) + if (hasSecondAddr) secondAddr = addrs.Substring(sizeof(addr_target)*2, sizeof(addr_target)*2); } @@ -8676,7 +8668,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC if (sizeValue) sizeValue.mType = sizeValue.mType->RemoveModifiers(); if ((sizeValue) && (headPointer) && (sizeValue.mType->IsInteger()) && (sizeValue.GetInt64() > 0)) - { + { DbgTypedValue curNode = headPointer; Array parentList; String continuationData; @@ -8728,9 +8720,9 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC retVal += "\n:addrs\t" + addrs; if (continuationData.length() > 0) retVal += "\n:continuation\t" + continuationData; - } + } } - } + } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary) { DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo); @@ -8739,7 +8731,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC if (sizeValue) sizeValue.mType = sizeValue.mType->RemoveModifiers(); if ((sizeValue) && (entriesPtrValue) && (sizeValue.mType->IsInteger()) && (sizeValue.GetInt64() > 0)) - { + { String continuationData; DbgType* valueType = entriesPtrValue.mType; @@ -8771,15 +8763,15 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC retVal += "\n:addrs\t" + addrs; if (continuationData.length() > 0) retVal += "\n:continuation\t" + continuationData; - } + } } } else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_CallStackList) - { + { int size = 0; String addrs; - String firstVal; + String firstVal; auto ptr = useTypedValue.mPtr; for (int i = 0; i < formatInfo.mOverrideCount; i++) @@ -8792,7 +8784,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC firstVal = addrs; addrs += EncodeDataPtr((addr_target)0, false); size++; - + int inlineIdx = 0; auto subProgram = mDebugTarget->FindSubProgram(funcAddr - 1, DbgOnDemandKind_LocalOnly); @@ -8800,7 +8792,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC { if (subProgram->mInlineeInfo == NULL) break; - + auto prevFuncAddr = subProgram->mBlock.mLowPC; subProgram = subProgram->mInlineeInfo->mInlineParent; @@ -8812,14 +8804,14 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC } } - String evalStr = "(System.CallStackAddr)0x{1}"; - evalStr += ", refid=\"" + referenceId + ".[]\""; + String evalStr = "(System.CallStackAddr)0x{1}"; + evalStr += ", refid=\"" + referenceId + ".[]\""; evalStr += ", ne"; retVal += "\n:repeat" + StrFormat("\t%d\t%d\t%d", 0, size, 10000) + "\t[{0}]\t" + evalStr + ", action=ShowCodeAddr {1} {2}\t" + firstVal + "\t" + EncodeDataPtr((addr_target)0, false); - - retVal += "\n:addrs\t" + addrs; + + retVal += "\n:addrs\t" + addrs; retVal += "\n:addrsEntrySize\t2"; return; } @@ -8867,7 +8859,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la regNum = X86Reg_EIP; else if (lwrRegName == "efl") regNum = X86Reg_EFL; -#else +#else DbgTypeCode regType = DbgType_i64; if (lwrRegName == "rax") @@ -8887,7 +8879,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la else if (lwrRegName == "rdi") regNum = X64Reg_RDI; else if (lwrRegName == "rip") - regNum = X64Reg_RIP; + regNum = X64Reg_RIP; else if (lwrRegName == "r8") regNum = X64Reg_R8; else if (lwrRegName == "r9") @@ -8920,7 +8912,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la else if (lwrRegName == "esi") regNum = X64Reg_RSI; else if (lwrRegName == "edi") - regNum = X64Reg_RDI; + regNum = X64Reg_RDI; else if (lwrRegName == "r8d") regNum = X64Reg_R8; else if (lwrRegName == "r9d") @@ -8947,11 +8939,11 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la else if (lwrRegName == "dx") regNum = X64Reg_RDX; else if (lwrRegName == "bx") - regNum = X64Reg_RBX; + regNum = X64Reg_RBX; else if (lwrRegName == "si") regNum = X64Reg_RSI; else if (lwrRegName == "di") - regNum = X64Reg_RDI; + regNum = X64Reg_RDI; else if (lwrRegName == "r8w") regNum = X64Reg_R8; else if (lwrRegName == "r9w") @@ -8982,7 +8974,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la else if (lwrRegName == "sil") regNum = X64Reg_RSI; else if (lwrRegName == "dil") - regNum = X64Reg_RDI; + regNum = X64Reg_RDI; else if (lwrRegName == "r8b") regNum = X64Reg_R8; else if (lwrRegName == "r9b") @@ -9003,9 +8995,9 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la } } #endif - + auto dbgModule = mEmptyDebugTarget->GetMainDbgModule(); - + if (regNum != -1) { DbgTypedValue typedVal; @@ -9054,12 +9046,12 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la regNum = CPUReg_XMMREG_FIRST + ((lwrRegName[3] - '0') * 4) + (lwrRegName[5] - '0'); } #else - if ((lwrRegName.length() == 6) && (lwrRegName[0] == 'x') && (lwrRegName[1] == 'm') && (lwrRegName[2] == 'm') && (lwrRegName[3] >= '0') && (lwrRegName[3] <= '9') && + if ((lwrRegName.length() == 6) && (lwrRegName[0] == 'x') && (lwrRegName[1] == 'm') && (lwrRegName[2] == 'm') && (lwrRegName[3] >= '0') && (lwrRegName[3] <= '9') && (lwrRegName[4] == '_') && (lwrRegName[5] >= '0') && (lwrRegName[5] <= '3')) { regNum = CPUReg_XMMREG_FIRST + ((lwrRegName[3] - '0') * 4) + (lwrRegName[5] - '0'); } - if ((lwrRegName.length() == 7) && (lwrRegName[0] == 'x') && (lwrRegName[1] == 'm') && (lwrRegName[2] == 'm') && (lwrRegName[3] == '1') && (lwrRegName[4] >= '0') && (lwrRegName[4] <= '9') && + if ((lwrRegName.length() == 7) && (lwrRegName[0] == 'x') && (lwrRegName[1] == 'm') && (lwrRegName[2] == 'm') && (lwrRegName[3] == '1') && (lwrRegName[4] >= '0') && (lwrRegName[4] <= '9') && (lwrRegName[5] == '_') && (lwrRegName[6] >= '0') && (lwrRegName[6] <= '3')) { regNum = CPUReg_XMMREG_FIRST + ((10 + (lwrRegName[4] - '0')) * 4) + (lwrRegName[6] - '0'); @@ -9097,7 +9089,7 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la typedVal.mRegNum = regNum; return typedVal; } - else if ((mmDisplayType == DwMmDisplayType_UInt8) || (mmDisplayType == DwMmDisplayType_Int16) || (mmDisplayType == DwMmDisplayType_Int32)) + else if ((mmDisplayType == DwMmDisplayType_UInt8) || (mmDisplayType == DwMmDisplayType_Int16) || (mmDisplayType == DwMmDisplayType_Int32)) { DbgTypedValue typedVal; typedVal.mType = dbgModule->GetPrimitiveType(DbgType_i32, language); @@ -9195,12 +9187,12 @@ DbgTypedValue WinDebugger::GetRegister(const StringImpl& regName, DbgLanguage la typedVal.mRegNum = regNum; return typedVal; } - + return DbgTypedValue(); } DbgModule* WinDebugger::GetCallStackDbgModule(int callStackIdx) -{ +{ if ((mRunState == RunState_NotStarted) || (!IsPaused())) return mEmptyDebugTarget->GetMainDbgModule(); if (callStackIdx == -1) @@ -9216,7 +9208,7 @@ DbgModule* WinDebugger::GetCallStackDbgModule(int callStackIdx) auto dbgModule = mDebugTarget->FindDbgModuleForAddress(mCallStack[callStackIdx]->mRegisters.GetPC()); if (dbgModule != NULL) return dbgModule; - return mDebugTarget->GetMainDbgModule(); + return mDebugTarget->GetMainDbgModule(); } DbgSubprogram* WinDebugger::GetCallStackSubprogram(int callStackIdx) @@ -9228,7 +9220,7 @@ DbgSubprogram* WinDebugger::GetCallStackSubprogram(int callStackIdx) if (mCallStack.IsEmpty()) return NULL; if (callStackIdx >= (int)mCallStack.size()) - callStackIdx = 0; + callStackIdx = 0; UpdateCallStackMethod(callStackIdx); auto subProgram = mCallStack[callStackIdx]->mSubProgram; return subProgram; @@ -9286,7 +9278,7 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance // Don't allow pending calls if we've already failed in the calling Evaluate() pendingExpr->mExpressionFlags = (DwEvalExpressionFlags)(pendingExpr->mExpressionFlags & ~DwEvalExpressionFlag_AllowCalls); } - + DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, pendingExpr->mCallStackIdx, pendingExpr->mCursorPos); if (!pendingExpr->mFormatInfo.mStackSearchStr.IsEmpty()) { @@ -9294,8 +9286,8 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance dbgExprEvaluator.mStackSearch->mSearchStr = pendingExpr->mFormatInfo.mStackSearchStr; } dbgExprEvaluator.mLanguage = pendingExpr->mFormatInfo.mLanguage; - dbgExprEvaluator.mReferenceId = &pendingExpr->mReferenceId; - dbgExprEvaluator.mExpressionFlags = pendingExpr->mExpressionFlags; + dbgExprEvaluator.mReferenceId = &pendingExpr->mReferenceId; + dbgExprEvaluator.mExpressionFlags = pendingExpr->mExpressionFlags; dbgExprEvaluator.mExplicitThis = pendingExpr->mFormatInfo.mExplicitThis; dbgExprEvaluator.mSubjectExpr = pendingExpr->mFormatInfo.mSubjectExpr; dbgExprEvaluator.mNamespaceSearchStr = pendingExpr->mFormatInfo.mNamespaceSearch; @@ -9308,19 +9300,19 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance if (pendingExpr->mCursorPos != -1) { - dbgExprEvaluator.mAutoComplete = &autoComplete; + dbgExprEvaluator.mAutoComplete = &autoComplete; } dbgExprEvaluator.mDbgCompileUnit = dbgCompileUnit; - DbgTypedValue exprResult; + DbgTypedValue exprResult; if (pendingExpr->mExplitType != NULL) { exprResult.mHasNoValue = true; - exprResult.mType = pendingExpr->mExplitType; + exprResult.mType = pendingExpr->mExplitType; } else if (pendingExpr->mExprNode != NULL) { - exprResult = dbgExprEvaluator.Resolve(pendingExpr->mExprNode); + exprResult = dbgExprEvaluator.Resolve(pendingExpr->mExprNode); } if (dbgExprEvaluator.mCreatedPendingCall) @@ -9334,24 +9326,24 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance pendingExpr->mFormatInfo.mOverrideCount = dbgExprEvaluator.mCountResultOverride; String val; - if (bfPassInstance.HasFailed()) + if (bfPassInstance.HasFailed()) { BfLogDbgExpr("Evaluate Failed: %s\n", bfPassInstance.mErrors[0]->mError.c_str()); - val = StrFormat("!%d\t%d\t%s", bfPassInstance.mErrors[0]->GetSrcStart(), bfPassInstance.mErrors[0]->GetSrcLength(), bfPassInstance.mErrors[0]->mError.c_str()); + val = StrFormat("!%d\t%d\t%s", bfPassInstance.mErrors[0]->GetSrcStart(), bfPassInstance.mErrors[0]->GetSrcLength(), bfPassInstance.mErrors[0]->mError.c_str()); } else if (dbgExprEvaluator.mBlockedSideEffects) { BfLogDbgExpr("Evaluate blocked side effects\n"); val = "!sideeffects"; - } + } else if (!exprResult) { if (exprResult.mType != NULL) { BfLogDbgExpr("Evaluate success\n"); - String typeName = exprResult.mType->ToString(); - DbgType* rawType = exprResult.mType; + String typeName = exprResult.mType->ToString(); + DbgType* rawType = exprResult.mType; if (rawType->IsBfObjectPtr()) rawType = rawType->mTypeParam; String typeNameRaw = rawType->ToStringRaw(); @@ -9394,11 +9386,11 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance } } else if ((pendingExpr->mExpressionFlags & (DwEvalExpressionFlag_MemoryWatch)) != 0) - { + { DbgType* resultType = exprResult.mType->RemoveModifiers(); bool isMemoryWatch = (pendingExpr->mExpressionFlags & DwEvalExpressionFlag_MemoryWatch) != 0; - + if (!resultType->IsPointerOrRef()) { if (exprResult.mSrcAddress != 0) @@ -9452,7 +9444,7 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance exprResult.mIsReadOnly = true; if (!pendingExpr->mReferenceId.empty()) pendingExpr->mFormatInfo.mReferenceId = pendingExpr->mReferenceId; - val = DbgTypedValueToString(exprResult, pendingExpr->mExprNode->ToString(), pendingExpr->mFormatInfo, &dbgExprEvaluator, (pendingExpr->mExpressionFlags & DwEvalExpressionFlag_FullPrecision) != 0); + val = DbgTypedValueToString(exprResult, pendingExpr->mExprNode->ToString(), pendingExpr->mFormatInfo, &dbgExprEvaluator, (pendingExpr->mExpressionFlags & DwEvalExpressionFlag_FullPrecision) != 0); if ((!val.empty()) && (val[0] == '!')) return val; @@ -9522,7 +9514,7 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance const char* langStr = (pendingExpr->mFormatInfo.mLanguage == DbgLanguage_Beef) ? "@Beef:" : "@C:"; if (exprResult.mSrcAddress != 0) - { + { val += StrFormat("\n:addrValueExpr\t%s(%s*)", langStr, exprResult.mType->ToString(pendingExpr->mFormatInfo.mLanguage).c_str()); val += EncodeDataPtr(exprResult.mSrcAddress, true); } @@ -9541,7 +9533,7 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance if (val[0] == '!') { // Already has an error embedded, can't edit - } + } else if ((exprResult.mSrcAddress != 0) && (underlyingType->mTypeCode >= DbgType_i8) && (underlyingType->mTypeCode <= DbgType_Ptr) && (underlyingType->mTypeCode != DbgType_Class) && (underlyingType->mTypeCode != DbgType_Struct)) { @@ -9550,13 +9542,13 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance if (exprResult.mType->mTypeCode == DbgType_Ptr) { val += "\n:editVal\t" + EncodeDataPtr(exprResult.mPtr, true); - } + } } else if ((underlyingType->IsStruct()) && (exprResult.mSrcAddress != 0) && (underlyingType->IsTypedPrimitive())) { auto primType = underlyingType->GetRootBaseType(); DbgTypedValue primVal = dbgExprEvaluator.ReadTypedValue(NULL, primType, exprResult.mSrcAddress, DbgAddrType_Target); - + String primResult = DbgTypedValueToString(primVal, "", pendingExpr->mFormatInfo, NULL); int crPos = (int)primResult.IndexOf('\n'); if (crPos != -1) @@ -9571,12 +9563,12 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance bool isPseudoReg = ( ((exprResult.mRegNum >= X86Reg_M128_XMMREG_FIRST) && (exprResult.mRegNum <= X86Reg_M128_XMMREG_LAST)) || ((exprResult.mRegNum >= X86Reg_CAT_FIRST) && (exprResult.mRegNum <= X86Reg_CAT_LAST)) ); if (!isPseudoReg) - { + { if (canEdit) val += "\n:canEdit"; } - } - } + } + } if (pendingExpr->mFormatInfo.mRawString) return ""; @@ -9590,10 +9582,10 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance val += StrFormat("\n:stackIdx\t%d", pendingExpr->mStackIdxOverride); } - if (pendingExpr->mCursorPos != -1) + if (pendingExpr->mCursorPos != -1) val += GetAutocompleteOutput(autoComplete); - - return val; + + return val; } String WinDebugger::EvaluateContinue() @@ -9606,7 +9598,7 @@ String WinDebugger::EvaluateContinue() return "!Evaluation canceled"; if (!IsPaused()) - return "!Not paused"; + return "!Not paused"; if (mRunState == RunState_DebugEval_Done) mRunState = RunState_Paused; @@ -9616,7 +9608,7 @@ String WinDebugger::EvaluateContinue() if (result != "!pending") { BfLogDbg("EvaluateContinue finishing pending expr in thread %d\n", mDebugEvalThreadInfo.mThreadId); - CleanupDebugEval(); + CleanupDebugEval(); } return result; @@ -9629,27 +9621,27 @@ void WinDebugger::EvaluateContinueKeep() } static void PdbTestFile(WinDebugger* debugger, const StringImpl& path) -{ +{ if (!path.EndsWith(".PDB", StringImpl::CompareKind_OrdinalIgnoreCase)) return; - + OutputDebugStrF("Testing %s\n", path.c_str()); COFF coffFile(debugger->mDebugTarget); uint8 wantGuid[16] = { 0 }; if (!coffFile.TryLoadPDB(path, wantGuid, -1)) - return; + return; if (!coffFile.mIs64Bit) - return; + return; coffFile.ParseTypeData(); coffFile.ParseSymbolData(); - coffFile.ParseGlobalsData(); - + coffFile.ParseGlobalsData(); + for (int i = 0; i < coffFile.mTypes.mSize; i++) coffFile.mTypes[i]->PopulateType(); } static void PdbTest(WinDebugger* debugger, const StringImpl& path) -{ +{ for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Files)) { String filePath = fileEntry.GetFilePath(); @@ -9662,15 +9654,15 @@ static void PdbTest(WinDebugger* debugger, const StringImpl& path) String childPath = fileEntry.GetFilePath(); String dirName; dirName = GetFileName(childPath); - + PdbTest(debugger, childPath); - } + } } String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags) { BP_ZONE_F("WinDebugger::Evaluate %s", BP_DYN_STR(expr.c_str())); - + AutoCrit autoCrit(mDebugManager->mCritSect); if ((expressionFlags & DwEvalExpressionFlag_Symbol) != 0) @@ -9686,20 +9678,20 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in UpdateCallStackMethod(callStackIdx); BfLogDbgExpr("Evaluate %s in thread %d\n", expr.c_str(), (mActiveThread != NULL) ? mActiveThread->mThreadId : 0); - + if (language != -1) formatInfo.mLanguage = (DbgLanguage)language; auto activeThread = mActiveThread; if ((!IsPaused()) && (mRunState != RunState_NotStarted) && (mRunState != RunState_DebugEval)) - { + { activeThread = NULL; callStackIdx = -1; } - + if (mDebugPendingExpr != NULL) { - // We already have a pending call + // We already have a pending call expressionFlags = (DwEvalExpressionFlags)(expressionFlags & ~DwEvalExpressionFlag_AllowCalls); } @@ -9724,7 +9716,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in }); bool usedSpecifiedLock = false; - int stackIdxOverride = -1; + int stackIdxOverride = -1; if (terminatedExpr.StartsWith('{')) { @@ -9766,9 +9758,9 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in locString.Remove(0, 5); char* endPtr = NULL; int64 funcAddr = (int64)strtoll(locString.c_str(), &endPtr, 16); - + if (endPtr != NULL) - { + { // Actually do it if ((mActiveThread != NULL) && (mActiveThread->mThreadId != threadId)) @@ -9797,7 +9789,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in if (stackFrame->mRegisters.GetSP() > sp) { foundStackIdx = checkStackIdx - 1; - break; + break; } checkStackIdx++; @@ -9807,7 +9799,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in { UpdateCallStackMethod(foundStackIdx); auto stackFrame = mCallStack[foundStackIdx]; - + if ((stackFrame->mSubProgram != NULL) && ((int64)stackFrame->mSubProgram->mBlock.mLowPC == funcAddr)) { if ((callStackIdx != foundStackIdx) || (mActiveThread != prevActiveThread)) @@ -9836,7 +9828,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in if (c == '}') break; } - else + else { if (c == '{') { @@ -9847,17 +9839,16 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in doClear = true; } else if (!::isspace((uint8)c)) - break; + break; } - } - } + } else if (!locString.IsEmpty()) - { + { const char* checkPtr = locString.c_str(); if ((*checkPtr == '^') || (*checkPtr == '@')) checkPtr++; - + char* endPtr = NULL; int useCallStackIdx = strtol(checkPtr, &endPtr, 10); if (endPtr == locString.c_str() + locString.length()) @@ -9879,8 +9870,8 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in auto dbgSubprogram = GetCallStackSubprogram(callStackIdx); DbgCompileUnit* dbgCompileUnit = NULL; if (dbgSubprogram != NULL) - dbgCompileUnit = dbgSubprogram->mCompileUnit; - + dbgCompileUnit = dbgSubprogram->mCompileUnit; + if ((expr.length() > 0) && (expr[0] == '!')) { if (expr.StartsWith("!step ")) @@ -9930,14 +9921,14 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in PdbTestFile(this, cmd.Substring(9)); } } - + bool valIsAddr = false; - + BfParser* parser = new BfParser(mBfSystem); parser->mCompatMode = true; - - BfPassInstance bfPassInstance(mBfSystem); - + + BfPassInstance bfPassInstance(mBfSystem); + if ((terminatedExpr.length() > 2) && (terminatedExpr[0] == '@')) { if (terminatedExpr[1] == '!') // Return string as error @@ -9956,7 +9947,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in else return terminatedExpr.Substring(2); } - else // Look for "@:" or "@Beef:" style + else // Look for "@:" or "@Beef:" style { int colonIdx = terminatedExpr.IndexOf(':'); if (colonIdx > 0) @@ -9982,13 +9973,13 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in if (dbgSubprogram != NULL) curLanguage = dbgSubprogram->GetLanguage(); if (language != curLanguage) - { + { dbgModule = mDebugTarget->mTargetBinary; dbgSubprogram = NULL; formatInfo.mLanguage = language; callStackIdx = -1; } - } + } } } } @@ -10006,24 +9997,24 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in bfReducer.mSource = parser; auto exprNode = bfReducer.CreateExpression(parser->mRootNode->mChildArr.GetAs(0)); parser->Close(); - + formatInfo.mCallStackIdx = callStackIdx; if ((formatInfo.mLanguage == DbgLanguage_Unknown) && (dbgSubprogram != NULL)) formatInfo.mLanguage = dbgSubprogram->GetLanguage(); - - DbgPendingExpr* pendingExpr = new DbgPendingExpr(); + + DbgPendingExpr* pendingExpr = new DbgPendingExpr(); if (activeThread != NULL) pendingExpr->mThreadId = activeThread->mThreadId; - pendingExpr->mParser = parser; + pendingExpr->mParser = parser; pendingExpr->mCallStackIdx = callStackIdx; - pendingExpr->mCursorPos = cursorPos; + pendingExpr->mCursorPos = cursorPos; pendingExpr->mExpressionFlags = expressionFlags; - pendingExpr->mExprNode = exprNode; + pendingExpr->mExprNode = exprNode; DbgType* explicitType = NULL; String formatFlags; String assignExpr; - int assignExprOffset = -1; + int assignExprOffset = -1; if ((exprNode != NULL) && (exprNode->GetSrcEnd() < (int)expr.length())) { @@ -10046,9 +10037,9 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in { explicitType = dbgModule->FindType(expr); } - + if ((explicitType == NULL) && (formatFlags.length() > 0)) - { + { String errorString = "Invalid expression"; if (!ParseFormatInfo(dbgModule, formatFlags, &formatInfo, &bfPassInstance, &assignExprOffset, &assignExpr, &errorString)) { @@ -10060,13 +10051,13 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in if (assignExprOffset != -1) assignExprOffset += formatOffset; } - } + } if (assignExpr.length() > 0) { String newEvalStr = exprNode->ToString() + " = "; int errorOffset = (int)newEvalStr.length(); - newEvalStr += assignExpr; + newEvalStr += assignExpr; String result = Evaluate(newEvalStr, formatInfo, callStackIdx, cursorPos, language, expressionFlags); if (result[0] == '!') { @@ -10082,7 +10073,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in } return result; } - + pendingExpr->mUsedSpecifiedLock = usedSpecifiedLock; pendingExpr->mStackIdxOverride = stackIdxOverride; pendingExpr->mExplitType = explicitType; @@ -10097,12 +10088,12 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in } mDebugPendingExpr = pendingExpr; mDebugEvalThreadInfo = *mActiveThread; - mActiveThread->mIsAtBreakpointAddress = 0; + mActiveThread->mIsAtBreakpointAddress = 0; mActiveThread->mStoppedAtAddress = 0; mActiveThread->mBreakpointAddressContinuing = 0; } else - delete pendingExpr; + delete pendingExpr; return result; } @@ -10173,7 +10164,7 @@ static void ConvertDoubleToFloat80(double d, byte fp80[10]) bool WinDebugger::AssignToReg(int callStackIdx, DbgTypedValue regVal, DbgTypedValue value, String& outError) { BF_ASSERT(regVal.mRegNum >= 0); - + if (mCallStack.size() == 0) { outError = "No call stack"; @@ -10290,7 +10281,7 @@ bool WinDebugger::AssignToReg(int callStackIdx, DbgTypedValue regVal, DbgTypedVa if (value.mType->GetByteCount() == 4) registers->mXmmRegsArray[xmmMajor].f[xmmMinor] = value.mSingle; else if (value.mType->GetByteCount() == 8) - registers->mXmmDRegsArray[xmmMajor].d[xmmMinor] = value.mDouble; + registers->mXmmDRegsArray[xmmMajor].d[xmmMinor] = value.mDouble; else BF_FATAL("Invalid XMM set value type"); regPtr = ®isters->mXmmRegsArray[xmmMajor]; @@ -10325,9 +10316,9 @@ bool WinDebugger::AssignToReg(int callStackIdx, DbgTypedValue regVal, DbgTypedVa else BF_FATAL("Not implemented"); #endif - + if (callStackIdx == 0) - { + { SetRegisters(&mCallStack[0]->mRegisters); return true; } @@ -10336,7 +10327,7 @@ bool WinDebugger::AssignToReg(int callStackIdx, DbgTypedValue regVal, DbgTypedVa bool wasSaved = false; for (int calleeStackIdx = callStackIdx - 1; calleeStackIdx >= 0; calleeStackIdx--) { - auto calleeRegisters = &mCallStack[calleeStackIdx]->mRegisters; + auto calleeRegisters = &mCallStack[calleeStackIdx]->mRegisters; if (!mDebugTarget->PropogateRegisterUpCallStack(registers, calleeRegisters, regPtr, wasSaved)) { outError = "Failed to set register"; @@ -10345,10 +10336,10 @@ bool WinDebugger::AssignToReg(int callStackIdx, DbgTypedValue regVal, DbgTypedVa if (wasSaved) return true; } - + // This register wasn't saved, so commit it to the callstack top return AssignToReg(0, regVal, value, outError); - } + } } String WinDebugger::GetAutocompleteOutput(DwAutoComplete& autoComplete) @@ -10412,13 +10403,13 @@ String WinDebugger::EvaluateToAddress(const StringImpl& expr, int callStackIdx, bfReducer.mSystem = mBfSystem; bfReducer.mPassInstance = &bfPassInstance; bfReducer.mVisitorPos = BfReducer::BfVisitorPos(parser.mRootNode); - bfReducer.mVisitorPos.MoveNext(); + bfReducer.mVisitorPos.MoveNext(); bfReducer.mSource = &parser; auto exprNode = bfReducer.CreateExpression(parser.mRootNode->GetFirst()); parser.Close(); - + DwAutoComplete autoComplete; - DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, callStackIdx, cursorPos); + DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, callStackIdx, cursorPos); if (cursorPos != -1) dbgExprEvaluator.mAutoComplete = &autoComplete; dbgExprEvaluator.mDbgCompileUnit = dbgCompileUnit; @@ -10442,7 +10433,7 @@ String WinDebugger::EvaluateToAddress(const StringImpl& expr, int callStackIdx, val = "!Invalid expression"; } else if (!resultType->IsPointerOrRef()) - { + { if (exprResult.mSrcAddress != 0) val = StrFormat("!Type '%s' is invalid. A sized pointer type is expected. Try using the '&' address-of operator.", exprResult.mType->ToString().c_str()); else @@ -10509,17 +10500,17 @@ String WinDebugger::EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int String WinDebugger::GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) { BP_ZONE("WinDebugger::GetAutoExpressions"); - + AutoCrit autoCrit(mDebugManager->mCritSect); if (IsInRunState()) return "!Not paused"; if (!IsPaused()) - return "!Not running"; + return "!Not running"; if (!FixCallStackIdx(callStackIdx)) - return ""; + return ""; CPUStackFrame* stackFrame = (callStackIdx >= 0) ? mCallStack[callStackIdx] : mCallStack.front(); @@ -10550,7 +10541,7 @@ String WinDebugger::GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart if (callStackIdx < (int)mCallStack.size() - 2) { WdStackFrame* prevStackFrame = mCallStack[callStackIdx + 1]; - // Inlined methods have no stack frame + // Inlined methods have no stack frame int stackSize = prevStackFrame->mRegisters.GetSP() - stackFrame->mRegisters.GetSP(); result += StrFormat("&$StackFrame\t%llu\t%llu\n", stackSize, stackFrame->mRegisters.GetSP()); } @@ -10571,18 +10562,18 @@ String WinDebugger::GetAutoLocals(int stackFrameIdx, bool showRegs) return ""; if (mCallStack.size() == 0) - UpdateCallStack(); - String result; + UpdateCallStack(); + String result; Array localList; - + int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); UpdateCallStackMethod(actualStackFrameIdx); if (actualStackFrameIdx >= mCallStack.size()) return ""; WdStackFrame* wdStackFrame = mCallStack[actualStackFrameIdx]; - + DbgSubprogram* dwSubprogram = wdStackFrame->mSubProgram; if (dwSubprogram == NULL) return ""; @@ -10600,7 +10591,7 @@ String WinDebugger::GetAutoLocals(int stackFrameIdx, bool showRegs) for (auto local : localList) { if (langage == DbgLanguage_C) - { + { if ((local == "this") && (strncmp(dwSubprogram->mName, "GetFirst()); parser.Close(); - - if ((exprNode == NULL) || (parentExprNode == NULL)) - return "!failed"; - DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, callStackIdx, -1); + if ((exprNode == NULL) || (parentExprNode == NULL)) + return "!failed"; + + DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, callStackIdx, -1); DwFormatInfo formatInfo; - formatInfo.mCallStackIdx = callStackIdx; + formatInfo.mCallStackIdx = callStackIdx; formatInfo.mLanguage = language; String formatFlags; @@ -10721,7 +10712,7 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI dbgExprEvaluator.mExplicitThisExpr = parentExprNode; DbgTypedValue exprResult = dbgExprEvaluator.Resolve(exprNode); - BfAstNode* headNode = dbgExprEvaluator.FinalizeExplicitThisReferences(exprNode); + BfAstNode* headNode = dbgExprEvaluator.FinalizeExplicitThisReferences(exprNode); BfPrinter printer(parser.mRootNode, NULL, NULL); printer.mIgnoreTrivia = true; @@ -10752,7 +10743,7 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI String WinDebugger::GetProcessInfo() { AutoCrit autoCrit(mDebugManager->mCritSect); - + if ((mActiveThread == NULL) && (!mIsRunning)) return ""; @@ -10766,18 +10757,18 @@ String WinDebugger::GetProcessInfo() ::GetProcessTimes(mProcessInfo.hProcess, &creationTime, &exitTime, &kernelTime, &userTime); String retStr; - PROCESS_MEMORY_COUNTERS memInfo = { 0 }; + PROCESS_MEMORY_COUNTERS memInfo = { 0 }; ::GetProcessMemoryInfo(mProcessInfo.hProcess, &memInfo, sizeof(PROCESS_MEMORY_COUNTERS)); - + FILETIME currentTime = { 0 }; ::GetSystemTimeAsFileTime(¤tTime); - retStr += StrFormat("VirtualMemory\t%d\n", memInfo.PagefileUsage); - retStr += StrFormat("WorkingMemory\t%d\n", memInfo.WorkingSetSize); + retStr += StrFormat("VirtualMemory\t%lld\n", memInfo.PagefileUsage); + retStr += StrFormat("WorkingMemory\t%lld\n", memInfo.WorkingSetSize); retStr += StrFormat("RunningTime\t%lld\n", *(int64*)¤tTime - *(int64*)&creationTime); retStr += StrFormat("KernelTime\t%lld\n", *(int64*)&kernelTime / sysinfo.dwNumberOfProcessors); retStr += StrFormat("UserTime\t%lld\n", *(int64*)&userTime / sysinfo.dwNumberOfProcessors); - + return retStr; } @@ -10794,20 +10785,20 @@ String WinDebugger::GetThreadInfo() { if (mActiveThread != NULL) retStr = StrFormat("%d", mActiveThread->mThreadId); - + for (auto threadInfo : mThreadList) { SetAndRestoreValue prevThread(mActiveThread, threadInfo); retStr += "\n"; - + for (int pass = 0; pass < 2; pass++) { CPURegisters registers; PopulateRegisters(®isters); String locString = EncodeDataPtr((addr_target)registers.GetPC(), true); - + TryGetThreadName(threadInfo); bool hadThreadName = true; @@ -10821,7 +10812,7 @@ String WinDebugger::GetThreadInfo() threadName = "Worker Thread"; } - bool isInvalid = false; + bool isInvalid = false; addr_target appendAddr = 0; for (int stackIdx = 0; true; stackIdx++) @@ -10847,22 +10838,22 @@ String WinDebugger::GetThreadInfo() break; } } - + DbgModule* module = mDebugTarget->FindDbgModuleForAddress(registers.GetPC()); - if (module == NULL) + if (module == NULL) { isInvalid = true; break; } - + DbgModule* linkedModule = module->GetLinkedModule(); appendAddr = (addr_target)registers.GetPC(); locString = linkedModule->mDisplayName + "!" + EncodeDataPtr((addr_target)registers.GetPC(), true); if (!hadThreadName) threadName = linkedModule->mDisplayName + " thread"; - + if ((mActiveThread == mExplicitStopThread) && (mActiveBreakpoint != NULL)) - { + { if ((subProgram == NULL) || (mActiveBreakpoint->mAddr < subProgram->mBlock.mLowPC) || (mActiveBreakpoint->mAddr >= subProgram->mBlock.mHighPC)) @@ -10885,7 +10876,7 @@ String WinDebugger::GetThreadInfo() if ((isInvalid) && (pass == 0)) continue; - + if (appendAddr != 0) { String symbolName; @@ -10902,7 +10893,7 @@ String WinDebugger::GetThreadInfo() locString = demangledName + StrFormat("+0x%X", offset); } } - + retStr += StrFormat("%d\t%s\t%s", threadInfo->mThreadId, threadName.c_str(), locString.c_str()); String attrs; @@ -10913,7 +10904,7 @@ String WinDebugger::GetThreadInfo() if (!attrs.IsEmpty()) { retStr += "\t"; - retStr += attrs; + retStr += attrs; } break; @@ -10924,9 +10915,9 @@ String WinDebugger::GetThreadInfo() } void WinDebugger::SetActiveThread(int threadId) -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); - + if ((mActiveThread != NULL) && (mActiveThread->mThreadId == threadId)) return; @@ -10945,7 +10936,7 @@ void WinDebugger::SetActiveThread(int threadId) *prevFrameArray = mCallStack; mCallStack.Clear(); } - + DoClearCallStack(false); Array* newFrameArray = NULL; @@ -11030,7 +11021,7 @@ void WinDebugger::DoClearCallStack(bool clearSavedStacks) } void WinDebugger::ClearCallStack() -{ +{ DoClearCallStack(true); } @@ -11069,7 +11060,7 @@ void WinDebugger::UpdateCallStack(bool slowEarlyOut) bool isPartial = false; - // Incrementally fill callstack structure to avoid stepping slowdown during deep nesting + // Incrementally fill callstack structure to avoid stepping slowdown during deep nesting for (int fillIdx = 0; fillIdx < (slowEarlyOut ? 10000 : 100000); fillIdx++) { WdStackFrame* wdStackFrame = new WdStackFrame(); @@ -11137,26 +11128,26 @@ int WinDebugger::GetCallStackCount() } int WinDebugger::GetRequestedStackFrameIdx() -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); if ((mActiveThread == mExplicitStopThread) && (mRequestedStackFrameIdx >= -1)) { if (mActiveBreakpoint != NULL) - mRequestedStackFrameIdx = GetBreakStackFrameIdx(); + mRequestedStackFrameIdx = GetBreakStackFrameIdx(); if (mRequestedStackFrameIdx == -1) mRequestedStackFrameIdx = 0; return mRequestedStackFrameIdx; - } - - int newCallStackIdx = 0; + } + + int newCallStackIdx = 0; while (true) - { + { if (newCallStackIdx >= (int)mCallStack.size() - 1) UpdateCallStack(); if (newCallStackIdx >= (int)mCallStack.size() - 1) break; - + intptr addr; String file; int hotIdx; @@ -11168,7 +11159,7 @@ int WinDebugger::GetRequestedStackFrameIdx() int stackSize; int8 flags; GetStackFrameInfo(newCallStackIdx, &addr, &file, &hotIdx, &defLineStart, &defLineEnd, &line, &column, &language, &stackSize, &flags); - if (!file.empty()) + if (!file.empty()) return newCallStackIdx; newCallStackIdx++; } @@ -11177,14 +11168,14 @@ int WinDebugger::GetRequestedStackFrameIdx() } int WinDebugger::GetBreakStackFrameIdx() -{ +{ AutoCrit autoCrit(mDebugManager->mCritSect); if ((mActiveBreakpoint == NULL) || (mRunState != RunState_Breakpoint)) return -1; if ((mBreakStackFrameIdx != -1) || (mActiveThread != mExplicitStopThread)) - return mBreakStackFrameIdx; - + return mBreakStackFrameIdx; + mBreakStackFrameIdx = 0; BF_ASSERT(mActiveBreakpoint != NULL); if (mCallStack.IsEmpty()) @@ -11195,12 +11186,12 @@ int WinDebugger::GetBreakStackFrameIdx() for (int stackIdx = 0; stackIdx < (int)mCallStack.size(); stackIdx++) { - auto callStackEntry = mCallStack[stackIdx]; + auto callStackEntry = mCallStack[stackIdx]; if (callStackEntry->mSubProgram == NULL) break; if ((mActiveBreakpoint->mAddr < callStackEntry->mSubProgram->mBlock.mLowPC) || (mActiveBreakpoint->mAddr >= callStackEntry->mSubProgram->mBlock.mHighPC)) - break; + break; DbgSubprogram* specificSubprogram = callStackEntry->mSubProgram; auto dwLineData = callStackEntry->mSubProgram->FindClosestLine(mActiveBreakpoint->mAddr, &specificSubprogram); @@ -11233,13 +11224,13 @@ void WinDebugger::UpdateRegisterUsage(int stackFrameIdx) auto dwSubprogram = wdStackFrame->mSubProgram; if (dwSubprogram == NULL) return; - + addr_target addr = dwSubprogram->mBlock.mLowPC; - + const uint8* baseOp = nullptr; while (addr < dwSubprogram->mBlock.mHighPC) { - CPUInst inst; + CPUInst inst; if (!mDebugTarget->DecodeInstruction(addr, &inst)) break; @@ -11255,7 +11246,7 @@ void WinDebugger::UpdateCallStackMethod(int stackFrameIdx) { if (mCallStack.empty()) return; - + int startIdx = std::min(stackFrameIdx, (int)mCallStack.size() - 1); while (startIdx >= 0) { @@ -11272,10 +11263,10 @@ void WinDebugger::UpdateCallStackMethod(int stackFrameIdx) if (checkFrameIdx >= mCallStack.size()) break; - WdStackFrame* wdStackFrame = mCallStack[checkFrameIdx]; + WdStackFrame* wdStackFrame = mCallStack[checkFrameIdx]; wdStackFrame->mHasGottenSubProgram = true; - addr_target pcAddress = (addr_target)wdStackFrame->GetSourcePC(); + addr_target pcAddress = (addr_target)wdStackFrame->GetSourcePC(); DbgSubprogram* dwSubprogram = mDebugTarget->FindSubProgram(pcAddress, DbgOnDemandKind_LocalOnly); wdStackFrame->mHasGottenSubProgram = true; wdStackFrame->mSubProgram = dwSubprogram; @@ -11315,7 +11306,7 @@ void WinDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* ou AutoCrit autoCrit(mDebugManager->mCritSect); DbgSubprogram* subProgram = NULL; - DbgLineData* callingLineData = FindLineDataAtAddress((addr_target)addr, &subProgram); + DbgLineData* callingLineData = FindLineDataAtAddress((addr_target)addr, &subProgram); if (inlineCallAddr != 0) { @@ -11347,7 +11338,7 @@ void WinDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* ou *outColumn = callingLineData->mColumn; } return; - } + } } if (subProgram != NULL) @@ -11357,7 +11348,7 @@ void WinDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* ou *outHotIdx = subProgram->mCompileUnit->mDbgModule->mHotIdx; *outFile = subProgram->GetLineSrcFile(*callingLineData)->GetLocalPath(); - *outLine = callingLineData->mLine; + *outLine = callingLineData->mLine; *outColumn = callingLineData->mColumn; FixupLineDataForSubprogram(subProgram); @@ -11381,7 +11372,7 @@ void WinDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* ou } if (dwEndLineData != NULL) - { + { *outDefLineStart = dwStartLineData->mLine; *outDefLineEnd = dwEndLineData->mLine; } @@ -11400,7 +11391,7 @@ void WinDebugger::GetStackAllocInfo(intptr addr, int* outThreadId, int* outStack return; for (auto thread : mThreadList) - { + { NT_TIB64 tib = { 0 }; if (!ReadMemory((intptr)thread->mThreadLocalBase, sizeof(tib), &tib)) continue; @@ -11408,14 +11399,14 @@ void WinDebugger::GetStackAllocInfo(intptr addr, int* outThreadId, int* outStack MEMORY_BASIC_INFORMATION stackInfo = { 0 }; if (VirtualQueryEx(mProcessInfo.hProcess, (void*)(tib.StackBase - 1), &stackInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0) continue; - + if ((addr >= (intptr)stackInfo.AllocationBase) && (addr < (intptr)tib.StackBase)) { *outThreadId = thread->mThreadId; if (outStackIdx == NULL) return; - + if (mActiveThread == thread) { UpdateCallStack(false); @@ -11466,11 +11457,11 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o UpdateCallStackMethod(stackFrameIdx); if (stackFrameIdx >= mCallStack.size()) - { + { return ""; } - int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); + int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); UpdateCallStackMethod(actualStackFrameIdx); WdStackFrame* wdStackFrame = mCallStack[actualStackFrameIdx]; @@ -11484,8 +11475,8 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o if (actualStackFrameIdx < (int)mCallStack.size() - 2) { WdStackFrame* prevStackFrame = mCallStack[actualStackFrameIdx + 1]; - // Inlined methods have no stack frame - *outStackSize = prevStackFrame->mRegisters.GetSP() - wdStackFrame->mRegisters.GetSP(); + // Inlined methods have no stack frame + *outStackSize = prevStackFrame->mRegisters.GetSP() - wdStackFrame->mRegisters.GetSP(); } const auto& _CheckHashSrcFile = [&](String& outStr, DbgModule* dbgModule, DbgSrcFile* srcFile) @@ -11493,7 +11484,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o if (srcFile->mHashKind != DbgHashKind_None) { outStr += "#"; - srcFile->GetHash(outStr); + srcFile->GetHash(outStr); } }; @@ -11526,17 +11517,17 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o }; if (wdStackFrame->mInInlineMethod) - { + { WdStackFrame* nextStackFrame = mCallStack[actualStackFrameIdx - 1]; auto subProgram = nextStackFrame->mSubProgram; _SetFlags(subProgram); - FixupLineDataForSubprogram(subProgram->mInlineeInfo->mRootInliner); + FixupLineDataForSubprogram(subProgram->mInlineeInfo->mRootInliner); DbgSubprogram* parentSubprogram = subProgram->mInlineeInfo->mInlineParent; // Require it be in the inline parent auto foundLine = parentSubprogram->FindClosestLine(subProgram->mBlock.mLowPC, &parentSubprogram); if (foundLine != NULL) - { + { auto srcFile = parentSubprogram->GetLineSrcFile(*foundLine); *outFile = srcFile->GetLocalPath(); _CheckHashSrcFile(*outFile, subProgram->mCompileUnit->mDbgModule, srcFile); @@ -11544,7 +11535,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o } *outLanguage = subProgram->GetLanguage(); - *outHotIdx = subProgram->mCompileUnit->mDbgModule->mHotIdx; + *outHotIdx = subProgram->mCompileUnit->mDbgModule->mHotIdx; *outColumn = -1; DbgSubprogram* callingSubProgram = NULL; @@ -11565,11 +11556,11 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o DbgModule* dbgModule = wdStackFrame->mSubProgram->mCompileUnit->mDbgModule; DbgModule* linkedModule = dbgModule->GetLinkedModule(); if (!linkedModule->mDisplayName.empty()) - name = linkedModule->mDisplayName + "!" + name; + name = linkedModule->mDisplayName + "!" + name; _FixFilePath(dbgModule); return name; } - + DbgSubprogram* dwSubprogram = wdStackFrame->mSubProgram; if (dwSubprogram != NULL) { @@ -11589,19 +11580,19 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o { dwSubprogram->ToString(demangledName, true); } - + DbgSrcFile* dwSrcFile = NULL; DbgLineData* dwLineData = NULL; FixupLineDataForSubprogram(dwSubprogram); - addr_target findAddress = wdStackFrame->GetSourcePC(); + addr_target findAddress = wdStackFrame->GetSourcePC(); DbgSubprogram* specificSubprogram = dwSubprogram; dwLineData = dwSubprogram->FindClosestLine(findAddress, &specificSubprogram); if ((dwLineData == NULL) && (dwSubprogram->mInlineeInfo != NULL) && (findAddress >= dwSubprogram->mBlock.mHighPC)) dwLineData = &dwSubprogram->mInlineeInfo->mLastLineData; - if (dwLineData != NULL) + if (dwLineData != NULL) dwSrcFile = dwSubprogram->GetLineSrcFile(*dwLineData); DbgLineData* dwStartLineData = NULL; @@ -11622,7 +11613,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o dwEndLineData = &dwSubprogram->mInlineeInfo->mLastLineData; } } - + DbgModule* dbgModule = dwSubprogram->mCompileUnit->mDbgModule; DbgModule* linkedModule = dbgModule->GetLinkedModule(); if (!linkedModule->mDisplayName.empty()) @@ -11635,8 +11626,8 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o if ((dwLineData != NULL) && (dwSrcFile != NULL)) { - *outFile = dwSrcFile->GetLocalPath(); - _CheckHashSrcFile(*outFile, dbgModule, dwSrcFile); + *outFile = dwSrcFile->GetLocalPath(); + _CheckHashSrcFile(*outFile, dbgModule, dwSrcFile); *outHotIdx = dbgModule->mHotIdx; *outLine = dwLineData->mLine; @@ -11644,7 +11635,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o *outLanguage = (int)dwSubprogram->mCompileUnit->mLanguage; if (dwEndLineData != NULL) - { + { *outDefLineStart = dwStartLineData->mLine; *outDefLineEnd = dwEndLineData->mLine; } @@ -11664,11 +11655,11 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o addr_target offset; DbgModule* dbgModule = NULL; if (mDebugTarget->FindSymbolAt(pcAddress, &symbolName, &offset, &dbgModule)) - { + { if (dbgModule->HasPendingDebugInfo()) { *outFlags |= FrameFlags_HasPendingDebugInfo; - + if (mPendingDebugInfoLoad.ContainsKey(dbgModule)) { String outName = EncodeDataPtr(pcAddress, true); @@ -11677,16 +11668,16 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o return outName; } } - + DbgModule* linkedModule = dbgModule->GetLinkedModule(); String demangledName = BfDemangler::Demangle(symbolName, DbgLanguage_Unknown); if (!linkedModule->mDisplayName.empty()) demangledName = linkedModule->mDisplayName + "!" + demangledName; _FixFilePath(dbgModule); - return demangledName + StrFormat("+0x%X", offset); - } + return demangledName + StrFormat("+0x%X", offset); + } } - + DbgModule* dbgModule = mDebugTarget->FindDbgModuleForAddress(pcAddress); DbgModule* linkedModule = NULL; if (dbgModule != NULL) @@ -11695,7 +11686,7 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o if (dbgModule->HasPendingDebugInfo()) *outFlags |= FrameFlags_HasPendingDebugInfo; } - String outName = EncodeDataPtr(pcAddress, true); + String outName = EncodeDataPtr(pcAddress, true); if ((linkedModule != NULL) && (!linkedModule->mDisplayName.empty())) outName = linkedModule->mDisplayName + "!" + outName; _FixFilePath(dbgModule); @@ -11729,7 +11720,7 @@ String WinDebugger::Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) if (!FixCallStackIdx(stackFrameIdx)) return ""; - + int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); UpdateCallStackMethod(actualStackFrameIdx); WdStackFrame* wdStackFrame = mCallStack[actualStackFrameIdx]; @@ -11742,32 +11733,32 @@ String WinDebugger::Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) WdStackFrame* nextStackFrame = mCallStack[actualStackFrameIdx - 1]; auto subProgram = nextStackFrame->mSubProgram; dbgModule = subProgram->mCompileUnit->mDbgModule; - + FixupLineDataForSubprogram(subProgram->mInlineeInfo->mRootInliner); DbgSubprogram* parentSubprogram = subProgram->mInlineeInfo->mInlineParent; // Require it be in the inline parent auto foundLine = parentSubprogram->FindClosestLine(subProgram->mBlock.mLowPC, &parentSubprogram); - if (foundLine != NULL) + if (foundLine != NULL) dbgSrcFile = parentSubprogram->GetLineSrcFile(*foundLine); DbgSubprogram* callingSubProgram = NULL; DbgLineData* callingLineData = FindLineDataAtAddress(nextStackFrame->mSubProgram->mBlock.mLowPC - 1, &callingSubProgram); - if ((callingLineData != NULL) && (callingSubProgram == wdStackFrame->mSubProgram)) - dbgSrcFile = callingSubProgram->GetLineSrcFile(*callingLineData); + if ((callingLineData != NULL) && (callingSubProgram == wdStackFrame->mSubProgram)) + dbgSrcFile = callingSubProgram->GetLineSrcFile(*callingLineData); } else { DbgSubprogram* dwSubprogram = wdStackFrame->mSubProgram; if (dwSubprogram != NULL) - { + { FixupLineDataForSubprogram(dwSubprogram); addr_target findAddress = wdStackFrame->GetSourcePC(); - DbgSubprogram* dbgSubprogram = NULL; + DbgSubprogram* dbgSubprogram = NULL; DbgLineData* dwLineData = dwSubprogram->FindClosestLine(findAddress, &dbgSubprogram, &dbgSrcFile); dbgModule = dwSubprogram->mCompileUnit->mDbgModule; } } - + if (dbgSrcFile != NULL) { // Note: we must use mFilePath here, make sure we don't use GetLocalPath() @@ -11782,7 +11773,7 @@ int WinDebugger::GetJmpState(int stackFrameIdx) if (!FixCallStackIdx(stackFrameIdx)) return -1; - + int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); UpdateCallStackMethod(actualStackFrameIdx); WdStackFrame* wdStackFrame = mCallStack[actualStackFrameIdx]; @@ -11791,7 +11782,7 @@ int WinDebugger::GetJmpState(int stackFrameIdx) CPUInst inst; if (!mDebugTarget->DecodeInstruction(pcAddress, &inst)) - return -1; + return -1; return inst.GetJmpState(wdStackFrame->mRegisters.mIntRegs.efl); } @@ -11826,7 +11817,7 @@ String WinDebugger::GetStackMethodOwner(int stackFrameIdx, int& language) if (!FixCallStackIdx(stackFrameIdx)) return ""; - + int actualStackFrameIdx = BF_MAX(0, stackFrameIdx); if (actualStackFrameIdx >= (int)mCallStack.size()) actualStackFrameIdx = 0; @@ -11854,7 +11845,7 @@ String WinDebugger::FindCodeAddresses(const StringImpl& fileName, int line, int return result; bool foundInSequence = false; - WdBreakpoint* prevBreakpoint = NULL; + WdBreakpoint* prevBreakpoint = NULL; int bestLineOffset = 0x7FFFFFFF; @@ -11878,7 +11869,7 @@ String WinDebugger::FindCodeAddresses(const StringImpl& fileName, int line, int if (!foundInSequence) { auto addr = dbgSubprogram->GetLineAddr(lineData); - result += EncodeDataPtr(addr, false) + "\t" + dbgSubprogram->ToString() + "\n"; + result += EncodeDataPtr(addr, false) + "\t" + dbgSubprogram->ToString() + "\n"; } } @@ -11895,15 +11886,15 @@ String WinDebugger::GetAddressSourceLocation(intptr address) { DbgSubprogram* subProgram = NULL; DbgLineData* lineData = FindLineDataAtAddress(address, &subProgram); - if (lineData != NULL) + if (lineData != NULL) return StrFormat("%s:%d:%d", subProgram->GetLineSrcFile(*lineData)->GetLocalPath().c_str(), lineData->mLine + 1, lineData->mColumn + 1); - + String outSymbol; addr_target offset = 0; DbgModule* dbgModule; if (mDebugTarget->FindSymbolAt(address, &outSymbol, &offset, &dbgModule)) { - if (offset < 0x10000) + if (offset < 0x10000) { outSymbol = BfDemangler::Demangle(outSymbol, DbgLanguage_Unknown); if (offset > 0) @@ -11919,7 +11910,7 @@ String WinDebugger::GetAddressSymbolName(intptr address, bool demangle) { auto subProgram = mDebugTarget->FindSubProgram(address); if (subProgram != NULL) - return subProgram->ToString(); + return subProgram->ToString(); String outSymbol; addr_target offset = 0; @@ -11929,7 +11920,7 @@ String WinDebugger::GetAddressSymbolName(intptr address, bool demangle) if (offset < 0x10000) { if (demangle) - outSymbol = BfDemangler::Demangle(outSymbol, DbgLanguage_Unknown); + outSymbol = BfDemangler::Demangle(outSymbol, DbgLanguage_Unknown); if (offset > 0) outSymbol += StrFormat("+%x", offset); return outSymbol; @@ -11944,12 +11935,12 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) addr_target address = (addr_target)inAddress; const int addrBorder = 1024; - + for (int offset = 0; offset < 8; offset++) { String result; bool addOffset = true; - bool hadAddr = false; + bool hadAddr = false; DbgModule* dbgModule = mDebugTarget->FindDbgModuleForAddress(address); DbgModuleMemoryCache* memCache = NULL; @@ -11972,13 +11963,13 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) addrStart = BF_MAX((addr_target)dbgModule->mImageBase, address - addrBorder - offset); } else - { + { memCache = new DbgModuleMemoryCache(addrStart & (4096 - 1), 4096 * 2); } if (memCache->mAddr == 0) return ""; - + //addr_target imageBase = dbgModule->mImageBase; //int imageSize = dbgModule->mImageSize; @@ -11986,16 +11977,16 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) addr_target addrEnd = addrStart + addrBorder * 2 + 16; while (dataAddr < addrEnd) - { + { if (dataAddr == address) hadAddr = true; if (dataAddr > address) - { + { if (!hadAddr) { if (offset == 7) { - dataAddr = address; + dataAddr = address; } break; } @@ -12008,7 +11999,7 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) if (mDebugTarget->FindSymbolAt(dataAddr, &outSymbol, &symOffset, &symDWARF)) { if (symOffset == 0) - { + { outSymbol = BfDemangler::Demangle(outSymbol, DbgLanguage_Unknown); if ((symDWARF != NULL) && (!symDWARF->mDisplayName.empty())) outSymbol = symDWARF->GetLinkedModule()->mDisplayName + "!" + outSymbol; @@ -12020,7 +12011,7 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) if (!mCPU->Decode(dataAddr, memCache, &inst)) { if ((offset == 7) && (!hadAddr)) - { + { uint8 instData[1]; memCache->Read(dataAddr, instData, 1); int instLen = 1; @@ -12065,11 +12056,11 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) { addr_target targetAddr = inst.GetTarget(); if (targetAddr != 0) - { + { if (mDebugTarget->FindSymbolAt(targetAddr, &outSymbol, &symOffset)) { if (symOffset < 0x10000) - { + { outSymbol = BfDemangler::Demangle(outSymbol, DbgLanguage_Unknown); result += " ; " + outSymbol; @@ -12078,7 +12069,6 @@ String WinDebugger::DisassembleAtRaw(intptr inAddress) //result += ">"; } } - } } @@ -12104,35 +12094,34 @@ String WinDebugger::DisassembleAt(intptr inAddress) addr_target address = (addr_target)inAddress; if (mDebugTarget == NULL) - return ""; + return ""; String result; - auto dwSubProgram = mDebugTarget->FindSubProgram(address); - if (dwSubProgram == NULL) - return DisassembleAtRaw(address); + auto dwSubProgram = mDebugTarget->FindSubProgram(address); + if (dwSubProgram == NULL) + return DisassembleAtRaw(address); dwSubProgram = dwSubProgram->GetRootInlineParent(); DbgModule* dwarf = dwSubProgram->mCompileUnit->mDbgModule; - int frameBaseRegister = mDebugTarget->GetFrameBaseRegister(dwSubProgram); + int frameBaseRegister = mDebugTarget->GetFrameBaseRegister(dwSubProgram); addr_target addrStart = dwSubProgram->mBlock.mLowPC; addr_target addrEnd = dwSubProgram->mBlock.mHighPC; - auto dwCompileUnit = dwSubProgram->mCompileUnit; - { + { FixupLineData(dwCompileUnit); - } + } DbgSrcFile* dwSrcFile = NULL; - + FixupLineDataForSubprogram(dwSubProgram); - + DbgLineData* dwLineData = NULL; if (dwSubProgram->mLineInfo != NULL) - dwLineData = &dwSubProgram->mLineInfo->mLines[0]; - int nextLineDataIdx = 1; - + dwLineData = &dwSubProgram->mLineInfo->mLines[0]; + int nextLineDataIdx = 1; + if (dwSubProgram->mIsOptimized) result += "O\n"; @@ -12140,7 +12129,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) int firstLine = 0; int curLine = 0; if (dwLineData != NULL) - { + { srcFile = dwSubProgram->GetLineSrcFile(*dwLineData); result += "S " + srcFile->GetLocalPath() + "\n"; if (srcFile->mHashKind != DbgHashKind_None) @@ -12156,14 +12145,14 @@ String WinDebugger::DisassembleAt(intptr inAddress) curLine = dwLineData->mLine + 1; firstLine = dwLineData->mLine; } - - Array inlineStack; + + Array inlineStack; Array blockList; blockList.push_back(&dwSubProgram->mBlock); - addr_target dataAddr = addrStart; - int decodeFailureCount = 0; + addr_target dataAddr = addrStart; + int decodeFailureCount = 0; auto& _PopInlineStack = [&]() { @@ -12179,7 +12168,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) }; std::function _UpdateInlineStackHelper = [&](DbgSubprogram* subprogram, int depth) - { + { int stackIdx = depth - 1; if (stackIdx < inlineStack.size()) { @@ -12222,20 +12211,20 @@ String WinDebugger::DisassembleAt(intptr inAddress) }; while (dataAddr < addrEnd) - { + { // Pop off old scopes while (blockList.size() > 0) { auto lastBlock = blockList.back(); if (dataAddr < lastBlock->mHighPC) break; - blockList.pop_back(); + blockList.pop_back(); } // Check entry into new child scopes - auto lastBlock = blockList.back(); + auto lastBlock = blockList.back(); for (auto checkBlock : lastBlock->mSubBlocks) - { + { if ((dataAddr >= checkBlock->mLowPC) && (dataAddr < checkBlock->mHighPC)) { blockList.push_back(checkBlock); @@ -12244,12 +12233,12 @@ String WinDebugger::DisassembleAt(intptr inAddress) } bool allowSourceJump = false; - + if ((dwLineData != NULL) && (dwLineData->mContribSize != 0) && (dataAddr >= dwSubProgram->GetLineAddr(*dwLineData) + dwLineData->mContribSize)) { - DbgSubprogram* inlinedSubprogram = NULL; + DbgSubprogram* inlinedSubprogram = NULL; auto inlinedLine = dwSubProgram->FindClosestLine(dataAddr, &inlinedSubprogram); - + _UpdateInlineStack(dwSubProgram); } @@ -12257,7 +12246,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) while ((dwLineData != NULL) && (dwSubProgram->GetLineAddr(*dwLineData) <= dataAddr)) { _UpdateInlineStack(dwSubProgram->GetLineInlinee(*dwLineData)); - + const int lineLimit = 5; // 15 if (allowSourceJump) @@ -12266,7 +12255,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) auto lineSrcFile = dwSubProgram->GetLineSrcFile(*dwLineData); if (lineSrcFile != srcFile) - { + { srcFile = lineSrcFile; result += "S "; result += srcFile->GetLocalPath(); @@ -12274,7 +12263,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) // Just show the one line from the new file curLine = dwLineData->mLine; } - + if (dwLineData->mLine < curLine - 1) { // Jumping backwards - possibly into inlined method, or possibly in current method. @@ -12297,10 +12286,10 @@ String WinDebugger::DisassembleAt(intptr inAddress) //for ( ; curLine <= dwLineData->mLine; curLine++) result += StrFormat("L %d %d\n", curLine, dwLineData->mLine - curLine + 1); curLine = dwLineData->mLine + 1; - + DbgLineData* nextLineData = NULL; while (nextLineDataIdx < dwSubProgram->mLineInfo->mLines.mSize) - { + { nextLineData = &dwSubProgram->mLineInfo->mLines[nextLineDataIdx]; //TODO: @@ -12348,12 +12337,12 @@ String WinDebugger::DisassembleAt(intptr inAddress) break; _PopInlineStack(); } - + bool hadDecodeFailure = false; - CPUInst inst; + CPUInst inst; if (!mCPU->Decode(dataAddr, dwarf->mOrigImageData, &inst)) - hadDecodeFailure = true; - + hadDecodeFailure = true; + if ((decodeFailureCount == 8) || ((decodeFailureCount > 0) && (!hadDecodeFailure))) { for (int i = decodeFailureCount; i < 4 + sizeof(addr_target); i++) @@ -12389,7 +12378,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) result += StrFormat("%02X ", instData[i]); for (int i = instLen; i < 4 + sizeof(addr_target); i++) - result += " "; + result += " "; result += " "; @@ -12413,9 +12402,9 @@ String WinDebugger::DisassembleAt(intptr inAddress) if ((reg == varRegister) && (offset == varOffset)) { result += " ; "; - result += variable->mName; + result += variable->mName; break; - } + } } } } @@ -12424,9 +12413,9 @@ String WinDebugger::DisassembleAt(intptr inAddress) { addr_target targetAddr = inst.GetTarget(); if (targetAddr != 0) - { + { if ((targetAddr >= addrStart) && (targetAddr < addrEnd)) - { + { result += StrFormat("\nJ %s", EncodeDataPtr(targetAddr, false).c_str()); } else @@ -12436,7 +12425,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) if (mDebugTarget->FindSymbolAt(targetAddr, &outSymbol, &offset)) { if (offset < 0x10000) - { + { outSymbol = BfDemangler::Demangle(outSymbol, dwSubProgram->GetLanguage()); result += " ; " + outSymbol; @@ -12444,7 +12433,6 @@ String WinDebugger::DisassembleAt(intptr inAddress) result += StrFormat("+%x", offset); } } - } } } @@ -12458,7 +12446,7 @@ String WinDebugger::DisassembleAt(intptr inAddress) /*if (curLine > 0) { for (int i = 0; i < 6; i++, curLine++) - result += StrFormat("L %d\n", curLine); + result += StrFormat("L %d\n", curLine); }*/ return result; } @@ -12469,10 +12457,10 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) addr_target address = (addr_target)inAddress; - DbgSubprogram* dwSubprogram = NULL; - + DbgSubprogram* dwSubprogram = NULL; + DbgLineData* startLineData = FindLineDataAtAddress(address, &dwSubprogram, NULL); - + if (dwSubprogram == NULL) return ""; @@ -12480,12 +12468,12 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) PopulateRegisters(®isters); auto inlinerSubprogram = dwSubprogram->GetRootInlineParent(); - FixupLineDataForSubprogram(inlinerSubprogram); + FixupLineDataForSubprogram(inlinerSubprogram); if (inlinerSubprogram->mLineInfo->mLines.mSize == 0) return ""; auto lineData = &inlinerSubprogram->mLineInfo->mLines[0]; - + addr_target addr = dwSubprogram->mBlock.mLowPC; addr_target endAddr = dwSubprogram->mBlock.mHighPC; @@ -12509,7 +12497,7 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) else nextLineAddr = inlinerSubprogram->mBlock.mHighPC; - // This stuff doesn't make sense... + // This stuff doesn't make sense... DbgSubprogram* nextSubProgram; if (nextLineData != NULL) { @@ -12545,7 +12533,7 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) if (addr < (addr_target)inAddress) callAddresses += "-"; - callAddresses += EncodeDataPtr(addr, false); + callAddresses += EncodeDataPtr(addr, false); addr_target targetAddr = inst.GetTarget(this, ®isters); if (targetAddr != 0) @@ -12586,7 +12574,7 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) callAddresses += "\tFunc@" + EncodeDataPtr(targetAddr, false); else callAddresses += "\t" + outSymbol; - + String attrs; bool isFiltered = false; if (subprogram != NULL) @@ -12598,12 +12586,12 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) } StepFilter* stepFilterPtr = NULL; - if (mDebugManager->mStepFilters.TryGetValue(outSymbol, &stepFilterPtr)) - isFiltered = stepFilterPtr->IsFiltered(isFiltered); - + if (mDebugManager->mStepFilters.TryGetValue(outSymbol, &stepFilterPtr)) + isFiltered = stepFilterPtr->IsFiltered(isFiltered); + if (isFiltered) attrs += "f"; // 'f' for filter - + if (!attrs.IsEmpty()) callAddresses += "\t" + attrs; } @@ -12629,15 +12617,15 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) if (checkLineAddr == checkSubprogram->mBlock.mLowPC) { addr_target inlineStartAddr = checkSubprogram->mBlock.mLowPC; - + // Find the calling line - DbgSubprogram* callingSubprogram = dwSubprogram; - auto checkLineData = dwSubprogram->FindClosestLine(inlineStartAddr, &callingSubprogram); + DbgSubprogram* callingSubprogram = dwSubprogram; + auto checkLineData = dwSubprogram->FindClosestLine(inlineStartAddr, &callingSubprogram); if ((checkLineData != NULL) && (checkLineData->mCtxIdx == startLineData->mCtxIdx) && (checkLineData->mLine == startLineData->mLine)) { if (inlineStartAddr <= (addr_target)inAddress) callAddresses += "-"; - callAddresses += EncodeDataPtr(inlineStartAddr, false); + callAddresses += EncodeDataPtr(inlineStartAddr, false); String outSymbol; CreateFilterName(outSymbol, checkSubprogram); callAddresses += "\t" + outSymbol; @@ -12646,13 +12634,13 @@ String WinDebugger::FindLineCallAddresses(intptr inAddress) StepFilter* stepFilterPtr; if (mDebugManager->mStepFilters.TryGetValue(outSymbol, &stepFilterPtr)) isFiltered = stepFilterPtr->IsFiltered(isFiltered); - - if (isFiltered) - callAddresses += "\tf"; // 'f' for filter - + + if (isFiltered) + callAddresses += "\tf"; // 'f' for filter + callAddresses += "\n"; } - + // if (checkSubprogram->mBlock.mHighPC < endAddr) // { // addr = checkSubprogram->mBlock.mHighPC; @@ -12701,7 +12689,7 @@ String WinDebugger::GetCurrentException() } break; case EXCEPTION_DATATYPE_MISALIGNMENT: - exStr = "EXCEPTION_DATATYPE_MISALIGNMENT"; + exStr = "EXCEPTION_DATATYPE_MISALIGNMENT"; case EXCEPTION_SINGLE_STEP: exStr = "EXCEPTION_SINGLE_STEP"; break; @@ -12784,13 +12772,13 @@ String WinDebugger::GetCurrentException() void WinDebugger::SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) { AutoCrit autoCrit(mDebugManager->mCritSect); - + String fixedOrigPath = FixPathAndCase(origPath); String fixedLocalPath = FixPathAndCase(localPath); auto origFile = mDebugTarget->AddSrcFile(origPath); origFile->mLocalPath = FixPath(localPath); - + mDebugTarget->mLocalToOrigSrcMap[fixedLocalPath] = fixedOrigPath; // We invalidate the step filters, because previously-failing 'CheckSourceFileExist' checks may now succeed mDebugManager->mStepFilterVersion++; @@ -12812,7 +12800,7 @@ String WinDebugger::GetModulesInfo() str += "\t"; if (module->mLoadState == DbgModuleLoadState_Loaded) { - str += module->mFilePath; + str += module->mFilePath; } else if (module->mLoadState == DbgModuleLoadState_NotLoaded) { @@ -12831,23 +12819,23 @@ String WinDebugger::GetModulesInfo() str += module->mMappedImageFile->mFileName; str += ")"; } - + str += "\t"; str += coff->mPDBPath; str += "\t"; - str += module->mVersion; - str += StrFormat("\t%@-%@\t%dk\t", module->mImageBase, module->mImageBase + module->mImageSize, module->mImageSize / 1024); + str += module->mVersion; + str += StrFormat("\t%@-%@\t%dk\t", module->mImageBase, module->mImageBase + module->mImageSize, module->mImageSize / 1024); time_t timestamp = coff->mTimeStamp; if (timestamp == 0) - timestamp = GetFileTimeWrite(coff->mFilePath); + timestamp = GetFileTimeWrite(coff->mFilePath); if (timestamp != 0) { char timeString[256]; auto time_info = localtime(×tamp); strftime(timeString, sizeof(timeString), "%D %T", time_info); str += timeString; - } + } str += "\n"; } @@ -12910,14 +12898,14 @@ int WinDebugger::LoadDebugInfoForModule(DbgModule* dbgModule) return 2; } dbgPendingDebugInfoLoad->mAllowRemote = true; - + return 0; } int WinDebugger::LoadDebugInfoForModule(const StringImpl& moduleName) { AutoCrit autoCrit(mDebugManager->mCritSect); - + for (auto dbgModule : mDebugTarget->mDbgModules) { String checkModuleName = GetFileName(dbgModule->mFilePath); @@ -12935,11 +12923,11 @@ int WinDebugger::LoadDebugInfoForModule(const StringImpl& modulePath, const Stri AutoCrit autoCrit(mDebugManager->mCritSect); for (auto dbgModule : mDebugTarget->mDbgModules) - { + { if (modulePath.Equals(dbgModule->mFilePath, StringImpl::CompareKind_OrdinalIgnoreCase)) { auto coff = (COFF*)dbgModule; - + String err; if (!coff->mPDBLoaded) { @@ -12948,8 +12936,8 @@ int WinDebugger::LoadDebugInfoForModule(const StringImpl& modulePath, const Stri { ModuleChanged(dbgModule); } - dbgModule->mFailMsgPtr = NULL; - } + dbgModule->mFailMsgPtr = NULL; + } else { err = StrFormat("Module '%s' already has debug information loaded", GetFileName(modulePath).c_str()); @@ -12971,14 +12959,14 @@ void WinDebugger::FixupLineData(DbgCompileUnit* compileUnit) { if (!compileUnit || !compileUnit->mNeedsLineDataFixup) return; - compileUnit->mNeedsLineDataFixup = false; + compileUnit->mNeedsLineDataFixup = false; } static int CompareLineData(const void* lineDataP1, const void* lineDataP2) { - int cmpResult = (int)(((DbgLineData*)lineDataP1)->mRelAddress - ((DbgLineData*)lineDataP2)->mRelAddress); + int cmpResult = (int)(((DbgLineData*)lineDataP1)->mRelAddress - ((DbgLineData*)lineDataP2)->mRelAddress); if (cmpResult != 0) - return cmpResult; + return cmpResult; // A larger contrib size means it's the 'outer' inlinee cmpResult = -(((DbgLineData*)lineDataP1)->mContribSize - ((DbgLineData*)lineDataP2)->mContribSize); @@ -12989,26 +12977,26 @@ static int CompareLineData(const void* lineDataP1, const void* lineDataP2) } void WinDebugger::FixupLineDataForSubprogram(DbgSubprogram* subProgram) -{ +{ if ((subProgram == NULL) || (!subProgram->mNeedLineDataFixup)) return; - BP_ZONE("FixupLineDataForSubprogram"); + BP_ZONE("FixupLineDataForSubprogram"); subProgram->mNeedLineDataFixup = false; if (subProgram->mInlineeInfo != NULL) FixupLineDataForSubprogram(subProgram->mInlineeInfo->mRootInliner); - + if ((subProgram->mLineInfo == NULL) || (subProgram->mLineInfo->mLines.mSize == 0)) return; - //TODO: I think this was covering up a bug in DWARF line encoding? Figure this out + //TODO: I think this was covering up a bug in DWARF line encoding? Figure this out // if (subProgram->mLineInfo->mLines.mSize >= 2) // { // DbgLineData* line0 = &subProgram->mLineInfo->mLines[0]; // DbgLineData* line1 = &subProgram->mLineInfo->mLines[1]; -// -// +// +// // if ((line0->mRelAddress == line1->mRelAddress) && (!line0->IsStackFrameSetup()) && (line1->IsStackFrameSetup())) // { // CPUInst inst; @@ -13017,7 +13005,7 @@ void WinDebugger::FixupLineDataForSubprogram(DbgSubprogram* subProgram) // } // } - qsort(subProgram->mLineInfo->mLines.mVals, subProgram->mLineInfo->mLines.mSize, sizeof(DbgLineData), CompareLineData); + qsort(subProgram->mLineInfo->mLines.mVals, subProgram->mLineInfo->mLines.mSize, sizeof(DbgLineData), CompareLineData); // If we have multiple lines with the same line/column/context, merge them if (!subProgram->mLineInfo->mLines.IsEmpty()) @@ -13052,8 +13040,8 @@ void WinDebugger::ReserveHotTargetMemory(int size) if (size > 0) { - // In 64-bit mode we have a reserved region on program load that we commit here because the offsets - // must be within 32-bits of the original EXE image, but in 32-bit mode we don't reserve anything + // In 64-bit mode we have a reserved region on program load that we commit here because the offsets + // must be within 32-bits of the original EXE image, but in 32-bit mode we don't reserve anything // until here #ifdef BF_DBG_32 //hotTargetMemory.mSize = std::max(1024 * 1024, size); @@ -13081,12 +13069,12 @@ addr_target WinDebugger::AllocHotTargetMemory(int size, bool canExecute, bool ca if (canExecute && canWrite) prot = PAGE_EXECUTE_READWRITE; else if (canExecute) - prot = PAGE_EXECUTE_READ; + prot = PAGE_EXECUTE_READ; auto hotTargetMemory = (HotTargetMemory*)&mHotTargetMemory.back(); if (hotTargetMemory->mPtr == 0) - { + { Fail("Failed to allocate memory for hot loading"); return 0; } @@ -13105,17 +13093,17 @@ addr_target WinDebugger::AllocHotTargetMemory(int size, bool canExecute, bool ca } void WinDebugger::ReleaseHotTargetMemory(addr_target addr, int size) -{ +{ #ifdef BF_DBG_32 ::VirtualFreeEx(mProcessInfo.hProcess, (void*)(intptr)addr, 0, MEM_RELEASE); #else mDebugTarget->mHotHeap->Release(addr, size); ::VirtualFreeEx(mProcessInfo.hProcess, (void*)(intptr)addr, size, MEM_DECOMMIT); -#endif +#endif } void WinDebugger::CleanupHotHeap() -{ +{ mDebugTarget->mLastHotHeapCleanIdx = mDebugTarget->mHotHeap->mBlockAllocIdx; // Our criteria for determining whether a hot loaded file is still being used: @@ -13141,7 +13129,7 @@ void WinDebugger::CleanupHotHeap() for (int threadIdx = 0; threadIdx < (int)mThreadList.size(); threadIdx++) { WdThreadInfo* threadInfo = mThreadList[threadIdx]; - + BF_CONTEXT lcContext; lcContext.ContextFlags = BF_CONTEXT_CONTROL; BF_GetThreadContext(threadInfo->mHThread, &lcContext); @@ -13164,7 +13152,7 @@ void WinDebugger::CleanupHotHeap() int numAddrsChecking = BF_MIN(1024, (int)((threadInfo->mStartSP - checkStackAddr) / sizeof(addr_target))); ReadMemory(checkStackAddr, numAddrsChecking * sizeof(addr_target), checkAddrArr); checkStackAddr += numAddrsChecking * sizeof(addr_target); - + for (int addrIdx = 0; addrIdx < numAddrsChecking; addrIdx++) { addr_target checkAddr = checkAddrArr[addrIdx]; @@ -13173,17 +13161,17 @@ void WinDebugger::CleanupHotHeap() } } } - + auto mainModule = mDebugTarget->mTargetBinary; for (auto entry : mainModule->mSymbolNameMap) { auto dwSymbol = entry->mValue; addr_target checkAddr = dwSymbol->mAddress; if ((checkAddr >= lowAddr) && (checkAddr < highAddr)) - mDebugTarget->mHotHeap->MarkBlockReferenced(checkAddr); + mDebugTarget->mHotHeap->MarkBlockReferenced(checkAddr); } - mDebugTarget->CleanupHotHeap(); + mDebugTarget->CleanupHotHeap(); BfLogDbg("Hot load memory used: %dk\n", (int)mDebugTarget->mHotHeap->GetUsedSize() / 1024); } @@ -13194,7 +13182,7 @@ int WinDebugger::EnableWriting(intptr address, int size) bool success = ::VirtualProtectEx(mProcessInfo.hProcess, (void*)(intptr)address, size, PAGE_READWRITE, &oldProt); if (!success) { - int err = GetLastError(); + int err = GetLastError(); } return (int)oldProt; } @@ -13229,10 +13217,10 @@ bool WinDebugger::ReadMemory(intptr address, uint64 length, void* dest, bool loc { return false; } - } - + } + if (mMemCacheAddr != 0) - { + { addr_target targetAddr = (addr_target)address; if ((targetAddr >= mMemCacheAddr) && (targetAddr + length <= mMemCacheAddr + WD_MEMCACHE_SIZE) && (mMemCacheAddr > 1)) { @@ -13250,7 +13238,7 @@ bool WinDebugger::ReadMemory(intptr address, uint64 length, void* dest, bool loc } // Failed, turn off caching - mMemCacheAddr = 0; + mMemCacheAddr = 0; } SIZE_T dwReadBytes; @@ -13264,7 +13252,7 @@ bool WinDebugger::ReadMemory(intptr address, uint64 length, void* dest, bool loc bool WinDebugger::WriteMemory(intptr address, void* src, uint64 length) { SIZE_T dwBytesWritten = 0; - int result = ::WriteProcessMemory(mProcessInfo.hProcess, (void*)(intptr)address, src, (SIZE_T)length, &dwBytesWritten); + int result = ::WriteProcessMemory(mProcessInfo.hProcess, (void*)(intptr)address, src, (SIZE_T)length, &dwBytesWritten); return result != 0; } @@ -13310,7 +13298,7 @@ addr_target WinDebugger::GetTLSOffset(int tlsIndex) return 0; NTSTATUS status = NtQueryInformationThread(mActiveThread->mHThread, (THREADINFOCLASS)0, &threadInfo, sizeof(threadInfo), nullptr); if (status < 0) - return 0; + return 0; #ifdef BF_DBG_32 addr_target tibAddr = ReadMemory((intptr)threadInfo.mTebBaseAddress + 0x0); @@ -13346,8 +13334,8 @@ DbgMemoryFlags WinDebugger::GetMemoryFlags(intptr address) flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Read); flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Write); } - if (memBasicInfo.AllocationProtect & PAGE_READONLY) - flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Read); + if (memBasicInfo.AllocationProtect & PAGE_READONLY) + flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Read); if (memBasicInfo.AllocationProtect & PAGE_WRITECOPY) flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Write); if (memBasicInfo.AllocationProtect & PAGE_EXECUTE) @@ -13355,7 +13343,7 @@ DbgMemoryFlags WinDebugger::GetMemoryFlags(intptr address) if (memBasicInfo.AllocationProtect & PAGE_EXECUTE_READ) { flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Execute); - flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Read); + flags = (DbgMemoryFlags)(flags | DbgMemoryFlags_Read); } if (memBasicInfo.AllocationProtect & PAGE_EXECUTE_READWRITE) { @@ -13380,7 +13368,7 @@ Debugger* Beefy::CreateDebugger64(DebugManager* debugManager, DbgMiniDump* miniD if (miniDump != NULL) { auto debugger = new MiniDumpDebugger(debugManager, miniDump); - + return debugger; } return new WinDebugger(debugManager); @@ -13400,5 +13388,4 @@ void WdAllocTest() } #endif - -#endif //!defined BF32 || !defined BF_DBG_64 +#endif //!defined BF32 || !defined BF_DBG_64 \ No newline at end of file diff --git a/IDEHelper/WinDebugger.h b/IDEHelper/WinDebugger.h index e157ccfa..17fd0b90 100644 --- a/IDEHelper/WinDebugger.h +++ b/IDEHelper/WinDebugger.h @@ -43,7 +43,7 @@ class HotHeap; #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE -#define BF_CONTEXT_ALL CONTEXT_ALL +#define BF_CONTEXT_ALL CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Esp #define BF_CONTEXT_BP(ctx) ctx.Ebp #define BF_CONTEXT_IP(ctx) ctx.Eip @@ -62,7 +62,7 @@ class HotHeap; #define BF_CONTEXT_EXCEPTION_REQUEST WOW64_CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE WOW64_CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE WOW64_CONTEXT_SERVICE_ACTIVE -#define BF_CONTEXT_ALL WOW64_CONTEXT_ALL +#define BF_CONTEXT_ALL WOW64_CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Esp #define BF_CONTEXT_BP(ctx) ctx.Ebp #define BF_CONTEXT_IP(ctx) ctx.Eip @@ -84,7 +84,7 @@ class HotHeap; #define BF_CONTEXT_EXCEPTION_REQUEST CONTEXT_EXCEPTION_REQUEST #define BF_CONTEXT_EXCEPTION_ACTIVE CONTEXT_EXCEPTION_ACTIVE #define BF_CONTEXT_SERVICE_ACTIVE CONTEXT_SERVICE_ACTIVE -#define BF_CONTEXT_ALL CONTEXT_ALL +#define BF_CONTEXT_ALL CONTEXT_ALL #define BF_CONTEXT_SP(ctx) ctx.Rsp #define BF_CONTEXT_BP(ctx) ctx.Rbp #define BF_CONTEXT_IP(ctx) ctx.Rip @@ -123,7 +123,7 @@ public: class WdBreakpointCondition { -public: +public: DbgEvaluationContext* mDbgEvaluationContext; String mExpr; ~WdBreakpointCondition(); @@ -135,7 +135,7 @@ public: addr_target mMemoryAddress; int mByteCount; String mReferenceName; - int8 mMemoryWatchSlotBitmap; + int8 mMemoryWatchSlotBitmap; WdMemoryBreakpointInfo() { @@ -147,31 +147,31 @@ public: class WdBreakpoint : public Breakpoint { -public: +public: WdMemoryBreakpointInfo* mMemoryBreakpointInfo; - + addr_target mAddr; DbgSrcFile* mSrcFile; DbgLineDataEx mLineData; WdBreakpointCondition* mCondition; - BreakpointType mBreakpointType; + BreakpointType mBreakpointType; public: WdBreakpoint() - { + { mMemoryBreakpointInfo = NULL; mAddr = 0; mSrcFile = NULL; mLineData = DbgLineDataEx(); mCondition = NULL; - mBreakpointType = BreakpointType_User; + mBreakpointType = BreakpointType_User; } virtual uintptr GetAddr() override { return (uintptr)mAddr; } - + virtual bool IsMemoryBreakpointBound() override { return (mMemoryBreakpointInfo != NULL) && (mMemoryBreakpointInfo->mMemoryWatchSlotBitmap != 0); @@ -188,7 +188,7 @@ public: enum StepType { StepType_None, - StepType_StepInto, + StepType_StepInto, StepType_StepInto_Unfiltered, StepType_StepInto_UnfilteredSingle, StepType_StepOver, @@ -201,7 +201,7 @@ enum StepType class WdStackFrame { -public: +public: CPURegisters mRegisters; bool mIsStart; bool mIsEnd; @@ -214,7 +214,7 @@ public: public: WdStackFrame() - { + { mSubProgram = NULL; mHasGottenSubProgram = false; mIsStart = true; @@ -241,11 +241,11 @@ struct WdThreadInfo public: uint mProcessId; uint mThreadId; - HANDLE mHThread; + HANDLE mHThread; void* mThreadLocalBase; void* mStartAddress; bool mIsBreakRestorePaused; - bool mFrozen; + bool mFrozen; addr_target mStartSP; String mName; addr_target mStoppedAtAddress; @@ -263,7 +263,7 @@ public: mThreadLocalBase = NULL; mStartAddress = NULL; mIsBreakRestorePaused = false; - mFrozen = false; + mFrozen = false; mIsAtBreakpointAddress = 0; mStoppedAtAddress = 0; @@ -274,16 +274,16 @@ public: class DbgPendingExpr { -public: +public: int mThreadId; BfParser* mParser; - DbgType* mExplitType; - DwFormatInfo mFormatInfo; + DbgType* mExplitType; + DwFormatInfo mFormatInfo; DwEvalExpressionFlags mExpressionFlags; int mCursorPos; BfExpression* mExprNode; String mReferenceId; - int mCallStackIdx; + int mCallStackIdx; String mResult; Array mCallResults; int mIdleTicks; @@ -311,13 +311,13 @@ struct WdMemoryBreakpointBind addr_target mAddress; int mOfs; int mByteCount; - + WdMemoryBreakpointBind() { mAddress = 0; mBreakpoint = NULL; mOfs = 0; - mByteCount = 0; + mByteCount = 0; } }; @@ -349,12 +349,12 @@ public: public: HANDLE mFileMapping; - Stats* mStats; + Stats* mStats; WinDbgHeapData() { mFileMapping = 0; - mStats = NULL; + mStats = NULL; } ~WinDbgHeapData() @@ -368,8 +368,8 @@ struct DwFormatInfo; class WinDebugger : public Debugger { -public: - SyncEvent mContinueEvent; +public: + SyncEvent mContinueEvent; Array mHotTargetMemory; Array mHotThreadStates; @@ -383,10 +383,10 @@ public: String mArgs; String mWorkingDir; bool mHotSwapEnabled; - Array mEnvBlock; + Array mEnvBlock; DebugTarget* mEmptyDebugTarget; DebugTarget* mDebugTarget; - BfSystem* mBfSystem; + BfSystem* mBfSystem; CPU* mCPU; PROCESS_INFORMATION mProcessInfo; BfDbgAttachFlags mDbgAttachFlags; @@ -396,25 +396,25 @@ public: HANDLE mDbgThreadHandle; bool mIsDebuggerWaiting; bool mWantsDebugContinue; - bool mNeedsRehupBreakpoints; + bool mNeedsRehupBreakpoints; bool mContinueFromBreakpointFailed; WdThreadInfo* mDebuggerWaitingThread; WdThreadInfo* mAtBreakThread; WdThreadInfo* mActiveThread; WdBreakpoint* mActiveBreakpoint; WdThreadInfo* mSteppingThread; - WdThreadInfo* mExplicitStopThread; // Don't try to show first frame-with-source for this thread (when we hit breakpoint in asm, encounter exception, etc) + WdThreadInfo* mExplicitStopThread; // Don't try to show first frame-with-source for this thread (when we hit breakpoint in asm, encounter exception, etc) DEBUG_EVENT mDebugEvent; bool mGotStartupEvent; - int mPageSize; + int mPageSize; DbgSymSrv mDbgSymSrv; DbgSymRequest* mActiveSymSrvRequest; DWORD mDebuggerThreadId; - + WdMemoryBreakpointBind mMemoryBreakpoints[4]; int mMemoryBreakpointVersion; - Dictionary mPhysBreakpointAddrMap; // To make sure we don't create multiple physical breakpoints at the same addr - Array mBreakpoints; + Dictionary mPhysBreakpointAddrMap; // To make sure we don't create multiple physical breakpoints at the same addr + Array mBreakpoints; Dictionary mBreakpointAddrMap; Array mFreeMemoryBreakIndices; Array mCallStack; @@ -424,20 +424,20 @@ public: int mBreakStackFrameIdx; addr_target mShowPCOverride; Dictionary mThreadMap; - Array mThreadList; + Array mThreadList; StepType mOrigStepType; - StepType mStepType; + StepType mStepType; int mCurNoInfoStepTries; DbgLineDataEx mStepLineData; bool mStepInAssembly; bool mStepIsRecursing; bool mStepSwitchedThreads; - bool mStepStopOnNextInstruction; - bool mDbgBreak; - + bool mStepStopOnNextInstruction; + bool mDbgBreak; + addr_target mStepStartPC; addr_target mStepPC; - addr_target mStepSP; + addr_target mStepSP; addr_target mStoredReturnValueAddr; addr_target mLastValidStepIntoPC; bool mIsStepIntoSpecific; @@ -449,27 +449,27 @@ public: Array mPendingDebugInfoRequests; HashSet mLiteralSet; - EXCEPTION_RECORD mCurException; + EXCEPTION_RECORD mCurException; bool mIsContinuingFromException; Array mTempBreakpoint; - Array mStepBreakpointAddrs; - + Array mStepBreakpointAddrs; + addr_target mSavedBreakpointAddressContinuing; addr_target mSavedAtBreakpointAddress; - BF_CONTEXT mSavedContext; - + BF_CONTEXT mSavedContext; + Dictionary mPendingProfilerMap; Array mNewProfilerList; HashSet mProfilerSet; - + addr_target mMemCacheAddr; - uint8 mMemCacheData[WD_MEMCACHE_SIZE]; + uint8 mMemCacheData[WD_MEMCACHE_SIZE]; public: - void Fail(const StringImpl& error); + void Fail(const StringImpl& error); void TryGetThreadName(WdThreadInfo* threadInfo); void ThreadRestorePause(WdThreadInfo* onlyPauseThread, WdThreadInfo* dontPauseThread); - void ThreadRestoreUnpause(); + void ThreadRestoreUnpause(); void UpdateThreadDebugRegisters(WdThreadInfo* threadInfo); void UpdateThreadDebugRegisters(); void ValidateBreakpoints(); @@ -477,13 +477,13 @@ public: void SetBreakpoint(addr_target address, bool fromRehup = false); void SetTempBreakpoint(addr_target address); void PhysRemoveBreakpoint(addr_target address); - void RemoveBreakpoint(addr_target address); + void RemoveBreakpoint(addr_target address); void SingleStepX86(); bool IsInRunState(); - bool ContinueFromBreakpoint(); + bool ContinueFromBreakpoint(); bool HasLineInfoAt(addr_target address); DbgLineData* FindLineDataAtAddress(addr_target address, DbgSubprogram** outSubProgram = NULL, DbgSrcFile** outSrcFile = NULL, int* outLineIdx = NULL, DbgOnDemandKind onDemandKind = DbgOnDemandKind_AllowRemote); - DbgLineData* FindLineDataInSubprogram(addr_target address, DbgSubprogram* dwSubprogram); + DbgLineData* FindLineDataInSubprogram(addr_target address, DbgSubprogram* dwSubprogram); bool IsStepFiltered(DbgSubprogram* dbgSubprogram, DbgLineData* dbgLineData); void RemoveTempBreakpoints(); void RehupBreakpoints(bool doFlush); @@ -496,7 +496,7 @@ public: virtual bool PopulateRegisters(CPURegisters* registers); bool RollBackStackFrame(CPURegisters* registers, bool isStackStart); bool SetHotJump(DbgSubprogram* oldSubprogram, addr_target newTarget, int newTargetSize); - DbgSubprogram* TryFollowHotJump(DbgSubprogram* subprogram, addr_target addr); + DbgSubprogram* TryFollowHotJump(DbgSubprogram* subprogram, addr_target addr); bool ParseFormatInfo(DbgModule* dbgModule, const StringImpl& formatInfoStr, DwFormatInfo* formatInfo, BfPassInstance* bfPassInstance, int* assignExprOffset, String* assignExpr = NULL, String* errorString = NULL, DbgTypedValue contextTypedValue = DbgTypedValue()); String MaybeQuoteFormatInfoParam(const StringImpl& str); @@ -508,12 +508,12 @@ public: String ReadString(DbgTypeCode charType, intptr addr, bool isLocalAddr, intptr maxLength, DwFormatInfo& formatInfo, bool wantStringView); String DbgTypedValueToString(const DbgTypedValue& typedValue, const StringImpl& expr, DwFormatInfo& formatFlags, DbgExprEvaluator* optEvaluator, bool fullPrecision = false); bool ShouldShowStaticMember(DbgType* dbgType, DbgVariable* member); - String GetMemberList(DbgType* dbgType, const StringImpl& expr, bool isPtr, bool isStatic, bool forceCast = false, bool isSplat = false, bool isReadOnly = false); + String GetMemberList(DbgType* dbgType, const StringImpl& expr, bool isPtr, bool isStatic, bool forceCast = false, bool isSplat = false, bool isReadOnly = false); DebugVisualizerEntry* FindVisualizerForType(DbgType* dbgType, Array* wildcardCaptures); - void ReserveHotTargetMemory(int size); + void ReserveHotTargetMemory(int size); addr_target AllocHotTargetMemory(int size, bool canExecute, bool canWrite, int* outAllocSize); void ReleaseHotTargetMemory(addr_target addr, int size); - void CleanupHotHeap(); + void CleanupHotHeap(); int EnableWriting(intptr address, int size); int SetProtection(intptr address, int size, int prot); void EnableMemCache(); @@ -522,14 +522,14 @@ public: bool WriteInstructions(intptr address, void* src, uint64 length); template bool WriteMemory(intptr addr, T val); virtual DbgMemoryFlags GetMemoryFlags(intptr address) override; - - void SetRunState(RunState runState); + + void SetRunState(RunState runState); bool IsPaused(); void ClearStep(); - bool SetupStep(StepType stepType); + bool SetupStep(StepType stepType); void CheckNonDebuggerBreak(); bool HasSteppedIntoCall(); - void StepLineTryPause(addr_target address, bool requireExactMatch); + void StepLineTryPause(addr_target address, bool requireExactMatch); void PushValue(CPURegisters* registers, int64 val); void PushValue(CPURegisters* registers, const DbgTypedValue& typedValue); void SetThisRegister(CPURegisters* registers, addr_target val); @@ -538,7 +538,7 @@ public: DbgTypedValue ReadReturnValue(CPURegisters* registers, DbgType* type); bool SetRegisters(CPURegisters* registers); void SaveAllRegisters(); - void RestoreAllRegisters(); + void RestoreAllRegisters(); String GetArrayItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData); String GetLinkedListItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, addr_target endNodePtr, DbgType* valueType, DbgTypedValue& curNode, int& count, String* outContinuationData); String GetDictionaryItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizerEntry* debugVis, DbgTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData); @@ -548,13 +548,13 @@ public: bool DoUpdate(); void DebugThreadProc(); bool DoOpenFile(const StringImpl& fileName, const StringImpl& args, const StringImpl& workingDir, const Array& envBlock); - + DbgTypedValue GetRegister(const StringImpl& regName, DbgLanguage language, CPURegisters* registers, Array* regForms = NULL); void FixupLineData(DbgCompileUnit* compileUnit); void FixupLineDataForSubprogram(DbgSubprogram* subProgram); DbgModule* GetCallStackDbgModule(int callStackIdx); - DbgSubprogram* GetCallStackSubprogram(int callStackIdx); - DbgCompileUnit* GetCallStackCompileUnit(int callStackIdx); + DbgSubprogram* GetCallStackSubprogram(int callStackIdx); + DbgCompileUnit* GetCallStackCompileUnit(int callStackIdx); String Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags); String EvaluateContinue() override; void EvaluateContinueKeep() override; @@ -562,15 +562,15 @@ public: String GetAutocompleteOutput(DwAutoComplete& autoComplete); bool CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubprogram* dbgSubprogram, addr_target pcAddress); void CleanupDebugEval(bool restoreRegisters = true); - bool FixCallStackIdx(int& callStackIdx); + bool FixCallStackIdx(int& callStackIdx); void DoClearCallStack(bool clearSavedStacks); - - int LoadDebugInfoForModule(DbgModule* dbgModule); + + int LoadDebugInfoForModule(DbgModule* dbgModule); public: WinDebugger(DebugManager* debugManager); virtual ~WinDebugger(); - + virtual void OutputMessage(const StringImpl& msg) override; virtual void OutputRawMessage(const StringImpl& msg) override; virtual int GetAddrSize() override; @@ -578,7 +578,7 @@ public: virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array& envBlock, bool hotSwapEnabled) override; virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override; virtual void Run() override; - virtual void HotLoad(const Array& objectFiles, int hotIdx) override; + virtual void HotLoad(const Array& objectFiles, int hotIdx) override; virtual void InitiateHotResolve(DbgHotResolveFlags flags) override; virtual intptr GetDbgAllocHeapSize() override; virtual String GetDbgAllocInfo() override; @@ -591,13 +591,13 @@ public: virtual Breakpoint* CreateAddressBreakpoint(intptr address) override; virtual void CheckBreakpoint(Breakpoint* breakpoint) override; virtual void HotBindBreakpoint(Breakpoint* breakpoint, int lineNum, int hotIdx) override; - virtual void DeleteBreakpoint(Breakpoint* breakpoint) override; + virtual void DeleteBreakpoint(Breakpoint* breakpoint) override; virtual void DetachBreakpoint(Breakpoint* breakpoint) override; virtual void MoveBreakpoint(Breakpoint* breakpoint, int lineNum, int wantColumn, bool rebindNow) override; virtual void MoveMemoryBreakpoint(Breakpoint* breakpoint, intptr addr, int byteCount) override; virtual void DisableBreakpoint(Breakpoint* breakpoint) override; virtual void SetBreakpointCondition(Breakpoint* breakpoint, const StringImpl& condition) override; - virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) override; + virtual void SetBreakpointLogging(Breakpoint* wdBreakpoint, const StringImpl& logging, bool breakAfterLogging) override; virtual Breakpoint* FindBreakpointAt(intptr address) override; virtual Breakpoint* GetActiveBreakpoint() override; virtual void BreakAll() override; @@ -611,7 +611,7 @@ public: virtual String EvaluateToAddress(const StringImpl& expr, int callStackIdx, int cursorPos) override; virtual String EvaluateAtAddress(const StringImpl& expr, intptr atAddr, int cursorPos) override; virtual bool AssignToReg(int callStackIdx, DbgTypedValue reg, DbgTypedValue value, String& outError); - virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) override; + virtual String GetCollectionContinuation(const StringImpl& continuationData, int callStackIdx, int count) override; virtual String GetAutoExpressions(int callStackIdx, uint64 memoryRangeStart, uint64 memoryRangeLen) override; virtual String GetAutoLocals(int callStackIdx, bool showRegs) override; virtual String CompactChildExpression(const StringImpl& expr, const StringImpl& parentExpr, int callStackIdx) override; @@ -646,17 +646,17 @@ public: virtual String DisassembleAtRaw(intptr address) override; virtual String DisassembleAt(intptr address) override; virtual String FindLineCallAddresses(intptr address) override; - virtual String GetCurrentException() override; + virtual String GetCurrentException() override; virtual void SetAliasPath(const StringImpl& origPath, const StringImpl& localPath) override; virtual String GetModulesInfo() override; - virtual void CancelSymSrv() override; + virtual void CancelSymSrv() override; virtual bool HasPendingDebugLoads() override; virtual int LoadImageForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override; virtual int LoadDebugInfoForModule(const StringImpl& moduleName, const StringImpl& debugFileName) override; virtual int LoadDebugInfoForModule(const StringImpl& moduleName) override; virtual void StopDebugging() override; virtual void Terminate() override; - virtual void Detach() override; + virtual void Detach() override; virtual Profiler* StartProfiling() override; virtual Profiler* PopProfiler() override; void AddProfiler(DbgProfiler* profiler); @@ -676,13 +676,13 @@ template bool WinDebugger::WriteMemory(intptr addr, T val) } template T WinDebugger::ReadMemory(intptr addr, bool local, bool* failed) -{ +{ bool success = true; - T val; + T val; memset(&val, 0, sizeof(T)); if (local) { - if (addr != 0) + if (addr != 0) { memcpy(&val, (void*)(intptr)addr, sizeof(T)); /*__try @@ -698,7 +698,7 @@ template T WinDebugger::ReadMemory(intptr addr, bool local, bool* fa success = false; } else - { + { //SIZE_T dwReadBytes; memset(&val, 0, sizeof(T)); //success = ReadProcessMemory(mProcessInfo.hProcess, (void*)(intptr)addr, &val, (SIZE_T)sizeof(T), &dwReadBytes) != 0; @@ -713,4 +713,3 @@ template T WinDebugger::ReadMemory(intptr addr, bool local, bool* fa addr_target DecodeTargetDataPtr(const char*& strRef); NS_BF_DBG_END - diff --git a/IDEHelper/X64.cpp b/IDEHelper/X64.cpp index feebc3d2..4cced4ea 100644 --- a/IDEHelper/X64.cpp +++ b/IDEHelper/X64.cpp @@ -54,7 +54,7 @@ const char* X64CPURegisters::sCPURegisterNames[] = "NONE", // integer general registers (DO NOT REORDER THESE; must exactly match DbgModule x86 register mappings) - "RAX", + "RAX", "RDX", "RCX", "RBX", @@ -69,7 +69,7 @@ const char* X64CPURegisters::sCPURegisterNames[] = "R12", "R13", "R14", - "R15", + "R15", "RIP", "EFL", "GS", @@ -88,7 +88,7 @@ const char* X64CPURegisters::sCPURegisterNames[] = "R13D", "R14D", "R15D", - + "AX", "DX", "CX", @@ -141,7 +141,7 @@ const char* X64CPURegisters::sCPURegisterNames[] = "MM4", "MM5", "MM6", - "MM7", + "MM7", "XMM0_f64", "XMM1_f64", @@ -354,7 +354,7 @@ bool X64Instr::IsRep(bool& isPrefixOnly) bool X64Instr::IsReturn() { - const MCInstrDesc &instDesc = mX64->mInstrInfo->get(mMCInst.getOpcode()); + const MCInstrDesc &instDesc = mX64->mInstrInfo->get(mMCInst.getOpcode()); return (instDesc.getFlags() & (1 << MCID::Return)) != 0; } @@ -402,7 +402,7 @@ static int ConvertRegNum(const MCOperand& operand) return X64Reg_RBP; case llvm::X86::RSP: return X64Reg_RSP; - + case llvm::X86::R8: case llvm::X86::R8D: case llvm::X86::R8W: @@ -507,7 +507,7 @@ static int ConvertRegNum(const MCOperand& operand) case llvm::X86::XMM14: return X64Reg_M128_XMM14; case llvm::X86::XMM15: - return X64Reg_M128_XMM15; + return X64Reg_M128_XMM15; } return -1; @@ -573,13 +573,13 @@ bool X64Instr::GetImmediate(uint64* outImm) int X64Instr::GetJmpState(int flags) { - const MCInstrDesc &instDesc = mX64->mInstrInfo->get(mMCInst.getOpcode()); + const MCInstrDesc &instDesc = mX64->mInstrInfo->get(mMCInst.getOpcode()); if ((instDesc.getFlags() & (1 << MCID::Branch)) == 0) return -1; if (mMCInst.getNumOperands() < 1) return 0; - + #define FLAGVAR(abbr, name) int flag##abbr = ((flags & ((uint64)1 << X64CPURegisters::GetFlagBitForRegister(X64Reg_FLAG_##abbr##_##name))) != 0) ? 1 : 0 FLAGVAR(CF, CARRY); FLAGVAR(PF, PARITY); @@ -641,10 +641,10 @@ void X64Instr::MarkRegsUsed(Array& regsUsed, bool overrideForm) int opCode = instDesc.getOpcode(); auto form = (instDesc.TSFlags & llvm::X86II::FormMask); - - /*if (opCode == 1724) + + /*if (opCode == 1724) { - // MOVAPSrr is emitted for all moves between XMM registers, regardless of + // MOVAPSrr is emitted for all moves between XMM registers, regardless of // their actual format, so we just copy the actual RegForm form here if (instDesc.getNumOperands() != 2) return; @@ -655,7 +655,7 @@ void X64Instr::MarkRegsUsed(Array& regsUsed, bool overrideForm) int regNumFrom = ConvertRegNum(operand); if (regNumFrom == -1) // ?? - return; + return; while (std::max(regNumFrom, regNumTo) >= (int)regsUsed.size()) regsUsed.push_back(RegForm_Invalid); @@ -680,7 +680,7 @@ void X64Instr::MarkRegsUsed(Array& regsUsed, bool overrideForm) int checkIdx = opCode * 3; //const MCInstrDesc &instDesc = mX64->mInstrInfo->get(mMCInst.getOpcode()); - //auto form = (instDesc.TSFlags & llvm::X86II::FormMask); + //auto form = (instDesc.TSFlags & llvm::X86II::FormMask); for (int opIdx = 0; opIdx < std::min((int)instDesc.getNumOperands(), 3); opIdx++) { @@ -696,7 +696,7 @@ void X64Instr::MarkRegsUsed(Array& regsUsed, bool overrideForm) regsUsed[regNum] = regForm; checkIdx++; - } + } } } @@ -733,7 +733,7 @@ uint64 X64Instr::GetTarget(Debugger* debugger, X64CPURegisters* registers) if (operand.isImm()) { - auto targetAddr = (uint64)operand.getImm(); + auto targetAddr = (uint64)operand.getImm(); if (instDesc.OpInfo[opIdx].OperandType == MCOI::OPERAND_PCREL) targetAddr += mAddress + mSize; return targetAddr; @@ -756,10 +756,10 @@ bool X64Instr::PartialSimulate(Debugger* debugger, X64CPURegisters* registers) // auto form = (instDesc.TSFlags & llvm::X86II::FormMask); // // if ((form == llvm::X86II::MRMSrcMem) && (instDesc.NumOperands == 6)) -// { +// { // auto destReg = mMCInst.getOperand(llvm::X86::AddrBaseReg); // if (destReg.isReg()) -// { +// { // int regNum = 0; // int offset = 0; // if (GetIndexRegisterAndOffset(®Num, &offset)) @@ -767,7 +767,7 @@ bool X64Instr::PartialSimulate(Debugger* debugger, X64CPURegisters* registers) // uint64 addr = registers->mIntRegsArray[regNum] + offset; // uint64 val = 0; // debugger->ReadMemory(addr, 8, &val); -// +// // switch (destReg.getReg()) // { // @@ -779,7 +779,7 @@ bool X64Instr::PartialSimulate(Debugger* debugger, X64CPURegisters* registers) //// if ((form == llvm::X86II::MRMDestMem) || (form == llvm::X86II::MRMSrcMem) || //// ((form >= llvm::X86II::MRM0m) && (form <= llvm::X86II::MRM7m))) //// { -//// } +//// } // } // // if (instDesc.getOpcode() == X86::XOR8rr) @@ -792,7 +792,7 @@ bool X64Instr::PartialSimulate(Debugger* debugger, X64CPURegisters* registers) // if ((destReg.isReg()) && (srcReg.isReg())) // { // if (destReg.getReg() == srcReg.getReg()) -// { +// { // switch (destReg.getReg()) // { // case X86::AL: @@ -817,8 +817,8 @@ X64CPU::X64CPU() : mInstrInfo = NULL; mInstPrinter = NULL; - //InitializeAllTargets(); - + //InitializeAllTargets(); + auto& TheX86_64Target = llvm::getTheX86_64Target(); const char* triple = "x86_64-pc-mingw32"; @@ -835,7 +835,7 @@ X64CPU::X64CPU() : return; mInstrInfo = TheX86_64Target.createMCInstrInfo(); - + mMCContext = new MCContext(Triple(triple), mAsmInfo, mRegisterInfo, mSubtargetInfo); mMCObjectFileInfo = TheX86_64Target.createMCObjectFileInfo(*mMCContext, false); @@ -875,11 +875,11 @@ X64CPU::~X64CPU() } bool X64CPU::Decode(uint64 address, DbgModuleMemoryCache* memoryCache, X64Instr* inst) -{ +{ inst->mAddress = address; inst->mX64 = this; - uint64 size = 0; + uint64 size = 0; uint8 data[15]; memoryCache->Read(address, data, 15); @@ -939,7 +939,6 @@ void X64CPU::GetNextPC(uint64 baseAddress, const uint8* dataBase, int dataLength mDisAsm->CommentStream = &nulls(); ArrayRef dataArrayRef(dataPtr, dataLength - (dataPtr - dataBase)); MCDisassembler::DecodeStatus S = mDisAsm->getInstruction(mcInst, size, dataArrayRef, address, nulls()); - } bool X64CPU::IsReturnInstruction(X64Instr* inst) @@ -957,7 +956,7 @@ String X64CPU::InstructionToString(X64Instr* inst, uint64 addr) //mInstPrinter->CurPCRelImmOffset = addr + inst->GetLength(); mInstPrinter->printInst(&inst->mMCInst, addr, annotationsStr, *mSubtargetInfo, OS); //OS.flush(); - //llvm::StringRef str = OS.str(); + //llvm::StringRef str = OS.str(); String result; for (int idx = 0; idx < (int)insnStr.size(); idx++) @@ -991,21 +990,21 @@ String X64CPU::InstructionToString(X64Instr* inst, uint64 addr) } DbgBreakKind X64CPU::GetDbgBreakKind(uint64 address, DbgModuleMemoryCache* memoryCache, int64* regs, int64* outObjectPtr) -{ +{ // We've looking for a CMP BYTE PTR [], -0x80 // if is R12 then encoding takes an extra 2 bytes - X64Instr inst; + X64Instr inst; for (int checkLen = 5; checkLen >= 3; checkLen--) - { + { int offset = -3 - checkLen; if (!Decode(address + offset, memoryCache, &inst)) - continue; + continue; if (inst.GetLength() != checkLen) continue; - const MCInstrDesc &instDesc = mInstrInfo->get(inst.mMCInst.getOpcode()); + const MCInstrDesc &instDesc = mInstrInfo->get(inst.mMCInst.getOpcode()); if (!instDesc.isCompare()) continue; @@ -1052,18 +1051,18 @@ DbgBreakKind X64CPU::GetDbgBreakKind(uint64 address, DbgModuleMemoryCache* memor for (int offset = 3; offset <= 3; offset++) { if (!Decode(address - offset, memoryCache, &inst)) - continue; + continue; if (inst.GetLength() != 2) continue; - const MCInstrDesc &instDesc = mInstrInfo->get(inst.mMCInst.getOpcode()); + const MCInstrDesc &instDesc = mInstrInfo->get(inst.mMCInst.getOpcode()); if (!instDesc.isBranch()) continue; auto immediateType = (instDesc.TSFlags & llvm::X86II::ImmMask); if ((immediateType == llvm::X86II::Imm8PCRel) && (inst.mMCInst.getNumOperands() == 2)) - { + { auto immOp = inst.mMCInst.getOperand(1); if (!immOp.isImm()) continue; @@ -1181,4 +1180,4 @@ bool X64CPU::ParseInlineAsmInstructionLLVM(const StringImpl&asmInst, String& out //outError = StrFormat("%s: \"%s\"", diagMessage.c_str(), diagLineContents.c_str()); return result; -} +} \ No newline at end of file diff --git a/IDEHelper/X64.h b/IDEHelper/X64.h index 68085a93..3cadf1a5 100644 --- a/IDEHelper/X64.h +++ b/IDEHelper/X64.h @@ -36,7 +36,7 @@ enum X64CPURegister X64Reg_None = -1, // integer general registers (DO NOT REORDER THESE; must exactly match DbgModule X64 register mappings) - X64Reg_RAX = 0, + X64Reg_RAX = 0, X64Reg_RDX, X64Reg_RCX, X64Reg_RBX, @@ -51,7 +51,7 @@ enum X64CPURegister X64Reg_R12, X64Reg_R13, X64Reg_R14, - X64Reg_R15, + X64Reg_R15, X64Reg_RIP, X64Reg_EFL, X64Reg_GS, @@ -74,7 +74,7 @@ enum X64CPURegister X64Reg_AX, X64Reg_DX, X64Reg_CX, - X64Reg_BX, + X64Reg_BX, X64Reg_SI, X64Reg_DI, X64Reg_R8W, @@ -93,7 +93,7 @@ enum X64CPURegister X64Reg_AH, X64Reg_DH, X64Reg_CH, - X64Reg_BH, + X64Reg_BH, X64Reg_SIL, X64Reg_DIL, X64Reg_R8B, @@ -159,7 +159,7 @@ enum X64CPURegister X64Reg_XMM12_f32, X64Reg_XMM13_f32, X64Reg_XMM14_f32, - X64Reg_XMM15_f32, + X64Reg_XMM15_f32, // xmm registers X64Reg_XMM00, @@ -298,14 +298,14 @@ public: struct IntRegs { - int64 rax; + int64 rax; int64 rdx; int64 rcx; - int64 rbx; + int64 rbx; int64 rsi; int64 rdi; uint64 rbp; - uint64 rsp; + uint64 rsp; int64 r8; int64 r9; int64 r10; @@ -395,7 +395,7 @@ public: X64Reg_RSP, X64Reg_RBP, X64Reg_RSI, - X64Reg_RDI, + X64Reg_RDI, X64Reg_R8, X64Reg_R9, X64Reg_R10, @@ -466,7 +466,7 @@ public: bool IsCall(); bool IsRep(bool& isPrefixOnly); bool IsReturn(); - bool IsLoadAddress(); + bool IsLoadAddress(); bool GetIndexRegisterAndOffset(int* outRegister, int* outOffset); // IE: [ebp + 0x4] bool GetImmediate(uint64* outImm); int GetJmpState(int flags); @@ -476,7 +476,6 @@ public: bool PartialSimulate(Debugger* debugger, X64CPURegisters* registers); }; - class X64CPU { public: diff --git a/IDEHelper/X86.cpp b/IDEHelper/X86.cpp index 0b38a3c1..518cb331 100644 --- a/IDEHelper/X86.cpp +++ b/IDEHelper/X86.cpp @@ -159,10 +159,10 @@ bool X86Instr::StackAdjust(uint32& adjust) if (mMCInst.getOpcode() != X86::SUB32ri8) return true; - + auto operand0 = mMCInst.getOperand(0); if (operand0.getReg() != llvm::X86::ESP) - return true; + return true; auto operand2 = mMCInst.getOperand(2); if (!operand2.isImm()) return false; @@ -191,7 +191,7 @@ bool X86Instr::IsReturn() } bool X86Instr::IsRep(bool& isPrefixOnly) -{ +{ auto instFlags = mMCInst.getFlags(); if ((instFlags & (X86::IP_HAS_REPEAT_NE | X86::IP_HAS_REPEAT)) != 0) { @@ -208,7 +208,7 @@ bool X86Instr::IsRep(bool& isPrefixOnly) } bool X86Instr::IsLoadAddress() -{ +{ const MCInstrDesc &instDesc = mX86->mInstrInfo->get(mMCInst.getOpcode()); if (instDesc.NumOperands >= 6) { @@ -234,25 +234,25 @@ static int ConvertRegNum(const MCOperand& operand) case llvm::X86::CL: case llvm::X86::CH: case llvm::X86::ECX: - return X86Reg_ECX; + return X86Reg_ECX; case llvm::X86::DL: case llvm::X86::DH: case llvm::X86::EDX: - return X86Reg_EDX; + return X86Reg_EDX; case llvm::X86::BL: case llvm::X86::BH: case llvm::X86::EBX: - return X86Reg_EBX; + return X86Reg_EBX; case llvm::X86::ESP: - return X86Reg_ESP; + return X86Reg_ESP; case llvm::X86::EBP: - return X86Reg_EBP; + return X86Reg_EBP; case llvm::X86::ESI: - return X86Reg_ESI; + return X86Reg_ESI; case llvm::X86::EDI: - return X86Reg_EDI; + return X86Reg_EDI; case llvm::X86::EIP: - return X86Reg_EIP; + return X86Reg_EIP; case llvm::X86::EFLAGS: return X86Reg_EFL; @@ -272,7 +272,7 @@ static int ConvertRegNum(const MCOperand& operand) return X86Reg_FPST6; case llvm::X86::ST7: return X86Reg_FPST7; - + case llvm::X86::XMM0: return X86Reg_M128_XMM0; case llvm::X86::XMM1: @@ -299,9 +299,9 @@ bool X86Instr::GetIndexRegisterAndOffset(int* outRegister, int* outOffset) const MCInstrDesc &instDesc = mX86->mInstrInfo->get(mMCInst.getOpcode()); auto form = (instDesc.TSFlags & llvm::X86II::FormMask); - if ((form == llvm::X86II::MRMDestMem) || (form == llvm::X86II::MRMSrcMem) || + if ((form == llvm::X86II::MRMDestMem) || (form == llvm::X86II::MRMSrcMem) || ((form >= llvm::X86II::MRM0m) && (form <= llvm::X86II::MRM7m))) - { + { auto baseReg = mMCInst.getOperand(llvm::X86::AddrBaseReg); auto scaleAmt = mMCInst.getOperand(llvm::X86::AddrScaleAmt); auto indexReg = mMCInst.getOperand(llvm::X86::AddrIndexReg); @@ -320,12 +320,12 @@ bool X86Instr::GetIndexRegisterAndOffset(int* outRegister, int* outOffset) if ((baseReg.isReg()) && (scaleAmt.isImm()) && (scaleAmt.getImm() == 1) && (indexReg.isReg()) && (indexReg.getReg() == llvm::X86::NoRegister) && - (addrDisp.isImm())) + (addrDisp.isImm())) { int regNum = ConvertRegNum(baseReg); if (regNum == -1) return false; - *outRegister = regNum; + *outRegister = regNum; *outOffset = (int)addrDisp.getImm(); return true; } @@ -336,11 +336,11 @@ bool X86Instr::GetIndexRegisterAndOffset(int* outRegister, int* outOffset) bool X86Instr::GetImmediate(uint32* outImm) { const MCInstrDesc &instDesc = mX86->mInstrInfo->get(mMCInst.getOpcode()); - + auto immediateType = (instDesc.TSFlags & llvm::X86II::ImmMask); if ((immediateType == 0) && (mMCInst.getNumOperands() < 6)) return false; - + auto immOp = mMCInst.getOperand(5); if (!immOp.isImm()) return false; @@ -376,9 +376,9 @@ void X86Instr::MarkRegsUsed(Array& regsUsed, bool overrideForm) } uint32 X86Instr::GetTarget(Debugger* debugger, X86CPURegisters* registers) -{ +{ const MCInstrDesc &instDesc = mX86->mInstrInfo->get(mMCInst.getOpcode()); - + if (mMCInst.getNumOperands() < 1) return 0; @@ -389,7 +389,7 @@ uint32 X86Instr::GetTarget(Debugger* debugger, X86CPURegisters* registers) opIdx = 4; operand = mMCInst.getOperand(opIdx); } - + if (operand.isImm()) { auto targetAddr = (uint32)operand.getImm(); @@ -418,7 +418,7 @@ X86CPU::X86CPU() : mInstrInfo = NULL; mInstPrinter = NULL; - //InitializeAllTargets(); + //InitializeAllTargets(); auto& TheX86_32Target = getTheX86_32Target(); @@ -438,7 +438,7 @@ X86CPU::X86CPU() : //TargetOptions targetOptions; //TargetMachine* targetMachine = TheX86_32Target.createTargetMachine(triple, "x86", "", targetOptions); - //const MCInstrInfo* MII = targetMachine->getSubtargetImpl()->getInstrInfo(); + //const MCInstrInfo* MII = targetMachine->getSubtargetImpl()->getInstrInfo(); //STI->getIntr mInstrInfo = TheX86_32Target.createMCInstrInfo(); @@ -452,11 +452,11 @@ X86CPU::X86CPU() : mMCContext->setObjectFileInfo(mMCObjectFileInfo); MCDisassembler *disAsm = TheX86_32Target.createMCDisassembler(*mSubtargetInfo, *mMCContext); - mDisAsm = disAsm; + mDisAsm = disAsm; //TODO: LLVM3.8 - changed params /*mInstPrinter = TheX86_32Target.createMCInstPrinter(1, *mAsmInfo, - *mInstrInfo, *mRegisterInfo, *mSubtargetInfo);*/ + *mInstrInfo, *mRegisterInfo, *mSubtargetInfo);*/ mInstPrinter = TheX86_32Target.createMCInstPrinter(Triple(triple), 1, *mAsmInfo, *mInstrInfo, *mRegisterInfo); @@ -471,7 +471,7 @@ X86CPU::X86CPU() : extern "C" void LLVMShutdown(); X86CPU::~X86CPU() -{ +{ delete mInstPrinter; delete mDisAsm; delete mMCContext; @@ -485,11 +485,11 @@ X86CPU::~X86CPU() } bool X86CPU::Decode(uint32 address, DbgModuleMemoryCache* memoryCache, X86Instr* inst) -{ +{ inst->mAddress = address; inst->mX86 = this; - uint64 size = 0; + uint64 size = 0; uint8 data[15]; memoryCache->Read(address, data, 15); @@ -504,15 +504,15 @@ bool X86CPU::Decode(uint32 address, DbgModuleMemoryCache* memoryCache, X86Instr* bool X86CPU::Decode(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, X86Instr* inst) { //X86GenericDisassembler assembler; - + //DisasmMemoryObject region((uint8*)dataBase, dataLength, baseAddress); //std::memorystream - + uint32 address = baseAddress + (uint32)(dataPtr - dataBase); inst->mAddress = address; inst->mX86 = this; - uint64 size = 0; + uint64 size = 0; //TODO: LLVM3.8 //MCDisassembler::DecodeStatus S = mDisAsm->getInstruction(inst->mMCInst, size, region, address, nulls(), inst->mAnnotationStream); @@ -526,7 +526,7 @@ bool X86CPU::Decode(uint32 baseAddress, const uint8* dataBase, int dataLength, c void X86CPU::GetNextPC(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, uint32* regs, uint32 nextPCs[2]) { - //DisasmMemoryObject region((uint8*) dataBase, dataLength, baseAddress); + //DisasmMemoryObject region((uint8*) dataBase, dataLength, baseAddress); uint32 address = baseAddress + (uint32)(dataPtr - dataBase); uint64 size = 0; @@ -535,17 +535,16 @@ void X86CPU::GetNextPC(uint32 baseAddress, const uint8* dataBase, int dataLength mDisAsm->CommentStream = &nulls(); ArrayRef dataArrayRef(dataPtr, dataLength - (dataPtr - dataBase)); MCDisassembler::DecodeStatus S = mDisAsm->getInstruction(mcInst, size, dataArrayRef, address, nulls()); - } bool X86CPU::IsReturnInstruction(X86Instr* inst) { const MCInstrDesc &instDesc = mInstrInfo->get(inst->mMCInst.getOpcode()); - return (instDesc.getFlags() & (1< insnStr; @@ -553,8 +552,8 @@ String X86CPU::InstructionToString(X86Instr* inst, uint32 addr) //mInstPrinter->CurPCRelImmOffset = addr + inst->GetLength(); mInstPrinter->printInst(&inst->mMCInst, addr, annotationsStr, *mSubtargetInfo, OS); //OS.flush(); - //llvm::StringRef str = OS.str(); - + //llvm::StringRef str = OS.str(); + String result; for (int idx = 0; idx < (int)insnStr.size(); idx++) { @@ -570,8 +569,8 @@ String X86CPU::InstructionToString(X86Instr* inst, uint32 addr) else result.Append(c); } - - /*String result = String(insnStr.data(), insnStr.size()); + + /*String result = String(insnStr.data(), insnStr.size()); for (int i = 0; i < (int)result.length(); i++) { if (result[i] == '\t') @@ -671,12 +670,12 @@ int X86CPU::GetOpcodesForMnemonic(const StringImpl& mnemonic, Array& outOpc String s(mnemonic); std::transform(s.begin(), s.end(), s.begin(), ::tolower); std::pair range = mStringToOpcodeMap.equal_range(s); - + outOpcodes.Clear(); for (StringToOpcodeMap::iterator it = range.first; it != range.second; ++it) outOpcodes.push_back(it->second); - return (int)outOpcodes.size(); + return (int)outOpcodes.size(); } void X86CPU::GetClobbersForMnemonic(const StringImpl& mnemonic, int argCount, Array& outImplicitClobberRegNums, int& outClobberArgCount, bool& outMayClobberMem) diff --git a/IDEHelper/X86.h b/IDEHelper/X86.h index 76af5d72..0640ec52 100644 --- a/IDEHelper/X86.h +++ b/IDEHelper/X86.h @@ -193,7 +193,7 @@ public: struct XmmDReg { double d[2]; - }; + }; struct XmmI32Reg { @@ -289,7 +289,7 @@ public: llvm::raw_svector_ostream mAnnotationStream; static uint8 sRegForm[]; - X86Instr() : + X86Instr() : mAnnotationStream(mAnnotationStr) { mX86 = NULL; @@ -297,7 +297,7 @@ public: mSize = 0; } - int GetLength(); + int GetLength(); bool StackAdjust(uint32& adjust); bool IsBranch(); bool IsCall(); @@ -340,7 +340,7 @@ public: bool Decode(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, X86Instr* inst); uint32 DecodeThunk(uint32 address, DbgModuleMemoryCache* memoryCache) { return 0; } - bool IsReturnInstruction(X86Instr* inst); + bool IsReturnInstruction(X86Instr* inst); String InstructionToString(X86Instr* inst, uint32 addr); void GetNextPC(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, uint32* regs, uint32 nextPCs[2]); diff --git a/IDEHelper/X86Target.cpp b/IDEHelper/X86Target.cpp index 5a5b80fa..0812b0f2 100644 --- a/IDEHelper/X86Target.cpp +++ b/IDEHelper/X86Target.cpp @@ -103,4 +103,4 @@ X86Target::~X86Target() { delete mX86CPU; delete mX64CPU; -} +} \ No newline at end of file diff --git a/bin/build.sh b/bin/build.sh index 22c3b141..3d234bed 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -4,9 +4,30 @@ echo Starting build.sh PATH=/usr/local/bin:$PATH:$HOME/bin SCRIPTPATH=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P) ROOTPATH="$(dirname "$SCRIPTPATH")" -echo Building from from $SCRIPTPATH +echo Building from $SCRIPTPATH cd $SCRIPTPATH +if [[ $1 == "clean" ]]; then + rm -rf ../jbuild + rm -rf ../jbuild_d +fi + +if command -v ninja >/dev/null 2>&1 ; then + CAN_USE_NINJA=1 + if [ -d ../jbuild_d ] && [ ! -f ../jbuild_d/build.ninja ]; then + CAN_USE_NINJA=0 + fi + + if [ $CAN_USE_NINJA == 1 ]; then + echo "Ninja is enabled for this build." + USE_NINJA="-GNinja" + else + echo "Ninja couldn't be enabled for this build, consider doing a clean build to start using Ninja for faster build speeds." + fi +else + echo "Ninja isn't installed, consider installing it for faster build speeds." +fi + # exit when any command fails set -e @@ -16,7 +37,7 @@ if [ ! -f ../BeefySysLib/third_party/libffi/Makefile ]; then echo Building libffi... cd ../BeefySysLib/third_party/libffi ./configure - make + make cd $SCRIPTPATH fi @@ -35,19 +56,19 @@ if [ ! -d jbuild_d ]; then mkdir jbuild fi cd jbuild_d -cmake -DCMAKE_BUILD_TYPE=Debug ../ +cmake $USE_NINJA -DCMAKE_BUILD_TYPE=Debug ../ cmake --build . cd ../jbuild -cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ../ +cmake $USE_NINJA -DCMAKE_BUILD_TYPE=RelWithDebInfo ../ cmake --build . cd ../IDE/dist if [[ "$OSTYPE" == "darwin"* ]]; then LIBEXT=dylib - LINKOPTS="-Wl,-no_compact_unwind -Wl,-rpath -Wl,@executable_path" + LINKOPTS="-Wl,-no_compact_unwind -Wl,-rpath -Wl,@executable_path" else - LIBEXT=so + LIBEXT=so LINKOPTS="-ldl -lpthread -Wl,-rpath -Wl,\$ORIGIN" fi diff --git a/extern/hunspell/CMakeLists.txt b/extern/hunspell/CMakeLists.txt index 3364d64f..7b121cad 100644 --- a/extern/hunspell/CMakeLists.txt +++ b/extern/hunspell/CMakeLists.txt @@ -24,9 +24,9 @@ endif(NOT CMAKE_BUILD_TYPE) # Definition of Macros add_definitions( - -D_DEBUG - -DIDEHELPER_EXPORTS - -DBFSYSLIB_DYNAMIC + -D_DEBUG + -DIDEHELPER_EXPORTS + -DBFSYSLIB_DYNAMIC -DUNICODE -D_UNICODE -DBF_NO_FBX @@ -57,16 +57,16 @@ endif() # Add Dependencies to project. # ################################################### -option(BUILD_DEPENDS - "Build other CMake project." - ON +option(BUILD_DEPENDS + "Build other CMake project." + ON ) # Dependencies : disable BUILD_DEPENDS to link with lib already build. if(BUILD_DEPENDS) - + else() - + endif() ################# Flags ################ @@ -78,10 +78,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc") endif(MSVC) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar") - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar") endif(NOT MSVC) ################ Files ################ diff --git a/extern/hunspell/src/win_api/libhunspell.vcxproj b/extern/hunspell/src/win_api/libhunspell.vcxproj index f36bcd03..1a9fb80e 100644 --- a/extern/hunspell/src/win_api/libhunspell.vcxproj +++ b/extern/hunspell/src/win_api/libhunspell.vcxproj @@ -166,6 +166,7 @@ $(IntDir)$(ProjectName).pdb Level1 EditAndContinue + true /MACHINE:X86 %(AdditionalOptions) @@ -186,6 +187,7 @@ ProgramDatabase 4706;4267;4100 false + true @@ -205,6 +207,7 @@ $(IntDir)$(ProjectName).pdb Level1 + true NDEBUG;%(PreprocessorDefinitions) @@ -231,6 +234,7 @@ 4267;4706;4100 false + true NDEBUG;%(PreprocessorDefinitions) diff --git a/extern/llvm_build.sh b/extern/llvm_build.sh index 261e8062..b81e11b6 100755 --- a/extern/llvm_build.sh +++ b/extern/llvm_build.sh @@ -1,6 +1,11 @@ #!/bin/bash set -e +USE_NINJA="" +if command -v ninja >/dev/null 2>&1 ; then + USE_NINJA="-GNinja" +fi + if [ ! -d llvm-project_13_0_1 ]; then if [ -f llvm-13.0.1.src.tar.xz ]; then # if user downloaded llvm-13.0.1.src.tar.xz then use it instead tar -xf llvm-13.0.1.src.tar.xz @@ -17,7 +22,7 @@ fi if [ ! -d llvm_linux_13_0_1/bin ]; then cd llvm_linux_13_0_1 - cmake ../llvm-project_13_0_1/llvm -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86;WebAssembly" -DCMAKE_BUILD_TYPE:String="Debug" + cmake $USE_NINJA ../llvm-project_13_0_1/llvm -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86;WebAssembly" -DCMAKE_BUILD_TYPE:String="Debug" cmake --build . -t $(cat ../llvm_targets.txt) cd .. fi @@ -28,7 +33,7 @@ fi if [ ! -d llvm_linux_rel_13_0_1/bin ]; then cd llvm_linux_rel_13_0_1 - cmake ../llvm-project_13_0_1/llvm -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86;WebAssembly" -DCMAKE_BUILD_TYPE:String="Release" + cmake $USE_NINJA ../llvm-project_13_0_1/llvm -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86;WebAssembly" -DCMAKE_BUILD_TYPE:String="Release" cmake --build . -t $(cat ../llvm_targets.txt) cd .. fi diff --git a/wasm/build_wasm.bat b/wasm/build_wasm.bat index 9ff409fb..0f51e363 100644 --- a/wasm/build_wasm.bat +++ b/wasm/build_wasm.bat @@ -26,13 +26,15 @@ mkdir src\BeefySysLib\third_party\utf8proc copy ..\BeefySysLib\third_party\utf8proc\* src\BeefySysLib\third_party\utf8proc mkdir src\BeefySysLib\third_party\stb copy ..\BeefySysLib\third_party\stb\* src\BeefySysLib\third_party\stb +mkdir src\BeefySysLib\third_party\putty +copy ..\BeefySysLib\third_party\putty\* src\BeefySysLib\third_party\putty :SKIPCOPY IF "%1" EQU "setup" GOTO SUCCESS -call emcc src\rt\Chars.cpp src\rt\Math.cpp src\rt\Object.cpp src\rt\Thread.cpp src\rt\Internal.cpp src\BeefySysLib\platform\wasm\WasmCommon.cpp src\BeefySysLib\Common.cpp src\BeefySysLib\util\String.cpp src\BeefySysLib\util\UTF8.cpp src\BeefySysLib\third_party\utf8proc\utf8proc.c -Isrc\ -Isrc\BeefySysLib -Isrc\BeefySysLib\platform\wasm -g -DBF_DISABLE_FFI -c -s WASM=1 -s USE_PTHREADS=1 +call emcc src\rt\Chars.cpp src\rt\Math.cpp src\rt\Object.cpp src\rt\Thread.cpp src\rt\Internal.cpp src\BeefySysLib\platform\wasm\WasmCommon.cpp src\BeefySysLib\Common.cpp src\BeefySysLib\util\String.cpp src\BeefySysLib\util\UTF8.cpp src\BeefySysLib\third_party\utf8proc\utf8proc.c src\BeefySysLib\third_party\putty\wildcard.c -Isrc\ -Isrc\BeefySysLib -Isrc\BeefySysLib\platform\wasm -g -DBF_DISABLE_FFI -c -s WASM=1 -s USE_PTHREADS=1 @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR -call emar r %LIBPATH%\Beef042RT32_wasm.a Common.o Internal.o Chars.o Math.o Object.o String.o Thread.o UTF8.o utf8proc.o WasmCommon.o +call emar r %LIBPATH%\Beef042RT32_wasm.a Common.o Internal.o Chars.o Math.o Object.o String.o Thread.o UTF8.o utf8proc.o wildcard.o WasmCommon.o @IF %ERRORLEVEL% NEQ 0 GOTO HADERROR :SUCCESS