Browse Source

Mixin name uniquing, 'this' for mixins

Brian Fiete 5 years ago
parent
commit
4d53f185d8

+ 11 - 1
IDE/Tests/Test1/scripts/Mixins.txt

@@ -25,4 +25,14 @@ StepOver()
 
 AssertLineContains("a + 20000")
 StepOver()
-AssertLineContains("a + 30000")
+AssertLineContains("a + 30000")
+
+StepOut()
+StepOver()
+StepInto()
+AssertEvalEquals("mStr.mLength", "6")
+AssertLineContains("a + mStr.Length")
+StepOut()
+StepOver()
+StepInto()
+AssertLineContains("a + b + mStr.Length")

+ 15 - 1
IDE/Tests/Test1/src/Mixins.bf

@@ -8,7 +8,17 @@ namespace IDETest
 	{
 		class ClassA
 		{
-			public String mStr;
+			public String mStr ~ delete _;
+
+			public mixin Zorf(int a)
+			{
+				a + mStr.Length
+			}
+
+			public mixin Zorf(int a, int b)
+			{
+				a + b + mStr.Length
+			}
 		}
 
 		public static mixin MixA(int a)
@@ -40,6 +50,10 @@ namespace IDETest
 			DeleteAndNullify!(ca.mStr);
 			int a = 123;
 			MixC!(1);
+
+			ca.mStr = new String("Zorpie");
+			int val = ca.Zorf!(100);
+			val = ca.Zorf!(200, 300);
 		}
 	}
 }

+ 21 - 0
IDEHelper/COFF.cpp

@@ -4325,6 +4325,27 @@ void COFF::FixupInlinee(DbgSubprogram* dbgSubprogram, uint32 ipiTag)
 			lfMFuncId* funcData = (lfMFuncId*)dataStart;
 			CvParseMethod(NULL, NULL, funcData->type, false, dbgSubprogram);			
 			dbgSubprogram->mName = (const char*)funcData->name;
+
+			if (dbgSubprogram->mName != NULL)
+			{
+				for (const char* cPtr = dbgSubprogram->mName + 1; true; cPtr++)
+				{
+					char c = *cPtr;
+					if (c == 0)
+						break;
+					// For removing the mangled name from the mixins
+					if (c == '?')
+					{
+						int nameLen = cPtr - dbgSubprogram->mName;
+						char* dupStr = (char*)mAlloc.AllocBytes(nameLen + 1);
+						memcpy(dupStr, dbgSubprogram->mName, nameLen);
+						dupStr[nameLen] = 0;
+						dbgSubprogram->mName = dupStr;
+						break;
+					}
+				}
+			}
+
 			FixSubprogramName(dbgSubprogram);
 
 			dbgSubprogram->mParentType = CvGetType(funcData->parentType);

+ 59 - 33
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -13513,7 +13513,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 
 	if (wantsDIData)
 	{		
-		BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(SizedArray<BfIRMDNode, 0>());
+		BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
 
 		//int defLine = mModule->mCurFilePosition.mCurLine;
 		
@@ -13527,7 +13527,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 		auto diParentType = mModule->mBfIRBuilder->DbgGetTypeInst(methodInstance->GetOwner());
 		if (!mModule->mBfIRBuilder->mIgnoreWrites)
 		{
-			curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodDef->mName + "!", "", mModule->mCurFilePosition.mFileInstance->mDIFile,
+			String methodName = methodDef->mName;
+			methodName += "!";						
+			BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance);
+			curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mModule->mCurFilePosition.mFileInstance->mDIFile,
 				defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
 			scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
 		}
@@ -13710,66 +13713,89 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 
 		newLocalVar->mParamIdx = -3;
 	};
-
+	
 	argExprEvaluatorItr = argExprEvaluators.begin();
-	for (int argIdx = 0; argIdx < (int)explicitParamCount; argIdx++)
+	for (int argIdx = methodDef->mIsStatic ? 0 : -1; argIdx < (int)explicitParamCount; argIdx++)
 	{
 		int paramIdx = argIdx;
 
-		auto exprEvaluator = *argExprEvaluatorItr;
-		auto paramDef = methodDef->mParams[paramIdx];
-		auto arg = &args[argIdx];
+		auto exprEvaluator = *argExprEvaluatorItr;		
+
+		BfTypedValue argValue;
+
+		BfLocalVariable* localVar = new BfLocalVariable();		
 
-		if (!arg->mTypedValue)
+		if (argIdx == -1)
 		{
-			auto wantType = methodInstance->GetParamType(paramIdx);
-			if (wantType->IsVar())
-				wantType = mModule->mContext->mBfObjectType;
-			arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
+			argValue = target;
+			localVar->mName = "this";
+			localVar->mIsThis = true;
+			localVar->mIsAssigned = true;
 		}
+		else
+		{
+			auto arg = &args[argIdx];
+			auto paramDef = methodDef->mParams[paramIdx];
 
-		BfLocalVariable* localVar = new BfLocalVariable();		
-		localVar->mName = paramDef->mName;		
-		localVar->mResolvedType = arg->mTypedValue.mType;				
-		if (arg->mTypedValue.mType->IsRef())
+			localVar->mName = paramDef->mName;
+
+			if (!arg->mTypedValue)
+			{
+				auto wantType = methodInstance->GetParamType(paramIdx);
+				if (wantType->IsVar())
+					wantType = mModule->mContext->mBfObjectType;
+				arg->mTypedValue = mModule->GetDefaultTypedValue(wantType);
+			}
+			argValue = arg->mTypedValue;
+		}
+		
+		localVar->mResolvedType = argValue.mType;				
+		if (argValue.mType->IsRef())
 		{
 			auto refType = (BfRefType*)localVar->mResolvedType;
-			localVar->mAddr = mModule->LoadValue(arg->mTypedValue).mValue;
-			localVar->mResolvedType = arg->mTypedValue.mType->GetUnderlyingType();			
+			localVar->mAddr = mModule->LoadValue(argValue).mValue;
+			localVar->mResolvedType = argValue.mType->GetUnderlyingType();
 			localVar->mIsAssigned = refType->mRefKind != BfRefType::RefKind_Out;
 		}
-		else if (arg->mTypedValue.IsAddr())
-			localVar->mAddr = arg->mTypedValue.mValue;
+		else if (argValue.IsAddr())
+			localVar->mAddr = argValue.mValue;
 		else
 		{
-			if (!arg->mTypedValue.mValue)
+			if (!argValue.mValue)
 			{
 				// Untyped value				
 			}
-			else if (arg->mTypedValue.mValue.IsConst())
+			else if (argValue.mValue.IsConst())
 			{
-				localVar->mConstValue = arg->mTypedValue.mValue;
+				localVar->mConstValue = argValue.mValue;
 			}
-			else if (arg->mTypedValue.IsSplat())
+			else if (argValue.IsSplat())
 			{
-				localVar->mValue = arg->mTypedValue.mValue;
+				localVar->mValue = argValue.mValue;
 				localVar->mIsSplat = true;
 			}
 			else
 			{
-				if (arg->mTypedValue.IsAddr())
-					localVar->mAddr = arg->mTypedValue.mValue;
+				if (argValue.IsAddr())
+					localVar->mAddr = argValue.mValue;
 				else
-					localVar->mValue = arg->mTypedValue.mValue;
+					localVar->mValue = argValue.mValue;
 			}
 
-			localVar->mIsReadOnly = arg->mTypedValue.IsReadOnly();
+			localVar->mIsReadOnly = argValue.IsReadOnly();
 		}
 		
-		_AddLocalVariable(localVar, exprEvaluator);
-		
-		endLocalIdx++;
-		++argExprEvaluatorItr;
+		if (argIdx == -1)
+		{
+			_AddLocalVariable(localVar, NULL);
+		}
+		else
+		{
+			_AddLocalVariable(localVar, exprEvaluator);
+
+			endLocalIdx++;
+			++argExprEvaluatorItr;
+		}
 	}
 
 	if (auto blockBody = BfNodeDynCast<BfBlock>(methodDef->mBody))

+ 40 - 32
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -2693,38 +2693,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
 			if (methodDef->mIsOverride)
 				continue;
 
-			llvm::SmallVector<BfIRMDNode, 8> diParams;
-			diParams.push_back(DbgGetType(methodInstance->mReturnType));
-
-			BfType* thisType = NULL;
-			if (!methodDef->mIsStatic)
-			{
-				BfType* thisType;
-				thisType = typeInstance;
-				if (!thisType->IsValuelessType())
-				{
- 					BfType* thisPtrType = thisType; 					
- 					auto diType = DbgGetType(thisPtrType);
-					if ((thisType->IsComposite()) && (!methodInstance->GetParamIsSplat(-1)))
-					{
-						diType = DbgCreatePointerType(diType);
-						diType = DbgCreateArtificialType(diType);
-					}
- 					diParams.push_back(diType);
-				}
-			}
-
-			for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
-			{
-				bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
-				if (!isParamSkipped)
-				{
-					auto resolvedType = methodInstance->GetParamType(paramIdx);
-					diParams.push_back(DbgGetType(resolvedType));
-				}
-			}
-
-			BfIRMDNode diFuncType = DbgCreateSubroutineType(diParams);
+			BfIRMDNode diFuncType = DbgCreateSubroutineType(methodInstance);
 
 			int defLine = 0;
 
@@ -5004,6 +4973,45 @@ BfIRMDNode BfIRBuilder::DbgCreateParameterVariable(BfIRMDNode scope, const Strin
 	return retVal;
 }
 
+BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(BfMethodInstance* methodInstance)
+{
+	auto methodDef = methodInstance->mMethodDef;
+	auto typeInstance = methodInstance->GetOwner();
+
+	llvm::SmallVector<BfIRMDNode, 8> diParams;
+	diParams.push_back(DbgGetType(methodInstance->mReturnType));
+
+	BfType* thisType = NULL;
+	if (!methodDef->mIsStatic)
+	{
+		BfType* thisType;
+		thisType = typeInstance;
+		if (!thisType->IsValuelessType())
+		{
+			BfType* thisPtrType = thisType;
+			auto diType = DbgGetType(thisPtrType);
+			if ((thisType->IsComposite()) && (!methodInstance->GetParamIsSplat(-1)))
+			{
+				diType = DbgCreatePointerType(diType);
+				diType = DbgCreateArtificialType(diType);
+			}
+			diParams.push_back(diType);
+		}
+	}
+
+	for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
+	{
+		bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
+		if (!isParamSkipped)
+		{
+			auto resolvedType = methodInstance->GetParamType(paramIdx);
+			diParams.push_back(DbgGetType(resolvedType));
+		}
+	}
+
+	return DbgCreateSubroutineType(diParams);
+}
+
 BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(const BfSizedArray<BfIRMDNode>& elements)
 {
 	BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSubroutineType, elements);

+ 1 - 0
IDEHelper/Compiler/BfIRBuilder.h

@@ -1252,6 +1252,7 @@ public:
 		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);
+	BfIRMDNode DbgCreateSubroutineType(BfMethodInstance* methodInstance);
 	BfIRMDNode DbgCreateSubroutineType(const BfSizedArray<BfIRMDNode>& elements);
 	BfIRMDNode DbgCreateAutoVariable(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNo, BfIRMDNode type, BfIRInitType initType = BfIRInitType_NotSet);
 	BfIRValue DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo);

+ 29 - 23
IDEHelper/Compiler/BfModule.cpp

@@ -12618,27 +12618,18 @@ void BfModule::DoAddLocalVariable(BfLocalVariable* localVar)
 	}
 }
 
-BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
-{		
-	if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend()))
-	{
-		if ((!localVarDef->mValue.IsConst()) && (!localVarDef->mValue.IsArg()) && (!localVarDef->mValue.IsFake()))
-		{
-			mBfIRBuilder->CreateValueScopeRetain(localVarDef->mValue);
-			mCurMethodState->mCurScope->mHadScopeValueRetain = true;
-		}
-	}
-
-	if ((addDebugInfo) && (mBfIRBuilder->DbgHasInfo()) &&
-        ((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) &&
-        (mHasFullDebugInfo) && 
+void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
+{
+	if ((mBfIRBuilder->DbgHasInfo()) &&
+		((mCurMethodInstance == NULL) || (!mCurMethodInstance->mIsUnspecialized)) &&
+		(mHasFullDebugInfo) &&
 		((mCurMethodState->mClosureState == NULL) || (!mCurMethodState->mClosureState->mCapturing)))
 	{
 		auto varType = localVarDef->mResolvedType;
 
 		if (localVarDef->mResolvedType->IsValuelessType())
 		{
-			
+
 		}
 		else
 		{
@@ -12651,7 +12642,7 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 				diValue = localVarDef->mAddr;
 				isByAddr = true;
 			}
-			
+
 			auto diType = mBfIRBuilder->DbgGetType(localVarDef->mResolvedType);
 			bool didConstToMem = false;
 
@@ -12662,7 +12653,7 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 			else if (localVarDef->mConstValue)
 			{
 				auto constant = mBfIRBuilder->GetConstant(localVarDef->mConstValue);
-				isConstant = 
+				isConstant =
 					(constant->mConstType < BfConstType_GlobalVar) ||
 					(constant->mConstType == BfConstType_AggZero) ||
 					(constant->mConstType == BfConstType_Array);
@@ -12672,9 +12663,9 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 					{
 						mBfIRBuilder->PopulateType(localVarDef->mResolvedType);
 						auto constMem = mBfIRBuilder->ConstToMemory(localVarDef->mConstValue);
-												
+
 						if (IsTargetingBeefBackend())
-						{	
+						{
 							diValue = mBfIRBuilder->CreateAliasValue(constMem);
 							didConstToMem = true;
 
@@ -12698,14 +12689,14 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 
 							mBfIRBuilder->SetInsertPoint(prevBlock);
 							mBfIRBuilder->RestoreDebugLocation();
-						}						
+						}
 					}
 
 					if (mCompiler->mOptions.IsCodeView())
 						diType = mBfIRBuilder->DbgCreateConstType(diType);
-				}				
+				}
 			}
-						
+
 			if (!mBfIRBuilder->mIgnoreWrites)
 			{
 				auto diVariable = mBfIRBuilder->DbgCreateAutoVariable(mCurMethodState->mCurScope->mDIScope,
@@ -12737,9 +12728,24 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
 					}
 				}
 			}
-		}		
+		}
+	}
+}
+
+BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType)
+{		
+	if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend()))
+	{
+		if ((!localVarDef->mValue.IsConst()) && (!localVarDef->mValue.IsArg()) && (!localVarDef->mValue.IsFake()))
+		{
+			mBfIRBuilder->CreateValueScopeRetain(localVarDef->mValue);
+			mCurMethodState->mCurScope->mHadScopeValueRetain = true;
+		}
 	}
 
+	if (addDebugInfo)
+		DoLocalVariableDebugInfo(localVarDef, doAliasValue, declareBefore, initType);
+	
 	localVarDef->mDeclBlock = mBfIRBuilder->GetInsertBlock();
 	DoAddLocalVariable(localVarDef);
 	

+ 1 - 0
IDEHelper/Compiler/BfModule.h

@@ -1647,6 +1647,7 @@ public:
 	bool CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs = NULL, BfError** errorOut = NULL);
 	BfIRValue AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd = true);
 	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);	
 	bool TryLocalVariableInit(BfLocalVariable* localVar);
 	void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);