diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf index 3a16088d..8549c43c 100644 --- a/BeefLibs/corlib/src/Attribute.bf +++ b/BeefLibs/corlib/src/Attribute.bf @@ -30,6 +30,8 @@ namespace System Delete = 0x80000, Alias = 0x100000, Block = 0x200000, + DelegateTypeRef = 0x400000, + FunctionTypeRef = 0x800000, Types = .Struct | .Enum | .Function | .Class | .Interface, ValueTypes = .Struct | .Enum | .Function, @@ -227,7 +229,7 @@ namespace System } - [AttributeUsage(.Method | .Constructor | .Delegate | .Function)] + [AttributeUsage(.Method | .Constructor | .Delegate | .Function | .DelegateTypeRef | .FunctionTypeRef)] public struct CallingConventionAttribute : Attribute { public enum Kind diff --git a/BeefLibs/corlib/src/IO/Shell.bf b/BeefLibs/corlib/src/IO/Shell.bf index 1c230313..41151db2 100644 --- a/BeefLibs/corlib/src/IO/Shell.bf +++ b/BeefLibs/corlib/src/IO/Shell.bf @@ -9,7 +9,7 @@ namespace System.IO { public struct VTable : COM_IUnknown.VTable { - public function HResult(COM_IPersistFile* self, Guid* pClassID) GetClassID; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, Guid* pClassID) GetClassID; } } @@ -19,11 +19,11 @@ namespace System.IO public struct VTable : COM_IPersist.VTable { - public function HResult(COM_IPersistFile* self) IsDirty; - public function HResult(COM_IPersistFile* self, char16* pszFileName) Load; - public function HResult(COM_IPersistFile* self, char16* pszFileName, Windows.IntBool remember) Save; - public function HResult(COM_IPersistFile* self, char16* pszFileName) SaveCompleted; - public function HResult(COM_IPersistFile* self, char16* pszName) GetCurFile; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self) IsDirty; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName) Load; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName, Windows.IntBool remember) Save; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszFileName) SaveCompleted; + public function [CallingConvention(.Stdcall)] HResult(COM_IPersistFile* self, char16* pszName) GetCurFile; } public new VTable* VT { @@ -43,24 +43,24 @@ namespace System.IO public struct VTable : Windows.COM_IUnknown.VTable { - public function HResult(COM_IShellLink* self, char16* pszFile, int32 cch, Windows.NativeFindData* pfd, uint32 fFlags) GetPath; - public function HResult(COM_IShellLink* self, IDLIST** ppidl) GetIDList; - public function HResult(COM_IShellLink* self, IDLIST* pidl) SetIDList; - public function HResult(COM_IShellLink* self, char16* pszName, int32 cch) GetDescription; - public function HResult(COM_IShellLink* self, char16* pszName) SetDescription; - public function HResult(COM_IShellLink* self, char16* pszDir, int32 cch) GetWorkingDirectory; - public function HResult(COM_IShellLink* self, char16* pszDir) SetWorkingDirectory; - public function HResult(COM_IShellLink* self, char16* pszArgs, int32 cch) GetArguments; - public function HResult(COM_IShellLink* self, char16* pszArgs) SetArguments; - public function HResult(COM_IShellLink* self, uint16 *pwHotkey) GetHotkey; - public function HResult(COM_IShellLink* self, uint16 wHotkey) SetHotkey; - public function HResult(COM_IShellLink* self, int32 *piShowCmd) GetShowCmd; - public function HResult(COM_IShellLink* self, int32 iShowCmd) SetShowCmd; - public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 cch, int32 *piIcon) GetIconLocation; - public function HResult(COM_IShellLink* self, char16* pszIconPath, int32 iIcon) SetIconLocation; - public function HResult(COM_IShellLink* self, char16* pszPathRel, uint32 dwReserved) SetRelativePath; - public function HResult(COM_IShellLink* self, Windows.HWnd hwnd, uint32 fFlags) Resolve; - public function HResult(COM_IShellLink* self, char16* pszFile) SetPath; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszFile, int32 cch, Windows.NativeFindData* pfd, uint32 fFlags) GetPath; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, IDLIST** ppidl) GetIDList; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, IDLIST* pidl) SetIDList; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszName, int32 cch) GetDescription; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszName) SetDescription; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszDir, int32 cch) GetWorkingDirectory; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszDir) SetWorkingDirectory; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszArgs, int32 cch) GetArguments; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszArgs) SetArguments; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, uint16 *pwHotkey) GetHotkey; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, uint16 wHotkey) SetHotkey; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, int32 *piShowCmd) GetShowCmd; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, int32 iShowCmd) SetShowCmd; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszIconPath, int32 cch, int32 *piIcon) GetIconLocation; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszIconPath, int32 iIcon) SetIconLocation; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszPathRel, uint32 dwReserved) SetRelativePath; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, Windows.HWnd hwnd, uint32 fFlags) Resolve; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellLink* self, char16* pszFile) SetPath; } public new VTable* VT diff --git a/BeefLibs/corlib/src/Windows.bf b/BeefLibs/corlib/src/Windows.bf index 23de97ad..b94d61c0 100644 --- a/BeefLibs/corlib/src/Windows.bf +++ b/BeefLibs/corlib/src/Windows.bf @@ -47,9 +47,9 @@ namespace System public struct VTable { - public function HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface; - public function uint32(COM_IUnknown* self) AddRef; - public function uint32(COM_IUnknown* self) Release; + public function [CallingConvention(.Stdcall)] HResult(COM_IUnknown* self, ref Guid riid, void** result) QueryInterface; + public function [CallingConvention(.Stdcall)] uint32(COM_IUnknown* self) AddRef; + public function [CallingConvention(.Stdcall)] uint32(COM_IUnknown* self) Release; } public enum HResult : int32 @@ -1124,13 +1124,13 @@ namespace System public struct VTable : Windows.COM_IUnknown.VTable { - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFileOk; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* psiFolder) OnFolderChanging; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFolderChange; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnSelectionChange; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, FDE_SHAREVIOLATION_RESPONSE* pResponse) OnShareViolation; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnTypeChange; - public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* shellItem, FDE_OVERWRITE_RESPONSE* response) OnOverwrite; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFileOk; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* psiFolder) OnFolderChanging; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFolderChange; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnSelectionChange; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, FDE_SHAREVIOLATION_RESPONSE* pResponse) OnShareViolation; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnTypeChange; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* shellItem, FDE_OVERWRITE_RESPONSE* response) OnOverwrite; } } @@ -1154,11 +1154,11 @@ namespace System public struct VTable : Windows.COM_IUnknown.VTable { - public function HResult(COM_IShellItem* self, void* pbc, ref Guid bhid, ref Guid riid, void** ppv) BindToHandler; - public function HResult(COM_IShellItem* self, out COM_IShellItem* ppsi) GetParent; - public function HResult(COM_IShellItem* self, SIGDN sigdnName, out char16* ppszName) GetDisplayName; - public function HResult(COM_IShellItem* self, uint sfgaoMask, out uint psfgaoAttribs) GetAttributes; - public function HResult(COM_IShellItem* self, COM_IShellItem* psi, uint32 hint, out int32 piOrder) Compare; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, void* pbc, ref Guid bhid, ref Guid riid, void** ppv) BindToHandler; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, out COM_IShellItem* ppsi) GetParent; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, SIGDN sigdnName, out char16* ppszName) GetDisplayName; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, uint sfgaoMask, out uint psfgaoAttribs) GetAttributes; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItem* self, COM_IShellItem* psi, uint32 hint, out int32 piOrder) Compare; } public new VTable* VT @@ -1207,13 +1207,13 @@ namespace System public struct VTable : Windows.COM_IUnknown.VTable { - public function HResult(COM_IShellItemArray* self, void* pbc, ref Guid rbhid, ref Guid riid, out void* ppvOut) BindToHandler; - public function HResult(COM_IShellItemArray* self, GETPROPERTYSTOREFLAGS flags, ref Guid riid, out void* ppv) GetPropertyStore; - public function HResult(COM_IShellItemArray* self, ref PROPERTYKEY keyType, ref Guid riid, out void* ppv) GetPropertyDescriptionList; - public function HResult(COM_IShellItemArray* self, SIATTRIBFLAGS dwAttribFlags, uint32 sfgaoMask, out uint32 psfgaoAttribs) GetAttributes; - public function HResult(COM_IShellItemArray* self, out uint32 pdwNumItems) GetCount; - public function HResult(COM_IShellItemArray* self, uint32 dwIndex, out COM_IShellItem* ppsi) GetItemAt; - public function HResult(COM_IShellItemArray* self, out void* ppenumShellItems) EnumItems; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, void* pbc, ref Guid rbhid, ref Guid riid, out void* ppvOut) BindToHandler; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, GETPROPERTYSTOREFLAGS flags, ref Guid riid, out void* ppv) GetPropertyStore; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, ref PROPERTYKEY keyType, ref Guid riid, out void* ppv) GetPropertyDescriptionList; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, SIATTRIBFLAGS dwAttribFlags, uint32 sfgaoMask, out uint32 psfgaoAttribs) GetAttributes; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, out uint32 pdwNumItems) GetCount; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, uint32 dwIndex, out COM_IShellItem* ppsi) GetItemAt; + public function [CallingConvention(.Stdcall)] HResult(COM_IShellItemArray* self, out void* ppenumShellItems) EnumItems; } public new VTable* VT { @@ -1268,30 +1268,30 @@ namespace System public struct VTable : Windows.COM_IUnknown.VTable { - public function HResult(COM_IFileDialog* self, Windows.HWnd parent) Show; - public function HResult(COM_IFileDialog* self, uint cFileTypes, COMDLG_FILTERSPEC* rgFilterSpec) SetFileTypes; - public function HResult(COM_IFileDialog* self, uint iFileType) SetFileTypeIndex; - public function HResult(COM_IFileDialog* self, out uint piFileType) GetFileTypeIndex; - public function HResult(COM_IFileDialog* self, COM_IFileDialogEvents* pfde, out uint pdwCookie) Advise; - public function HResult(COM_IFileDialog* self, uint dwCookie) Unadvise; - public function HResult(COM_IFileDialog* self, FOS fos) SetOptions; - public function HResult(COM_IFileDialog* self, out FOS pfos) GetOptions; - public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetDefaultFolder; - public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetFolder; - public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetFolder; - public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetCurrentSelection; - public function HResult(COM_IFileDialog* self, char16* pszName) SetFileName; - public function HResult(COM_IFileDialog* self, out char16* pszName) GetFileName; - public function HResult(COM_IFileDialog* self, char16* pszTitle) SetTitle; - public function HResult(COM_IFileDialog* self, char16* pszText) SetOkButtonLabel; - public function HResult(COM_IFileDialog* self, char16* pszLabel) SetFileNameLabel; - public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetResult; - public function HResult(COM_IFileDialog* self, COM_IShellItem* psi, FDAP fdap) AddPlace; - public function HResult(COM_IFileDialog* self, char16* pszDefaultExtension) SetDefaultExtension; - public function HResult(COM_IFileDialog* self, int hr) Close; - public function HResult(COM_IFileDialog* self, ref Guid guid) SetClientGuid; - public function HResult(COM_IFileDialog* self) ClearClientData; - public function HResult(COM_IFileDialog* self, void* pFilter) SetFilter; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, Windows.HWnd parent) Show; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint cFileTypes, COMDLG_FILTERSPEC* rgFilterSpec) SetFileTypes; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint iFileType) SetFileTypeIndex; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out uint piFileType) GetFileTypeIndex; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IFileDialogEvents* pfde, out uint pdwCookie) Advise; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, uint dwCookie) Unadvise; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, FOS fos) SetOptions; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out FOS pfos) GetOptions; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetDefaultFolder; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetFolder; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetFolder; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetCurrentSelection; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszName) SetFileName; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out char16* pszName) GetFileName; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszTitle) SetTitle; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszText) SetOkButtonLabel; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszLabel) SetFileNameLabel; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetResult; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, COM_IShellItem* psi, FDAP fdap) AddPlace; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, char16* pszDefaultExtension) SetDefaultExtension; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, int hr) Close; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, ref Guid guid) SetClientGuid; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self) ClearClientData; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileDialog* self, void* pFilter) SetFilter; } public new VTable* VT { @@ -1314,8 +1314,8 @@ namespace System public struct VTable : COM_IFileDialog.VTable { - public function HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppenum) GetResults; - public function HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppsai) GetSelectedItems; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppenum) GetResults; + public function [CallingConvention(.Stdcall)] HResult(COM_IFileOpenDialog* self, out COM_IShellItemArray* ppsai) GetSelectedItems; } public new VTable* VT { diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 9bd0fa6f..21b546ba 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -14769,7 +14769,7 @@ BfAllocTarget BfExprEvaluator::ResolveAllocTarget(BfAstNode* allocNode, BfTokenN if (attributeDirective != NULL) { - auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, true, &allocTarget.mCaptureInfo); + auto customAttrs = mModule->GetCustomAttributes(attributeDirective, BfAttributeTargets_Alloc, BfGetCustomAttributesFlags_AllowNonConstArgs, &allocTarget.mCaptureInfo); if (customAttrs != NULL) { for (auto& attrib : customAttrs->mAttributes) diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index d085677a..0468eeb1 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -11144,8 +11144,11 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf } } -void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo) +void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, BfGetCustomAttributesFlags flags, BfCaptureInfo* captureInfo) { + bool allowNonConstArgs = (flags & BfGetCustomAttributesFlags_AllowNonConstArgs) != 0; + bool keepConstsInModule = (flags & BfGetCustomAttributesFlags_KeepConstsInModule) != 0; + if (!mCompiler->mHasRequiredTypes) return; @@ -11389,7 +11392,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues); if (result) { - CurrentAddToConstHolder(result.mValue); + if (!keepConstsInModule) + CurrentAddToConstHolder(result.mValue); setField.mParam = result; customAttribute.mSetField.push_back(setField); } @@ -11451,7 +11455,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri if (!result.mValue.IsConst()) result = GetDefaultTypedValue(result.mType); BF_ASSERT(result.mType == propType); - CurrentAddToConstHolder(result.mValue); + if (!keepConstsInModule) + CurrentAddToConstHolder(result.mValue); setProperty.mParam = result; customAttribute.mSetProperties.push_back(setProperty); } @@ -11567,10 +11572,13 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri } // Move all those to the constHolder - for (auto& ctorArg : customAttribute.mCtorArgs) - { - if (ctorArg.IsConst()) - CurrentAddToConstHolder(ctorArg); + if (!keepConstsInModule) + { + for (auto& ctorArg : customAttribute.mCtorArgs) + { + if (ctorArg.IsConst()) + CurrentAddToConstHolder(ctorArg); + } } if (attributesDirective->mAttributeTargetSpecifier != NULL) @@ -11627,10 +11635,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri ValidateCustomAttributes(customAttributes, attrTarget); } -BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs, BfCaptureInfo* captureInfo) +BfCustomAttributes* BfModule::GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags, BfCaptureInfo* captureInfo) { BfCustomAttributes* customAttributes = new BfCustomAttributes(); - GetCustomAttributes(customAttributes, attributesDirective, attrType, allowNonConstArgs, captureInfo); + GetCustomAttributes(customAttributes, attributesDirective, attrType, flags, captureInfo); return customAttributes; } @@ -15480,7 +15488,11 @@ void BfModule::CreateDelegateInvokeMethod() mBfIRBuilder->AddBlock(doneBB); mBfIRBuilder->SetInsertPoint(doneBB); - if ((mCurMethodInstance->mReturnType->IsValuelessType()) || + if (mCurMethodInstance->mReturnType->IsVar()) + { + // Do nothing + } + else if ((mCurMethodInstance->mReturnType->IsValuelessType()) || ((!mIsComptimeModule) && (mCurMethodInstance->GetStructRetIdx() != -1))) { mBfIRBuilder->CreateRetVoid(); @@ -21553,6 +21565,10 @@ 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; } void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& mangledName, bool isTemporaryFunc, bool* outIsIntrinsic) @@ -21831,6 +21847,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { BP_ZONE("BfModule::BfMethodDeclaration"); + if (mCurTypeInstance->IsFunctionFromTypeRef()) + { + NOP; + } + // 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); diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index d575d265..0be8a8b2 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1383,6 +1383,13 @@ enum BfDeferredBlockFlags BfDeferredBlockFlag_MoveNewBlocksToEnd = 8, }; +enum BfGetCustomAttributesFlags +{ + BfGetCustomAttributesFlags_None = 0, + BfGetCustomAttributesFlags_AllowNonConstArgs = 1, + BfGetCustomAttributesFlags_KeepConstsInModule = 2 +}; + class BfVDataExtEntry { public: @@ -1567,8 +1574,8 @@ public: BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType); BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false); void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget); - void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL); - BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL); + void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL); + BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, BfGetCustomAttributesFlags flags = BfGetCustomAttributesFlags_None, BfCaptureInfo* captureInfo = NULL); BfCustomAttributes* GetCustomAttributes(BfTypeDef* typeDef); void FinishAttributeState(BfAttributeState* attributeState); void ProcessTypeInstCustomAttributes(bool& isPacked, bool& isUnion, bool& isCRepr, bool& isOrdered, int& alignOverride, BfType*& underlyingArrayType, int& underlyingArraySize); @@ -1846,6 +1853,7 @@ public: void CheckIdentifierFixit(BfAstNode* node); void TypeRefNotFound(BfTypeReference* typeRef, const char* appendName = NULL); bool ValidateTypeWildcard(BfTypeReference* 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); BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index d1201234..616b3c45 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -9370,6 +9370,28 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod return BfTypedValue(); } +void BfModule::GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention) +{ + if (delegateTypeRef->mAttributes == NULL) + return; + + BfCaptureInfo captureInfo; + auto customAttributes = GetCustomAttributes(delegateTypeRef->mAttributes, (BfAttributeTargets)(BfAttributeTargets_DelegateTypeRef | BfAttributeTargets_FunctionTypeRef), BfGetCustomAttributesFlags_KeepConstsInModule); + if (customAttributes != NULL) + { + auto linkNameAttr = customAttributes->Get(mCompiler->mCallingConventionAttributeTypeDef); + if (linkNameAttr != NULL) + { + if (linkNameAttr->mCtorArgs.size() == 1) + { + auto constant = mBfIRBuilder->GetConstant(linkNameAttr->mCtorArgs[0]); + if (constant != NULL) + callingConvention = (BfCallingConvention)constant->mInt32; + } + } + } +} + BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, int numGenericArgs) { BP_ZONE("BfModule::ResolveTypeRef"); @@ -10113,6 +10135,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula lookupCtx.mRootTypeDef = typeDef; lookupCtx.mModule = this; BfResolvedTypeSet::Entry* resolvedEntry = NULL; + if (auto delegateTypeRef = BfNodeDynCastExact(typeRef)) + GetDelegateTypeRefAttributes(delegateTypeRef, lookupCtx.mCallingConvention); + auto inserted = mContext->mResolvedTypes.Insert(typeRef, &lookupCtx, &resolvedEntry); if (resolvedEntry == NULL) @@ -10867,7 +10892,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula dlgType->mIsUnspecializedTypeVariation = isUnspecialized; delegateType = dlgType; } - + + delegateInfo->mCallingConvention = lookupCtx.mCallingConvention; + Val128 hashContext; BfTypeDef* typeDef = new BfTypeDef(); @@ -13123,9 +13150,11 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf auto fromMethodInst = GetRawMethodByName(fromTypeInst, "Invoke", -1, true); auto toMethodInst = GetRawMethodByName(toTypeInst, "Invoke", -1, true); - + + auto toDelegateInfo = toTypeInst->GetDelegateInfo(); + if ((fromMethodInst != NULL) && (toMethodInst != NULL) && - (fromMethodInst->mMethodDef->mCallingConvention == toMethodInst->mMethodDef->mCallingConvention) && + (fromMethodInst->mCallingConvention == toMethodInst->mCallingConvention) && (fromMethodInst->mMethodDef->mIsMutating == toMethodInst->mMethodDef->mIsMutating) && (fromMethodInst->mReturnType == toMethodInst->mReturnType) && (fromMethodInst->GetParamCount() == toMethodInst->GetParamCount())) @@ -13706,6 +13735,25 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF str += "delegate "; else str += "function "; + + if (delegateInfo->mCallingConvention != BfCallingConvention_Unspecified) + { + str += "[CallingConvention("; + switch (delegateInfo->mCallingConvention) + { + case BfCallingConvention_Cdecl: + str += ".Cdecl"; + break; + case BfCallingConvention_Stdcall: + str += ".Stdcall"; + break; + case BfCallingConvention_Fastcall: + str += ".Fastcall"; + break; + } + str += ")] "; + } + DoTypeToString(str, delegateInfo->mReturnType, typeNameFlags, genericMethodNameOverrides); str += "("; diff --git a/IDEHelper/Compiler/BfPrinter.cpp b/IDEHelper/Compiler/BfPrinter.cpp index a5e473df..39dcbbce 100644 --- a/IDEHelper/Compiler/BfPrinter.cpp +++ b/IDEHelper/Compiler/BfPrinter.cpp @@ -1585,8 +1585,9 @@ void BfPrinter::Visit(BfDelegateTypeRef* typeRef) VisitChild(typeRef->mTypeToken); ExpectSpace(); - VisitChild(typeRef->mReturnType); VisitChild(typeRef->mAttributes); + ExpectSpace(); + VisitChild(typeRef->mReturnType); VisitChild(typeRef->mOpenParen); for (int i = 0; i < (int)typeRef->mParams.size(); i++) diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index baa65d07..0164aad0 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -281,9 +281,52 @@ bool BfReducer::IsTypeReference(BfAstNode* checkNode, BfToken successToken, int* int endNode = -1; + bool failed = false; + // Return type auto checkNode = mVisitorPos.GetCurrent(); - if ((checkNode == NULL) || (!IsTypeReference(checkNode, BfToken_LParen, &endNode, couldBeExpr, isGenericType, isTuple))) + if (auto checkToken = BfNodeDynCast(checkNode)) + { + if (checkToken->mToken == BfToken_LBracket) + { + while (true) + { + mVisitorPos.mReadPos++; + checkNode = mVisitorPos.GetCurrent(); + if (checkNode == NULL) + { + failed = true; + break; + } + + if (BfNodeIsA(checkNode)) + { + failed = true; + break; + } + + if (checkToken = BfNodeDynCast(checkNode)) + { + if (checkToken->mToken == BfToken_RBracket) + { + mVisitorPos.mReadPos++; + checkNode = mVisitorPos.GetCurrent(); + break; + } + if ((checkToken->mToken != BfToken_Comma) && + (checkToken->mToken != BfToken_Dot) && + (checkToken->mToken != BfToken_LParen) && + (checkToken->mToken != BfToken_RParen)) + { + failed = true; + break; + } + } + } + } + } + + if ((failed) || (checkNode == NULL) || (!IsTypeReference(checkNode, BfToken_LParen, &endNode, couldBeExpr, isGenericType, isTuple))) { if (outEndNode != NULL) *outEndNode = endNode; @@ -4806,6 +4849,14 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF ReplaceNode(firstNode, delegateTypeRef); MEMBER_SET(delegateTypeRef, mTypeToken, tokenNode); + auto nextToken = BfNodeDynCast(mVisitorPos.GetNext()); + if ((nextToken != NULL) && (nextToken->mToken == BfToken_LBracket)) + { + mVisitorPos.MoveNext(); + auto attribs = CreateAttributeDirective(nextToken); + MEMBER_SET_CHECKED(delegateTypeRef, mAttributes, attribs); + } + auto returnType = CreateTypeRefAfter(delegateTypeRef); MEMBER_SET_CHECKED(delegateTypeRef, mReturnType, returnType); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 3e4e49f2..712a7ec5 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -3670,6 +3670,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) BfDelegateInfo* rhsDelegateInfo = rhs->GetDelegateInfo(); if (lhsInst->mTypeDef->mIsDelegate != rhsInst->mTypeDef->mIsDelegate) return false; + if (lhsDelegateInfo->mCallingConvention != rhsDelegateInfo->mCallingConvention) + return false; auto lhsMethodDef = lhsInst->mTypeDef->mMethods[0]; auto rhsMethodDef = rhsInst->mTypeDef->mMethods[0]; @@ -4091,8 +4093,16 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* if ((lhs->IsDelegate()) != rhsIsDelegate) return false; + + BfCallingConvention rhsCallingConvention = BfCallingConvention_Unspecified; + if (ctx->mRootTypeRef == rhsDelegateType) + rhsCallingConvention = ctx->mCallingConvention; + else + ctx->mModule->GetDelegateTypeRefAttributes(rhsDelegateType, rhsCallingConvention); + if (lhsDelegateInfo->mCallingConvention != rhsCallingConvention) + return false; if (!Equals(lhsDelegateInfo->mReturnType, rhsDelegateType->mReturnType, ctx)) - return false; + return false; bool isMutating = true; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index f02f097c..cd59cf14 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -452,6 +452,7 @@ public: Array mParams; bool mHasExplicitThis; bool mHasVarArgs; + BfCallingConvention mCallingConvention; public: BfDelegateInfo() @@ -459,6 +460,7 @@ public: mReturnType = NULL; mHasExplicitThis = false; mHasVarArgs = false; + mCallingConvention = BfCallingConvention_Unspecified; } ~BfDelegateInfo() @@ -1582,7 +1584,9 @@ enum BfAttributeTargets : int32 BfAttributeTargets_Delete = 0x80000, BfAttributeTargets_Alias = 0x100000, BfAttributeTargets_Block = 0x200000, - BfAttributeTargets_All = 0x3FFFFF + BfAttributeTargets_DelegateTypeRef = 0x400000, + BfAttributeTargets_FunctionTypeRef = 0x800000, + BfAttributeTargets_All = 0xFFFFFF }; enum BfAttributeFlags : int8 @@ -2510,6 +2514,7 @@ public: BfType* mRootResolvedType; Dictionary mResolvedTypeMap; BfResolveTypeRefFlags mResolveFlags; + BfCallingConvention mCallingConvention; bool mHadVar; bool mFailed; @@ -2524,6 +2529,7 @@ public: mFailed = false; mHadVar = false; mResolveFlags = BfResolveTypeRefFlag_None; + mCallingConvention = BfCallingConvention_Unspecified; } BfType* GetCachedResolvedType(BfTypeReference* typeReference);