diff --git a/BeefLibs/corlib/src/Attribute.bf b/BeefLibs/corlib/src/Attribute.bf index 8b3d9708..21358256 100644 --- a/BeefLibs/corlib/src/Attribute.bf +++ b/BeefLibs/corlib/src/Attribute.bf @@ -206,6 +206,12 @@ namespace System } } + [AttributeUsage(.Parameter | .ReturnValue)] + public struct MangleConstAttribute : Attribute + { + + } + [AttributeUsage(.Method | .Constructor | .Delegate | .Function)] public struct CallingConventionAttribute : Attribute { diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 06c84012..d24d5620 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -2929,8 +2929,7 @@ class BfMethodDeclaration : public BfMemberDeclaration public: BF_AST_TYPE(BfMethodDeclaration, BfMemberDeclaration); - BfCommentNode* mDocumentation; - BfAttributeDirective* mReturnAttributes; + BfCommentNode* mDocumentation; BfTokenNode* mExternSpecifier; BfTokenNode* mVirtualSpecifier; // either 'virtual', 'override', or 'abstract' BfTokenNode* mNewSpecifier; diff --git a/IDEHelper/Compiler/BfElementVisitor.cpp b/IDEHelper/Compiler/BfElementVisitor.cpp index 8655defc..93a00fbc 100644 --- a/IDEHelper/Compiler/BfElementVisitor.cpp +++ b/IDEHelper/Compiler/BfElementVisitor.cpp @@ -999,8 +999,7 @@ void BfElementVisitor::Visit(BfMethodDeclaration* methodDeclaration) VisitChild(methodDeclaration->mProtectionSpecifier); VisitChild(methodDeclaration->mReadOnlySpecifier); VisitChild(methodDeclaration->mStaticSpecifier); - - VisitChild(methodDeclaration->mReturnAttributes); + VisitChild(methodDeclaration->mExternSpecifier); VisitChild(methodDeclaration->mVirtualSpecifier); // either 'virtual', 'override', or 'abstract' VisitChild(methodDeclaration->mNewSpecifier); diff --git a/IDEHelper/Compiler/BfMangler.cpp b/IDEHelper/Compiler/BfMangler.cpp index 0077b5ef..1f09abda 100644 --- a/IDEHelper/Compiler/BfMangler.cpp +++ b/IDEHelper/Compiler/BfMangler.cpp @@ -1452,7 +1452,7 @@ void BfMSMangler::AddPrefix(MangleContext& mangleContext, StringImpl& name, int name.Insert(startIdx, prefix); } -void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList) +void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList, bool isConst) { bool isLongPrim = false; @@ -1612,11 +1612,16 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* auto pointerType = (BfPointerType*)type; const char* strAdd = mangleContext.mIs64Bit ? "PEA" : "PA"; - //if (!FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_Prefix, strAdd, pointerType->mTypeId))) - { - name += strAdd; - Mangle(mangleContext, name, pointerType->mElementType); - } + + if (mangleContext.mIs64Bit) + name += "PE"; + else + name += "P"; + if (isConst) + name += "B"; + else + name += "A"; + Mangle(mangleContext, name, pointerType->mElementType); } else if (type->IsRef()) { @@ -1624,7 +1629,10 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfType* name += "A"; if (mangleContext.mIs64Bit) name += "E"; - name += "A"; + if (isConst) + name += "B"; + else + name += "A"; if (refType->mRefKind == BfRefType::RefKind_Mut) name += "mut$"; else if (refType->mRefKind == BfRefType::RefKind_Out) @@ -1788,6 +1796,7 @@ 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; @@ -2119,8 +2128,12 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho // if (!isSpecialFunc) { + bool isConst = false; + if (methodDeclaration != NULL) + HandleParamCustomAttributes(methodDeclaration->mAttributes, true, isConst); + mangleContext.mInRet = true; - Mangle(mangleContext, name, methodInst->mReturnType); + Mangle(mangleContext, name, methodInst->mReturnType, false, isConst); mangleContext.mInRet = false; } if ((methodInst->mParams.size() == 0) && (!doExplicitThis)) @@ -2139,7 +2152,16 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho Mangle(mangleContext, name, typeInst->GetUnderlyingType(), true); } for (auto& param : methodInst->mParams) - Mangle(mangleContext, name, param.mResolvedType, true); + { + bool isConst = false; + if ((param.mParamDefIdx >= 0) && (methodDeclaration != NULL) && (param.mParamDefIdx < methodDeclaration->mParams.mSize)) + { + auto paramDecl = methodDeclaration->mParams[param.mParamDefIdx]; + HandleParamCustomAttributes(paramDecl->mAttributes, false, isConst); + } + + Mangle(mangleContext, name, param.mResolvedType, true, isConst); + } name += '@'; } @@ -2311,3 +2333,17 @@ void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfI } } +void BfMangler::HandleParamCustomAttributes(BfAttributeDirective* attributes, bool isReturn, bool& isConst) +{ + while (attributes != NULL) + { + if (attributes->mAttributeTypeRef != NULL) + { + auto typeRefName = attributes->mAttributeTypeRef->ToString(); + if (typeRefName == "MangleConst") + isConst = true; + } + + attributes = attributes->mNextAttribute; + } +} diff --git a/IDEHelper/Compiler/BfMangler.h b/IDEHelper/Compiler/BfMangler.h index 8d6fe20b..e6c057a2 100644 --- a/IDEHelper/Compiler/BfMangler.h +++ b/IDEHelper/Compiler/BfMangler.h @@ -85,6 +85,7 @@ public: static void MangleMethodName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& methodName); static void MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType = NULL); static void HandleCustomAttributes(BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfModule* module, StringImpl& name, bool& isCMangle, bool& isCPPMangle); + static void HandleParamCustomAttributes(BfAttributeDirective* attributes, bool isReturn, bool& isConst); }; class BfGNUMangler : public BfMangler @@ -169,7 +170,7 @@ public: 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); + 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); static void MangleConst(MangleContext& mangleContext, StringImpl& name, int64 val); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index df9c878b..0eb3b90e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -6226,15 +6226,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin if (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject)) continue; - if (auto methodDeclaration = methodDef->GetMethodDeclaration()) - { - for (BfParameterDeclaration* paramDecl : methodDeclaration->mParams) - { - if (paramDecl->mAttributes != NULL) - methodReflectKind = (BfReflectKind)(methodReflectKind | _GetReflectUserFromDirective(paramDecl->mAttributes, BfAttributeTargets_Parameter)); + + // + { + SetAndRestoreValue prevTypeInstance(mCurTypeInstance, typeInstance); + if (auto methodDeclaration = methodDef->GetMethodDeclaration()) + { + for (BfParameterDeclaration* paramDecl : methodDeclaration->mParams) + { + if (paramDecl->mAttributes != NULL) + methodReflectKind = (BfReflectKind)(methodReflectKind | _GetReflectUserFromDirective(paramDecl->mAttributes, BfAttributeTargets_Parameter)); + } } - if (methodDeclaration->mReturnAttributes != NULL) - methodReflectKind = (BfReflectKind)(methodReflectKind | _GetReflectUserFromDirective(methodDeclaration->mReturnAttributes, BfAttributeTargets_ReturnValue)); } if ((methodReflectKind & (BfReflectKind_Methods | BfReflectKind_User)) != 0) diff --git a/IDEHelper/Tests/CLib/main.cpp b/IDEHelper/Tests/CLib/main.cpp index c0919d17..09f64ba8 100644 --- a/IDEHelper/Tests/CLib/main.cpp +++ b/IDEHelper/Tests/CLib/main.cpp @@ -21,6 +21,11 @@ namespace Tests ret.mA = mA + other.mA + arg0; return ret; } + + const float& MethodA2(const float& val) + { + return val; + } }; struct StructB @@ -534,6 +539,8 @@ void UseIt() Interop::StructA sa; sa.MethodA0(0); sa.MethodA1(sa, 1); + float f = 123; + sa.MethodA2(f); Interop::StructB sb; sb.MethodB0(0); sb.MethodB1(sb, 1); diff --git a/IDEHelper/Tests/src/Interop.bf b/IDEHelper/Tests/src/Interop.bf index 23ecdd6a..23e153ed 100644 --- a/IDEHelper/Tests/src/Interop.bf +++ b/IDEHelper/Tests/src/Interop.bf @@ -16,6 +16,9 @@ namespace Tests public extern int32 MethodA0(int32 arg0) mut; [LinkName(.CPP)] public extern StructA MethodA1(StructA sa, int32 arg0) mut; + [LinkName(.CPP)] + [return: MangleConst] + public extern ref float MethodA2([MangleConst]ref float val); } [CRepr] @@ -391,6 +394,8 @@ namespace Tests } Test.Assert(StructA.sVal == 1234); + float f = 123; + Test.Assert(sa0.MethodA2(ref f) == 123); StartTest("Func0"); Test.Assert(Func0(12, 34) == 3412);