Procházet zdrojové kódy

Fixed CPP mangling for static fields

Brian Fiete před 4 roky
rodič
revize
ca3308d959

+ 86 - 93
IDEHelper/Compiler/BfMangler.cpp

@@ -689,35 +689,13 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
 	MangleContext mangleContext;	
 	mangleContext.mModule = methodInst->GetOwner()->mModule;
 	if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
-		mangleContext.mCCompat = true;	
-	auto customAttributes = methodInst->GetCustomAttributes();
-	if (customAttributes != NULL)
-	{
-		auto linkNameAttr = customAttributes->Get(typeInst->mModule->mCompiler->mLinkNameAttributeTypeDef);
-		if (linkNameAttr != NULL)
-		{
-			if (linkNameAttr->mCtorArgs.size() == 1)
-			{
-				if (typeInst->mModule->TryGetConstString(typeInst->mConstHolder, linkNameAttr->mCtorArgs[0], name))
-					if (!name.IsWhitespace())
-						return name;
-
-				auto constant = typeInst->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
-				if (constant != NULL)
-				{
-					if (constant->mInt32 == 1) // C
-					{
-						name += methodInst->mMethodDef->mName;
-						return name;
-					}
-					else if (constant->mInt32 == 2) // CPP
-					{
-						mangleContext.mCPPMangle = true;
-					}
-				}
-			}
-		}
-	}
+		mangleContext.mCCompat = true;		
+	bool isCMangle = false;	
+	HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
+	if (isCMangle)	
+		name += methodInst->mMethodDef->mName;
+	if (!name.IsEmpty())
+		return name;
 
 	bool mangledMethodIdx = false;
 	bool prefixLen = false;
@@ -1024,13 +1002,14 @@ String BfGNUMangler::MangleMethodName(BfTypeInstance* type, const StringImpl& me
 
 String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName)
 {
+	MangleContext mangleContext;
+	mangleContext.mModule = type->mModule;
+
 	auto typeInst = type->ToTypeInstance();
 	auto typeDef = typeInst->mTypeDef;
 	if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
 		return fieldName;
-
-	MangleContext mangleContext;
-	mangleContext.mModule = type->mModule;
+	
 	StringT<256> name = "_Z";	
 	bool isNameOpen;
 	MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
@@ -1040,6 +1019,33 @@ String BfGNUMangler::MangleStaticFieldName(BfTypeInstance* type, const StringImp
 	return name;
 }
 
+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)
+		name += fieldInstance->GetFieldDef()->mName;
+	if (!name.IsEmpty())
+		return name;
+
+	auto typeInst = fieldInstance->mOwner->ToTypeInstance();
+	auto typeDef = typeInst->mTypeDef;
+	if ((typeDef->IsGlobalsContainer()) && (typeDef->mNamespace.IsEmpty()))
+		return fieldInstance->GetFieldDef()->mName;
+
+	name += "_Z";
+	bool isNameOpen;
+	MangleTypeInst(mangleContext, name, typeInst, NULL, &isNameOpen);
+	AddSizedString(name, fieldInstance->GetFieldDef()->mName);
+	if (isNameOpen)
+		name += "E";
+	return name;
+}
+
 //////////////////////////////////////////////////////////////////////////
 
 BfModule* BfMSMangler::MangleContext::GetUnreifiedModule()
@@ -1790,36 +1796,13 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
 	mangleContext.mModule = methodInst->GetOwner()->mModule;	
 	if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
 		mangleContext.mCCompat = true;
-	auto customAttributes = methodInst->GetCustomAttributes();
-	if (customAttributes != NULL)
-	{
-		auto linkNameAttr = customAttributes->Get(typeInst->mModule->mCompiler->mLinkNameAttributeTypeDef);
-		if (linkNameAttr != NULL)
-		{
-			if (linkNameAttr->mCtorArgs.size() == 1)
-			{				
-				if (typeInst->mModule->TryGetConstString(typeInst->mConstHolder, linkNameAttr->mCtorArgs[0], name))
-					if (!name.IsWhitespace())
-						return;
-
-				auto constant = typeInst->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
-				if (constant != NULL)
-				{
-					if (constant->mInt32 == 1) // C
-					{
-						name += methodInst->mMethodDef->mName;
-						return;
-					}
-					else if (constant->mInt32 == 2) // CPP
-					{
-						mangleContext.mCPPMangle = true;
-						mangleContext.mCCompat = true;
-					}
-				}
-			}
-		}
-	}
-
+	bool isCMangle = false;	
+	HandleCustomAttributes(methodInst->GetCustomAttributes(), typeInst->mConstHolder, mangleContext.mModule, name, isCMangle, mangleContext.mCPPMangle);
+	if (isCMangle)
+		name += methodInst->mMethodDef->mName;
+	if (!name.IsEmpty())
+		return;
+	
 	name += '?';
 
 	if (methodInst->GetNumGenericArguments() != 0)
@@ -2193,6 +2176,13 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfFieldInstance* fieldI
 	MangleContext mangleContext;
 	mangleContext.mIs64Bit = is64Bit;
 	mangleContext.mModule = fieldInstance->mOwner->mModule;	
+
+	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);	
@@ -2266,38 +2256,11 @@ void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstan
 }
 
 void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance)
-{	
-	if (fieldInstance->mCustomAttributes != NULL)
-	{
-		auto module = fieldInstance->mOwner->mModule;
-		auto linkNameAttr = fieldInstance->mCustomAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef);
-		if (linkNameAttr != NULL)
-		{
-			if (linkNameAttr->mCtorArgs.size() == 1)
-			{
-				if (module->TryGetConstString(fieldInstance->mOwner->mConstHolder, linkNameAttr->mCtorArgs[0], outStr))
-					if (!outStr.IsWhitespace())
-						return;
-
-				auto constant = fieldInstance->mOwner->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
-				if (constant != NULL)
-				{
-					if (constant->mInt32 == 1) // C
-					{
-						outStr += fieldInstance->GetFieldDef()->mName;
-						return;
-					}
-					else if (constant->mInt32 == 2) // CPP
-					{
-						//mangleContext.mCPPMangle = true;
-					}
-				}
-			}
-		}
-	}
-
+{		
 	if (mangleKind == BfMangler::MangleKind_GNU)
-		outStr += BfGNUMangler::MangleStaticFieldName(fieldInstance->mOwner, fieldInstance->GetFieldDef()->mName);
+	{		
+		outStr += BfGNUMangler::Mangle(fieldInstance);
+	}
 	else
 		BfMSMangler::Mangle(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, fieldInstance);
 }
@@ -2318,3 +2281,33 @@ void BfMangler::MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind,
 		BfMSMangler::MangleStaticFieldName(outStr, mangleKind == BfMangler::MangleKind_Microsoft_64, type, fieldName, fieldType);
 }
 
+void BfMangler::HandleCustomAttributes(BfCustomAttributes* customAttributes, BfIRConstHolder* constHolder, BfModule* module, StringImpl& name, bool& isCMangle, bool& isCPPMangle)
+{
+	if (customAttributes == NULL)
+		return;
+	
+	auto linkNameAttr = customAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef);
+	if (linkNameAttr != NULL)
+	{
+		if (linkNameAttr->mCtorArgs.size() == 1)
+		{
+			if (module->TryGetConstString(constHolder, linkNameAttr->mCtorArgs[0], name))
+				if (!name.IsWhitespace())
+					return;
+
+			auto constant = constHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
+			if (constant != NULL)
+			{
+				if (constant->mInt32 == 1) // C
+				{					
+					isCMangle = true;
+				}
+				else if (constant->mInt32 == 2) // CPP
+				{
+					isCPPMangle = true;
+				}
+			}
+		}
+	}	
+}
+

+ 4 - 1
IDEHelper/Compiler/BfMangler.h

@@ -8,6 +8,7 @@ NS_BF_BEGIN
 
 class BfType;
 class BfFieldInstance;
+class BfCustomAttributes;
 
 class BfMangler
 {
@@ -83,6 +84,7 @@ public:
 	static void Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance);
 	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);
 };
 
 class BfGNUMangler : public BfMangler
@@ -123,8 +125,9 @@ public:
 
 	static void Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType = NULL);
 	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);
 };
 

+ 4 - 1
IDEHelper/Tests/CLib/main.cpp

@@ -2,12 +2,13 @@
 #include <stdio.h>
 
 namespace Tests
-{
+{	
 	struct Interop
 	{
 		struct StructA
 		{
 			int mA;
+			static int sVal;
 
 			int MethodA0(int arg0)
 			{
@@ -287,6 +288,8 @@ namespace Tests
 			float mX;
 		};
 	};
+
+	int Interop::StructA::sVal = 1234;
 }
 
 using namespace Tests;

+ 5 - 0
IDEHelper/Tests/src/Interop.bf

@@ -9,6 +9,9 @@ namespace Tests
 		{
 			public int32 mA;
 
+			[LinkName(.CPP)]
+			public static extern int32 sVal;
+
 			[LinkName(.CPP)]
 			public extern int32 MethodA0(int32 arg0) mut;
 			[LinkName(.CPP)]
@@ -387,6 +390,8 @@ namespace Tests
 				//Console.WriteLine(str);
 			}
 
+			Test.Assert(StructA.sVal == 1234);
+
 			StartTest("Func0");
 			Test.Assert(Func0(12, 34) == 3412);
 			StartTest("Func0K");