Browse Source

Watch lock fixes, add watch pointee/pointer address

Brian Fiete 3 years ago
parent
commit
eccfabbad2

+ 1 - 1
IDE/src/IDEApp.bf

@@ -4598,7 +4598,7 @@ namespace IDE
 
 
 			            DebuggerUnpaused();
 			            DebuggerUnpaused();
 			        }
 			        }
-			        else
+			        else if (sourceViewPanel != null)
 			        {
 			        {
 						var activePanel = sourceViewPanel.GetActivePanel();
 						var activePanel = sourceViewPanel.GetActivePanel();
 
 

+ 113 - 24
IDE/src/ui/WatchPanel.bf

@@ -44,6 +44,8 @@ namespace IDE.ui
 		public String mStackFrameId ~ delete _;
 		public String mStackFrameId ~ delete _;
 		public bool mWantsStackFrameId;
 		public bool mWantsStackFrameId;
         public String mEvalStr ~ delete _;
         public String mEvalStr ~ delete _;
+		public String mAddrValueExpr ~ delete _;
+		public String mPointeeExpr ~ delete _;
         public bool mCanEdit;
         public bool mCanEdit;
         public String mEditInitialize ~ delete _;
         public String mEditInitialize ~ delete _;
         public bool mHadValue;
         public bool mHadValue;
@@ -2577,6 +2579,8 @@ namespace IDE.ui
 			watch.mLanguage = .NotSet;
 			watch.mLanguage = .NotSet;
             DeleteAndNullify!(watch.mEditInitialize);
             DeleteAndNullify!(watch.mEditInitialize);
 			DeleteAndNullify!(watch.mAction);
 			DeleteAndNullify!(watch.mAction);
+			DeleteAndNullify!(watch.mAddrValueExpr);
+			DeleteAndNullify!(watch.mPointeeExpr);
             watch.mCanEdit = false;
             watch.mCanEdit = false;
 			watch.mAction = null;
 			watch.mAction = null;
 
 
@@ -2764,6 +2768,14 @@ namespace IDE.ui
 						if (int32 stackIdx = int32.Parse(memberVals[1]))
 						if (int32 stackIdx = int32.Parse(memberVals[1]))
 							watch.mCurStackIdx = stackIdx;
 							watch.mCurStackIdx = stackIdx;
 					}
 					}
+					else if (memberVals0 == ":addrValueExpr")
+					{
+						watch.mAddrValueExpr = new .(memberVals[1]);
+					}
+					else if (memberVals0 == ":pointeeExpr")
+					{
+						watch.mPointeeExpr = new .(memberVals[1]);
+					}
 					else
 					else
                         watch.ParseCmd(memberVals);
                         watch.ParseCmd(memberVals);
                     continue;
                     continue;
@@ -2808,7 +2820,7 @@ namespace IDE.ui
 			{
 			{
 				watch.mWantsStackFrameId = false;
 				watch.mWantsStackFrameId = false;
 				watch.mStackFrameId = gApp.mDebugger.GetStackFrameId((watch.mCurStackIdx != -1) ? watch.mCurStackIdx : gApp.mDebugger.mActiveCallStackIdx, .. new .());
 				watch.mStackFrameId = gApp.mDebugger.GetStackFrameId((watch.mCurStackIdx != -1) ? watch.mCurStackIdx : gApp.mDebugger.mActiveCallStackIdx, .. new .());
-				if (gApp.mDebugger.mActiveCallStackIdx != watch.mCurStackIdx)
+				if ((gApp.mDebugger.mActiveCallStackIdx != watch.mCurStackIdx) && (watch.mCurStackIdx != -1))
 					watch.mUsedLock = true;
 					watch.mUsedLock = true;
 			}
 			}
 
 
@@ -3061,7 +3073,7 @@ namespace IDE.ui
             return true;
             return true;
         }
         }
 
 
-		protected static void WithSelectedWatchEntries(WatchListView listView, delegate void(WatchEntry) dlg)
+		protected static void WithSelectedWatchEntries(WatchListView listView, delegate void(WatchEntry watchEntry) dlg)
 		{
 		{
 			listView.GetRoot().WithSelectedItems(scope (item) =>
 			listView.GetRoot().WithSelectedItems(scope (item) =>
 				{
 				{
@@ -3082,28 +3094,12 @@ namespace IDE.ui
 			Menu menu = new Menu();
 			Menu menu = new Menu();
 
 
 			Menu anItem;
 			Menu anItem;
-
-			/*if (listViewItem.mParent != mListView.GetRoot())
-			{
-				anItem = menu.AddItem("Add Watch");
-			}*/
-
 			if (listViewItem != null)
 			if (listViewItem != null)
 			{
 			{
 				var clickedHoverItem = listViewItem.GetSubItem(0) as HoverWatch.HoverListViewItem;
 				var clickedHoverItem = listViewItem.GetSubItem(0) as HoverWatch.HoverListViewItem;
 
 
 				var watchEntry = listViewItem.mWatchEntry;
 				var watchEntry = listViewItem.mWatchEntry;
-				if (listViewItem.mParentItem != listView.GetRoot())
-				{
-					anItem = menu.AddItem("Add Watch");
-					anItem.mOnMenuItemSelected.Add(new (menu) =>
-						{
-							String compactEvalStr = scope String();
-							CompactChildExpression(listViewItem, compactEvalStr);
-							gApp.AddWatch(compactEvalStr);
-						});
-				}
-
+				
 			    AddDisplayTypeMenu("Default Display", menu, listViewItem.mWatchEntry.mResultType, null, false);
 			    AddDisplayTypeMenu("Default Display", menu, listViewItem.mWatchEntry.mResultType, null, false);
 
 
 			    //Debug.WriteLine(String.Format("RefType: {0}", watchEntry.mReferenceId));
 			    //Debug.WriteLine(String.Format("RefType: {0}", watchEntry.mReferenceId));
@@ -3178,11 +3174,95 @@ namespace IDE.ui
 				}
 				}
 
 
 				anItem = menu.AddItem("Add Watch");
 				anItem = menu.AddItem("Add Watch");
-				anItem.mOnMenuItemSelected.Add(new (menu) =>
+				var addWatchNew = anItem.AddItem("Duplicate");
+				addWatchNew.mOnMenuItemSelected.Add(new (menu) =>
 					{
 					{
-						IDEApp.sApp.AddWatch(watchEntry.mEvalStr);
+						List<String> pendingEvalStrs = scope .();
+
+						listView.GetRoot().WithSelectedItems(scope (item) =>
+							{
+								var watchListViewItem = item as WatchListViewItem;
+								if (watchListViewItem.mWatchEntry != null)
+								{
+									if (watchListViewItem.mParentItem != listView.GetRoot())
+									{
+										String compactEvalStr = new String();
+										CompactChildExpression(watchListViewItem, compactEvalStr);
+										pendingEvalStrs.Add(compactEvalStr);
+									}
+									else
+									{
+										pendingEvalStrs.Add(new .(watchEntry.mEvalStr));
+									}
+								}
+							});
+
+						for (var str in pendingEvalStrs)
+						{
+							gApp.AddWatch(str);
+							delete str;
+						}
 					});
 					});
 
 
+				String pointeeExpr = null;
+				String addrValueExpr = null;
+				WithSelectedWatchEntries(listView, scope [&] (selectedWatchEntry) =>
+					{
+						if (selectedWatchEntry.mPointeeExpr != null)
+						{
+							if (pointeeExpr != null)
+								pointeeExpr = "";
+							else
+								pointeeExpr = selectedWatchEntry.mPointeeExpr;
+						}
+						if (selectedWatchEntry.mAddrValueExpr != null)
+						{
+							if (addrValueExpr != null)
+								addrValueExpr = "";
+							else
+								addrValueExpr = selectedWatchEntry.mAddrValueExpr;
+						}	
+					});
+
+
+				if (pointeeExpr != null)
+				{
+					var addWatchPointee = anItem.AddItem(scope $"Pointee Address {pointeeExpr}");
+					addWatchPointee.mOnMenuItemSelected.Add(new (menu) =>
+						{
+							WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
+								{
+									if (selectedWatchEntry.mPointeeExpr != null)
+										gApp.AddWatch(selectedWatchEntry.mPointeeExpr);
+								});
+						});
+
+					if (addrValueExpr != null)
+					{
+						var addWatchPointer = anItem.AddItem(scope $"Pointer Address {addrValueExpr}");
+						addWatchPointer.mOnMenuItemSelected.Add(new (menu) =>
+							{
+								WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
+									{
+										if (selectedWatchEntry.mAddrValueExpr != null)
+											gApp.AddWatch(selectedWatchEntry.mAddrValueExpr);
+									});
+							});
+					}
+				}
+				else if (addrValueExpr != null)
+				{
+					var addValuePointer = anItem.AddItem(scope $"Value Address {addrValueExpr}");
+					addValuePointer.mOnMenuItemSelected.Add(new (menu) =>
+						{
+							WithSelectedWatchEntries(listView, scope (selectedWatchEntry) =>
+								{
+									if (selectedWatchEntry.mAddrValueExpr != null)
+										gApp.AddWatch(selectedWatchEntry.mAddrValueExpr);
+								});
+						});
+				}
+
 				if (!watchEntry.IsConstant)
 				if (!watchEntry.IsConstant)
 				{
 				{
 					anItem = menu.AddItem("Break When Value Changes");
 					anItem = menu.AddItem("Break When Value Changes");
@@ -3192,10 +3272,19 @@ namespace IDE.ui
 							{
 							{
 								String evalStr = scope String();
 								String evalStr = scope String();
 								CompactChildExpression(listViewItem, evalStr);
 								CompactChildExpression(listViewItem, evalStr);
-								if (evalStr.StartsWith("*"))
-									evalStr.Remove(0, 1);
+
+								int valStart = 0;
+								if (evalStr.StartsWith('{'))
+								{
+									int endPos = evalStr.IndexOf('}');
+									valStart = endPos + 1;
+									while ((valStart < evalStr.Length) && (evalStr[valStart].IsWhiteSpace))
+										valStart++;
+								}
+								if ((valStart < evalStr.Length) && (evalStr[valStart] == '*'))
+									evalStr.Remove(valStart, 1);
 								else
 								else
-									evalStr.Insert(0, "&");
+									evalStr.Insert(valStart, "&");
 								gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
 								gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr);
 								gApp.MarkDirty();
 								gApp.MarkDirty();
 							});
 							});

+ 1 - 1
IDEHelper/Compiler/CeDebugger.cpp

@@ -4137,7 +4137,7 @@ void CeDebugger::HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry*
 				if (!valueType->IsPointer())
 				if (!valueType->IsPointer())
 					ptrType = ceModule->CreatePointerType(valueType);
 					ptrType = ceModule->CreatePointerType(valueType);
 				evalStr = StrFormat("(comptype(%d)", ptrType->mTypeId);
 				evalStr = StrFormat("(comptype(%d)", ptrType->mTypeId);
-				evalStr += ")0x{1}";;
+				evalStr += ")0x{1}";
 			}
 			}
 			else
 			else
 			{
 			{

+ 29 - 9
IDEHelper/DbgExprEvaluator.cpp

@@ -970,10 +970,20 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfTypeReference* typeRef)
 
 
 	String name = typeRef->ToString();
 	String name = typeRef->ToString();
 	if (name.StartsWith("_T_"))
 	if (name.StartsWith("_T_"))
-	{		
-		int idx = atoi(name.c_str() + 3);
-		if ((idx >= 0) && (idx < (int)mDbgModule->mTypes.size()))
-			return mDbgModule->mTypes[idx];
+	{
+		auto dbgModule = mDbgModule;
+
+		char* endPtr = NULL;
+		int typeIdx = strtol(name.c_str() + 3, &endPtr, 10);
+		if ((endPtr != NULL) && (*endPtr == '_'))
+		{
+			int moduleIdx = typeIdx;
+			typeIdx = atoi(endPtr + 1);
+			mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule);
+		}
+		
+		if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size()))
+			return dbgModule->mTypes[typeIdx];
 	}
 	}
 
 
 	auto entry = mDbgModule->mTypeMap.Find(name.c_str(), GetLanguage());
 	auto entry = mDbgModule->mTypeMap.Find(name.c_str(), GetLanguage());
@@ -1023,23 +1033,33 @@ DbgType* DbgExprEvaluator::ResolveTypeRef(BfAstNode* typeRef, BfAstNode** parent
 		for (int i = 3; i < (int)name.length(); i++)
 		for (int i = 3; i < (int)name.length(); i++)
 		{
 		{
 			char c = name[i];
 			char c = name[i];
-			if ((c < '0') || (c > '9'))
+			if (((c < '0') || (c > '9')) && (c != '_'))
 			{
 			{
 				endIdx = i;
 				endIdx = i;
 				break;
 				break;
 			}
 			}
 		}
 		}
 
 
-		int idx = atoi(name.c_str() + 3);
-		if ((idx >= 0) && (idx < (int)mDbgModule->mTypes.size()))
+		auto dbgModule = mDbgModule;
+
+		char* endPtr = NULL;
+		int typeIdx = strtol(name.c_str() + 3, &endPtr, 10);
+		if ((endPtr != NULL) && (*endPtr == '_'))
+		{
+			int moduleIdx = typeIdx;
+			typeIdx = atoi(endPtr + 1);
+			mDebugTarget->mDbgModuleMap.TryGetValue(moduleIdx, &dbgModule);
+		}
+		
+		if ((dbgModule != NULL) && (typeIdx >= 0) && (typeIdx < (int)dbgModule->mTypes.size()))
 		{
 		{
 			if ((mExplicitThisExpr != NULL) && (parentChildRef != NULL))
 			if ((mExplicitThisExpr != NULL) && (parentChildRef != NULL))
 				mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(typeRef, parentChildRef, true));
 				mDeferredInsertExplicitThisVector.push_back(NodeReplaceRecord(typeRef, parentChildRef, true));
-			DbgType* dbgType = mDbgModule->mTypes[idx];
+			DbgType* dbgType = dbgModule->mTypes[typeIdx];
 			for (int i = endIdx; i < (int)name.length(); i++)
 			for (int i = endIdx; i < (int)name.length(); i++)
 			{
 			{
 				if (name[i] == '*')
 				if (name[i] == '*')
-					dbgType = mDbgModule->GetPointerType(dbgType);
+					dbgType = dbgModule->GetPointerType(dbgType);
 			}
 			}
 			return dbgType;
 			return dbgType;
 		}
 		}

+ 1 - 1
IDEHelper/DbgModule.cpp

@@ -1547,7 +1547,7 @@ DbgType* DbgType::RemoveModifiers(bool* hadRef)
 String DbgType::ToStringRaw(DbgLanguage language)
 String DbgType::ToStringRaw(DbgLanguage language)
 {
 {
 	if (mTypeIdx != -1)
 	if (mTypeIdx != -1)
-		return StrFormat("_T_%d", mTypeIdx);	
+		return StrFormat("_T_%d_%d", mCompileUnit->mDbgModule->mId, mTypeIdx);	
 	return ToString(language);
 	return ToString(language);
 }
 }
 
 

+ 13 - 6
IDEHelper/DebugTarget.cpp

@@ -33,6 +33,7 @@ DebugTarget::DebugTarget(WinDebugger* debugger)
 	mLastHotHeapCleanIdx = 0;	
 	mLastHotHeapCleanIdx = 0;	
 	mIsEmpty = false;
 	mIsEmpty = false;
 	mWasLocallyBuilt = false;
 	mWasLocallyBuilt = false;
+	mCurModuleId = 0;
 	
 	
 	/*dbgType = new DbgType();
 	/*dbgType = new DbgType();
 	dbgType->mName = "int";
 	dbgType->mName = "int";
@@ -252,9 +253,12 @@ String DebugTarget::UnloadDyn(addr_target imageBase)
 
 
 			if (mTargetBinary == dwarf)
 			if (mTargetBinary == dwarf)
 				mTargetBinary = NULL;
 				mTargetBinary = NULL;
+			
+			mDbgModules.RemoveAt(i);
+			bool success = mDbgModuleMap.Remove(dwarf->mId);
+			BF_ASSERT_REL(success);
 
 
 			delete dwarf;
 			delete dwarf;
-			mDbgModules.erase(mDbgModules.begin() + i);
 			return filePath;
 			return filePath;
 		}
 		}
 	}	
 	}	
@@ -292,9 +296,11 @@ void DebugTarget::CleanupHotHeap()
 		{
 		{
 			DbgModule* dbgModule = mDbgModules[dwarfIdx];
 			DbgModule* dbgModule = mDbgModules[dwarfIdx];
 			if (dbgModule->mDeleting)
 			if (dbgModule->mDeleting)
-			{
+			{				
+				mDbgModules.RemoveAt(dwarfIdx);
+				bool success = mDbgModuleMap.Remove(dbgModule->mId);
+				BF_ASSERT_REL(success);
 				delete dbgModule;
 				delete dbgModule;
-				mDbgModules.erase(mDbgModules.begin() + dwarfIdx);
 				dwarfIdx--;
 				dwarfIdx--;
 			}
 			}
 		}		
 		}		
@@ -906,10 +912,11 @@ void DebugTarget::GetCompilerSettings()
 }
 }
 
 
 void DebugTarget::AddDbgModule(DbgModule* dbgModule)
 void DebugTarget::AddDbgModule(DbgModule* dbgModule)
-{
-	static int id = 0;	
-	dbgModule->mId = ++id;
+{	
+	dbgModule->mId = ++mCurModuleId;
 	mDbgModules.Add(dbgModule);
 	mDbgModules.Add(dbgModule);
+	bool success = mDbgModuleMap.TryAdd(dbgModule->mId, dbgModule);
+	BF_ASSERT_REL(success);
 }
 }
 
 
 #if 1
 #if 1

+ 3 - 1
IDEHelper/DebugTarget.h

@@ -38,7 +38,8 @@ public:
 	String mTargetPath;
 	String mTargetPath;
 	DbgModule* mLaunchBinary;
 	DbgModule* mLaunchBinary;
 	DbgModule* mTargetBinary;	
 	DbgModule* mTargetBinary;	
-	Array<DbgModule*> mDbgModules;	
+	Array<DbgModule*> mDbgModules;
+	Dictionary<int, DbgModule*> mDbgModuleMap;
 	HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
 	HashSet<DbgSrcFile*> mPendingSrcFileRehup; // Waiting to remove old/invalid line info
 	
 	
 	BumpAllocator mAlloc;	
 	BumpAllocator mAlloc;	
@@ -51,6 +52,7 @@ public:
 	bool mBfHasLargeCollections;
 	bool mBfHasLargeCollections;
 	int mBfObjectVDataIntefaceSlotCount;
 	int mBfObjectVDataIntefaceSlotCount;
 	int mBfObjectSize;
 	int mBfObjectSize;
+	int mCurModuleId;
 
 
 	Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors;
 	Array<DwCommonFrameDescriptor*> mCommonFrameDescriptors;
 	std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap;
 	std::map<addr_target, DwFrameDescriptor> mDwFrameDescriptorMap;

+ 51 - 12
IDEHelper/WinDebugger.cpp

@@ -389,6 +389,8 @@ DbgPendingExpr::DbgPendingExpr()
 	mIdleTicks = 0;
 	mIdleTicks = 0;
 	mExplitType = NULL;
 	mExplitType = NULL;
 	mExpressionFlags = DwEvalExpressionFlag_None;
 	mExpressionFlags = DwEvalExpressionFlag_None;
+	mUsedSpecifiedLock = false;
+	mStackIdxOverride = -1;
 }
 }
 
 
 DbgPendingExpr::~DbgPendingExpr()
 DbgPendingExpr::~DbgPendingExpr()
@@ -8727,7 +8729,7 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC
 		}
 		}
 	}			
 	}			
 	else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary)
 	else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_Dictionary)
-	{		
+	{
 		DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo);
 		DbgTypedValue sizeValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mSize, dbgVisWildcardCaptures), &formatInfo);
 		DbgTypedValue entriesPtrValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mEntries, dbgVisWildcardCaptures), &formatInfo);
 		DbgTypedValue entriesPtrValue = EvaluateInContext(dbgCompileUnit, useTypedValue, debugVisualizers->DoStringReplace(debugVis->mEntries, dbgVisWildcardCaptures), &formatInfo);
 
 
@@ -9461,6 +9463,25 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
 		if (exprResult.mIsReadOnly)
 		if (exprResult.mIsReadOnly)
 			canEdit = false;
 			canEdit = false;
 
 
+		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);
+		}
+
+		if (exprResult.mType->IsPointerOrRef())
+		{
+			auto underlyingType = exprResult.mType->mTypeParam;
+			if (underlyingType != NULL)
+			{
+				val += StrFormat("\n:pointeeExpr\t%s(%s%s)", langStr, underlyingType->ToString(pendingExpr->mFormatInfo.mLanguage).c_str(),
+					underlyingType->IsBfObject() ? "" : "*");
+				val += EncodeDataPtr(exprResult.mPtr, true);
+			}
+		}
+
 		if (val[0] == '!')
 		if (val[0] == '!')
 		{
 		{
 			// Already has an error embedded, can't edit
 			// Already has an error embedded, can't edit
@@ -9504,6 +9525,15 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
 	if (pendingExpr->mFormatInfo.mRawString)
 	if (pendingExpr->mFormatInfo.mRawString)
 		return "";
 		return "";
 
 
+	if (val[0] != '!')
+	{
+		if (pendingExpr->mUsedSpecifiedLock)
+			val += "\n:usedLock";
+
+		if (pendingExpr->mStackIdxOverride != -1)
+			val += StrFormat("\n:stackIdx\t%d", pendingExpr->mStackIdxOverride);
+	}
+
 	if (pendingExpr->mCursorPos != -1)	
 	if (pendingExpr->mCursorPos != -1)	
 		val += GetAutocompleteOutput(autoComplete);
 		val += GetAutocompleteOutput(autoComplete);
 	
 	
@@ -9642,8 +9672,10 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
 
 
 	if (terminatedExpr.StartsWith('{'))
 	if (terminatedExpr.StartsWith('{'))
 	{
 	{
+		String locString;
 		int closeIdx = terminatedExpr.IndexOf('}');
 		int closeIdx = terminatedExpr.IndexOf('}');
-		String locString = terminatedExpr.Substring(1, closeIdx - 1);
+		if (closeIdx != -1)
+			locString = terminatedExpr.Substring(1, closeIdx - 1);
 
 
 		for (int i = 0; i <= closeIdx; i++)
 		for (int i = 0; i <= closeIdx; i++)
 			terminatedExpr[i] = ' ';
 			terminatedExpr[i] = ' ';
@@ -9728,7 +9760,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
 											foundLockMatch = true;
 											foundLockMatch = true;
 										}
 										}
 									}
 									}
-								}								
+								}
 							}
 							}
 						}
 						}
 					}
 					}
@@ -9995,6 +10027,8 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
 		return result;
 		return result;
 	}
 	}
 		
 		
+	pendingExpr->mUsedSpecifiedLock = usedSpecifiedLock;
+	pendingExpr->mStackIdxOverride = stackIdxOverride;
 	pendingExpr->mExplitType = explicitType;
 	pendingExpr->mExplitType = explicitType;
 	pendingExpr->mFormatInfo = formatInfo;
 	pendingExpr->mFormatInfo = formatInfo;
 	String result = EvaluateContinue(pendingExpr, bfPassInstance);
 	String result = EvaluateContinue(pendingExpr, bfPassInstance);
@@ -10012,13 +10046,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
 		mActiveThread->mBreakpointAddressContinuing = 0;
 		mActiveThread->mBreakpointAddressContinuing = 0;
 	}
 	}
 	else
 	else
-		delete pendingExpr;
-
-	if ((!formatInfo.mRawString) && (usedSpecifiedLock))
-		result += "\n:usedLock";
-
-	if ((!formatInfo.mRawString) && (stackIdxOverride != -1))
-		result += StrFormat("\n:stackIdx\t%d", stackIdxOverride);
+		delete pendingExpr;	
 
 
 	return result;
 	return result;
 }
 }
@@ -10579,8 +10607,17 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI
 	parser.SetSource(terminatedExpr.c_str(), terminatedExpr.length());
 	parser.SetSource(terminatedExpr.c_str(), terminatedExpr.length());
 	parser.Parse(&bfPassInstance);
 	parser.Parse(&bfPassInstance);
 
 
-	BfParser parentParser(mBfSystem);
 	auto terminatedParentExpr = parentExpr + ";";
 	auto terminatedParentExpr = parentExpr + ";";
+
+	String parentPrefix;
+	if (terminatedParentExpr.StartsWith('{'))
+	{
+		int prefixEnd = terminatedParentExpr.IndexOf('}');
+		parentPrefix = terminatedParentExpr.Substring(0, prefixEnd + 1);
+		terminatedParentExpr.Remove(0, prefixEnd + 1);
+	}
+
+	BfParser parentParser(mBfSystem);	
 	parentParser.mCompatMode = language != DbgLanguage_Beef;
 	parentParser.mCompatMode = language != DbgLanguage_Beef;
 	parentParser.SetSource(terminatedParentExpr.c_str(), terminatedParentExpr.length());
 	parentParser.SetSource(terminatedParentExpr.c_str(), terminatedParentExpr.length());
 	parentParser.Parse(&bfPassInstance);
 	parentParser.Parse(&bfPassInstance);
@@ -10633,7 +10670,9 @@ String WinDebugger::CompactChildExpression(const StringImpl& expr, const StringI
 	printer.mIgnoreTrivia = true;
 	printer.mIgnoreTrivia = true;
 	printer.mReformatting = true;
 	printer.mReformatting = true;
 	printer.VisitChild(headNode);
 	printer.VisitChild(headNode);
-	auto result = printer.mOutString;
+	String result;
+	result += parentPrefix;
+	result += printer.mOutString;
 	if (formatInfo.mNoVisualizers)
 	if (formatInfo.mNoVisualizers)
 		result += ", nv";
 		result += ", nv";
 	if (formatInfo.mNoMembers)
 	if (formatInfo.mNoMembers)

+ 2 - 0
IDEHelper/WinDebugger.h

@@ -288,6 +288,8 @@ public:
 	Array<DbgCallResult> mCallResults;
 	Array<DbgCallResult> mCallResults;
 	int mIdleTicks;
 	int mIdleTicks;
 	String mException;
 	String mException;
+	bool mUsedSpecifiedLock;
+	int mStackIdxOverride;
 
 
 	DbgPendingExpr();
 	DbgPendingExpr();
 	~DbgPendingExpr();
 	~DbgPendingExpr();