1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Made callstack aware of outer types vs namespaces. Colorized classview

This commit is contained in:
Brian Fiete 2019-12-11 12:54:50 -08:00
parent 33edbd18bb
commit b3cc0b5be4
9 changed files with 662 additions and 376 deletions

View file

@ -8,6 +8,7 @@ using Beefy.utils;
using Beefy; using Beefy;
using Beefy.gfx; using Beefy.gfx;
using Beefy.theme.dark; using Beefy.theme.dark;
using IDE.ui;
namespace IDE namespace IDE
{ {
@ -288,6 +289,276 @@ namespace IDE
g.Draw(DarkTheme.sDarkTheme.GetImage(.LockIcon), x, y); g.Draw(DarkTheme.sDarkTheme.GetImage(.LockIcon), x, y);
} }
} }
public static void InsertColorChange(String str, int idx, uint32 color)
{
char8* insertChars = scope char8[5]*;
insertChars[0] = (char8)1;
*(uint32*)(insertChars + 1) = (color >> 1) & 0x7F7F7F7F;
str.Insert(idx, scope String(insertChars, 5));
}
public static void ModifyColorChange(String str, int idx, uint32 color)
{
char8* insertPos = str.Ptr + idx;
*(uint32*)(insertPos + 1) = (color >> 1) & 0x7F7F7F7F;
}
public enum CodeKind
{
Callstack,
Method,
Field,
Type
}
public static void ColorizeCodeString(String label, CodeKind codeKind)
{
//int q = 98;
int prevTypeColor = -1;
int prevStart = -1;
bool foundOpenParen = codeKind != .Callstack;
// Check to see if this is just a Mixin name, don't mistake for the bang that separates module name
bool awaitingBang = label.Contains('!') && !label.EndsWith("!");
bool awaitingParamName = false;
int chevronCount = 0;
int parenCount = 0;
int lastTopStart = -1;
int lastTopEnd = -1;
bool inSubtype = false;
bool IsIdentifierChar(char8 c)
{
return (c.IsLetterOrDigit) || (c == '_') || (c == '$') || (c == '@');
}
bool IsIdentifierStart(char8 c)
{
return (c.IsLetter) || (c == '_');
}
for (int32 i = 0; i < label.Length; i++)
{
char8 c = label[i];
if ((c == '0') && (i == 0))
break; // Don't colorize addresses
if ((c == '<') && (i == 0))
{
uint32 color = 0xFFA0A0A0;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, 0, color);
label.Append('\x02');
break;
}
if (awaitingBang)
{
if ((c == ':') || (c == '<'))
{
awaitingBang = false;
i = -1;
continue;
}
if (c == '!')
{
bool endNow = false;
if (i + 1 < label.Length)
{
char16 nextC = label[i + 1];
if ((nextC == '(') || (nextC == '='))
{
awaitingBang = false;
i = -1;
continue;
}
else if ((nextC == '0') || (nextC == '<'))
{
endNow = true; // Just a raw string
}
}
uint32 color = 0xFFA0A0A0;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, 0, color);
awaitingBang = false;
i += 5;
label.Insert(i, '\x02');
if (endNow)
{
InsertColorChange(label, i + 2, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method]);
break;
}
}
}
else if (c == '$')
{
uint32 color = 0xFF80A080;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, i, color);
i += 5;
}
else if (IsIdentifierChar(c))
{
if ((prevStart == -1) && (!awaitingParamName))
prevStart = i;
}
else
{
int setNamespaceIdx = -1;
if ((!inSubtype) && (prevTypeColor != -1))
{
setNamespaceIdx = prevTypeColor;
}
bool isSubtypeSplit = false;
char8 nextC = (i < label.Length - 1) ? label[i + 1] : 0;
// Check for internal '+' subtype encoding
if ((c == '+') && (IsIdentifierStart(nextC)))
{
isSubtypeSplit = true;
inSubtype = true;
label[i] = '.';
}
if (prevStart != -1)
{
//label.Insert(prevStart, SourceEditWidgetContent.sTextColors[(int)SourceElementType.TypeRef]);
/*uint32 color = SourceEditWidgetContent.sTextColors[
inSubtype ? (int32)SourceElementType.TypeRef : (int32)SourceElementType.Namespace
];*/
uint32 color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.TypeRef];
/*if ((c == '+') || (c == '('))
{
foundOpenParen = true;
color = SourceEditWidgetContent.sTextColors[(int)SourceElementType.Method];
}*/
if (chevronCount == 0)
{
lastTopStart = prevStart;
lastTopEnd = i;
}
prevTypeColor = prevStart;
InsertColorChange(label, prevStart, color);
i += 5;
label.Insert(i, '\x02');
prevStart = -1;
awaitingParamName = false;
i++;
}
if (c == ',')
awaitingParamName = false;
if ((c == ')') && (parenCount > 0))
parenCount--;
if ((c != '+') && (c != '.'))
{
inSubtype = false;
prevTypeColor = -1;
}
if ((c == '(') || ((c == '+') && (!isSubtypeSplit)))
setNamespaceIdx = -1;
if (setNamespaceIdx != -1)
ModifyColorChange(label, setNamespaceIdx, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Namespace]);
if (isSubtypeSplit)
{
// Handled
}
else if ((c == '(') && ((i == 0) || (chevronCount > 0)))
{
parenCount++;
}
else if ((c == '(') || (c == '+'))
{
foundOpenParen = true;
if (lastTopStart != -1)
{
char8* insertChars = label.CStr() + lastTopStart;
uint32 color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method];
*(uint32*)(insertChars + 1) = (color >> 1) & 0x7F7F7F7F;
}
else
{
int checkIdx = i - 1;
while (checkIdx > 0)
{
char8 checkC = label[checkIdx];
if (checkC == ':')
{
checkIdx++;
break;
}
checkIdx--;
}
if (checkIdx >= 0)
{
InsertColorChange(label, checkIdx, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method]);
i += 5;
}
}
}
if ((foundOpenParen) && (!awaitingParamName) && (chevronCount == 0))
{
if (c == ' ')
{
bool nextIsName = true;
int32 spaceCount = 0;
for (int32 checkIdx = i + 1; checkIdx < label.Length; checkIdx++)
{
char8 checkC = label[checkIdx];
if (checkC == ' ')
{
spaceCount++;
if (spaceCount > 1)
nextIsName = false;
}
if ((checkC == '<') || (checkC == '*') || (checkC == '['))
nextIsName = false;
if ((checkC == ',') || (checkC == ')'))
{
if (spaceCount > 0)
nextIsName = false;
break;
}
}
if (nextIsName)
awaitingParamName = true;
}
}
}
if (c == '<')
chevronCount++;
else if (c == '>')
chevronCount--;
}
if ((prevStart != -1) && (codeKind == .Type))
{
InsertColorChange(label, prevStart, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Type]);
}
}
} }
} }

View file

@ -47,203 +47,6 @@ namespace IDE.ui
return new CallStackListViewItem(); return new CallStackListViewItem();
} }
static void InsertColorChange(String str, int idx, uint32 color)
{
char8* insertChars = scope char8[5]*;
insertChars[0] = (char8)1;
*(uint32*)(insertChars + 1) = (color >> 1) & 0x7F7F7F7F;
str.Insert(idx, scope String(insertChars, 5));
}
public static void ColorizeLocationString(String label, int line = -1)
{
int prevStart = -1;
bool foundOpenParen = false;
// Check to see if this is just a Mixin name, don't mistake for the bang that separates module name
bool awaitingBang = label.Contains('!') && !label.EndsWith("!");
bool awaitingParamName = false;
int chevronCount = 0;
int parenCount = 0;
int lastTopStart = -1;
int lastTopEnd = -1;
for (int32 i = 0; i < label.Length; i++)
{
char8 c = label[i];
if ((c == '0') && (i == 0))
break; // Don't colorize addresses
if ((c == '<') && (i == 0))
{
uint32 color = 0xFFA0A0A0;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, 0, color);
label.Append('\x02');
break;
}
if (awaitingBang)
{
if ((c == ':') || (c == '<'))
{
awaitingBang = false;
i = -1;
continue;
}
if (c == '!')
{
bool endNow = false;
if (i + 1 < label.Length)
{
char16 nextC = label[i + 1];
if ((nextC == '(') || (nextC == '='))
{
awaitingBang = false;
i = -1;
continue;
}
else if ((nextC == '0') || (nextC == '<'))
{
endNow = true; // Just a raw string
}
}
uint32 color = 0xFFA0A0A0;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, 0, color);
awaitingBang = false;
i += 5;
label.Insert(i, '\x02');
if (endNow)
{
InsertColorChange(label, i + 2, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method]);
break;
}
}
}
else if (c == '$')
{
uint32 color = 0xFF80A080;//SourceEditWidgetContent.sTextColors[(int)SourceElementType.Comment];
InsertColorChange(label, i, color);
i += 5;
}
else if ((c.IsLetterOrDigit) || (c == '_') || (c == '$') || (c == '@') /*|| (c == '>') || (c == '<') || (c == ':') || (c == '[') || (c == ']')*/)
{
if ((prevStart == -1) && (!awaitingParamName))
prevStart = i;
}
else
{
if (prevStart != -1)
{
//label.Insert(prevStart, SourceEditWidgetContent.sTextColors[(int)SourceElementType.TypeRef]);
uint32 color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.TypeRef];
/*if ((c == '+') || (c == '('))
{
foundOpenParen = true;
color = SourceEditWidgetContent.sTextColors[(int)SourceElementType.Method];
}*/
if (chevronCount == 0)
{
lastTopStart = prevStart;
lastTopEnd = i;
}
InsertColorChange(label, prevStart, color);
i += 5;
label.Insert(i, '\x02');
prevStart = -1;
awaitingParamName = false;
i++;
}
if (c == ',')
awaitingParamName = false;
if ((c == ')') && (parenCount > 0))
parenCount--;
if ((c == '(') && ((i == 0) || (chevronCount > 0)))
{
parenCount++;
}
else if ((c == '(') || (c == '+'))
{
foundOpenParen = true;
if (lastTopStart != -1)
{
char8* insertChars = label.CStr() + lastTopStart;
uint32 color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method];
*(uint32*)(insertChars + 1) = (color >> 1) & 0x7F7F7F7F;
}
else
{
int checkIdx = i - 1;
while (checkIdx > 0)
{
char8 checkC = label[checkIdx];
if (checkC == ':')
{
checkIdx++;
break;
}
checkIdx--;
}
if (checkIdx >= 0)
{
InsertColorChange(label, checkIdx, SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Method]);
i += 5;
}
}
}
if ((foundOpenParen) && (!awaitingParamName) && (chevronCount == 0))
{
if (c == ' ')
{
bool nextIsName = true;
int32 spaceCount = 0;
for (int32 checkIdx = i + 1; checkIdx < label.Length; checkIdx++)
{
char8 checkC = label[checkIdx];
if (checkC == ' ')
{
spaceCount++;
if (spaceCount > 1)
nextIsName = false;
}
if ((checkC == '<') || (checkC == '*') || (checkC == '['))
nextIsName = false;
if ((checkC == ',') || (checkC == ')'))
{
if (spaceCount > 0)
nextIsName = false;
break;
}
}
if (nextIsName)
awaitingParamName = true;
}
}
}
if (c == '<')
chevronCount++;
else if (c == '>')
chevronCount--;
}
if (line != -1)
label.AppendF(" Line {0}", (int32)(line + 1));
}
public override void PopulateVirtualItem(DarkVirtualListViewItem listViewItem) public override void PopulateVirtualItem(DarkVirtualListViewItem listViewItem)
{ {
base.PopulateVirtualItem(listViewItem); base.PopulateVirtualItem(listViewItem);
@ -267,7 +70,10 @@ namespace IDE.ui
String label = scope String(256); String label = scope String(256);
DebugManager.FrameFlags frameFlags; DebugManager.FrameFlags frameFlags;
gApp.mDebugger.GetStackFrameInfo(listViewItem.mVirtualIdx, label, out addr, file, out hotIdx, out defLineStart, out defLineEnd, out line, out column, out language, out stackSize, out frameFlags); gApp.mDebugger.GetStackFrameInfo(listViewItem.mVirtualIdx, label, out addr, file, out hotIdx, out defLineStart, out defLineEnd, out line, out column, out language, out stackSize, out frameFlags);
ColorizeLocationString(label, line); IDEUtils.ColorizeCodeString(label, .Callstack);
if (line != -1)
label.AppendF(" Line {0}", (int32)(line + 1));
listViewItem.Label = label; listViewItem.Label = label;

View file

@ -19,6 +19,7 @@ namespace IDE.ui
public Object mRefObject; public Object mRefObject;
public DataKind mKind; public DataKind mKind;
public PendingEntry mMemberInfo ~ delete _; public PendingEntry mMemberInfo ~ delete _;
public bool mProcessedLabel;
protected override float GetLabelOffset() protected override float GetLabelOffset()
{ {
@ -44,7 +45,36 @@ namespace IDE.ui
public override void Draw(Graphics g) public override void Draw(Graphics g)
{ {
if ((!mProcessedLabel) && (mLabel != null))
{
uint32 color = 0;
switch (mMemberInfo.mKind)
{
case .Globals:
/*color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Identifier];
color = Color.Mult(color, Color.Get(0.8f));*/
case .Namespace:
color = SourceEditWidgetContent.sTextColors[(int32)SourceElementType.Namespace];
case .Interface,
.Class,
.ValueType:
IDEUtils.ColorizeCodeString(mLabel, .Type);
case .Field,
.Property:
IDEUtils.ColorizeCodeString(mLabel, .Field);
case .Method:
IDEUtils.ColorizeCodeString(mLabel, .Method);
default:
}
if (color != 0)
IDEUtils.InsertColorChange(mLabel, 0, color);
mProcessedLabel = true;
}
base.Draw(g); base.Draw(g);
if (mRefObject != null) if (mRefObject != null)
{ {
bool hasChanged = false; bool hasChanged = false;
@ -203,8 +233,13 @@ namespace IDE.ui
{ {
if (((Object)val1 == null) || ((Object)val2 == null)) if (((Object)val1 == null) || ((Object)val2 == null))
return ((Object)val1 == null) && ((Object)val2 == null); return ((Object)val1 == null) && ((Object)val2 == null);
if ((val1.mKind != val2.mKind) && ((val1.mKind != .Namespace) && (val2.mKind != .Namespace))) if (val1.mKind != val2.mKind)
return false; {
if ((val1.mKind == .Project) || (val2.mKind == .Project))
return false;
if ((val1.mKind != .Namespace) && (val2.mKind != .Namespace))
return false;
}
return (val1.mName == val2.mName); return (val1.mName == val2.mName);
} }
@ -598,6 +633,8 @@ namespace IDE.ui
List<PendingEntry> partialRefs = scope List<PendingEntry>(); List<PendingEntry> partialRefs = scope List<PendingEntry>();
char8[] seps = scope char8[] ('.', '+');
for (var subStrRef in str.Split('\n')) for (var subStrRef in str.Split('\n'))
{ {
String param = scope String(); String param = scope String();
@ -656,6 +693,8 @@ namespace IDE.ui
kind = .Interface; kind = .Interface;
else if (cmd == 'c') else if (cmd == 'c')
kind = .Class; kind = .Class;
else if (cmd == 'g')
kind = .Globals;
if (parentEntry != null) if (parentEntry != null)
{ {
@ -677,7 +716,7 @@ namespace IDE.ui
} }
int nameIdx = 0; int nameIdx = 0;
for (var subName in param.Split('.')) for (var subName in param.Split(seps))
{ {
if (nameIdx < addIdx) if (nameIdx < addIdx)
{ {
@ -687,10 +726,13 @@ namespace IDE.ui
String subNameStr = scope String(); String subNameStr = scope String();
bool isLast = subName.Ptr + subName.Length == param.Ptr + param.Length;
if (nameIdx == addIdx) if (nameIdx == addIdx)
{ {
DataKind insertKind = isLast ? kind : .Namespace;
subNameStr.Reference(StringView(param, 0, @subName.MatchPos)); subNameStr.Reference(StringView(param, 0, @subName.MatchPos));
curEntry = mPendingInfo.mPendingRoot.AddChild(kind, subNameStr); curEntry = mPendingInfo.mPendingRoot.AddChild(insertKind, subNameStr);
curEntry.mParent = curProject; curEntry.mParent = curProject;
Debug.Assert(curProject != (Object)curEntry); Debug.Assert(curProject != (Object)curEntry);
partialRefs.Add(curEntry); partialRefs.Add(curEntry);
@ -700,7 +742,6 @@ namespace IDE.ui
} }
DataKind insertKind = kind; DataKind insertKind = kind;
bool isLast = subName.Ptr + subName.Length == param.Ptr + param.Length;
if (!isLast) if (!isLast)
{ {
char8 nextChar = subName.Ptr[subName.Length]; char8 nextChar = subName.Ptr[subName.Length];
@ -803,6 +844,7 @@ namespace IDE.ui
childListViewItem.mRefObject = pendingEntry.mRefObject; childListViewItem.mRefObject = pendingEntry.mRefObject;
childListViewItem.mOpenOnDoubleClick = false; childListViewItem.mOpenOnDoubleClick = false;
childListViewItem.mKind = child.mKind; childListViewItem.mKind = child.mKind;
childListViewItem.mProcessedLabel = false;
DeleteAndNullify!(childListViewItem.mMemberInfo); DeleteAndNullify!(childListViewItem.mMemberInfo);
//if (child.mFile != null) //if (child.mFile != null)
{ {
@ -940,7 +982,10 @@ namespace IDE.ui
if (mWorkWait == -1) if (mWorkWait == -1)
{ {
if (mWantsSubmit) if (mWantsSubmit)
{
mTypeLV.KeyDown(.Return, false); mTypeLV.KeyDown(.Return, false);
mWantsSubmit = false;
}
} }
} }

View file

@ -447,7 +447,7 @@ namespace IDE.ui
subItem = (ThreadListViewItem)listViewItem.CreateSubItem(2); subItem = (ThreadListViewItem)listViewItem.CreateSubItem(2);
label.Clear(); label.Clear();
label.Append(elementData[2]); label.Append(elementData[2]);
CallStackListView.ColorizeLocationString(label); IDEUtils.ColorizeCodeString(label, .Callstack);
subItem.Label = label; subItem.Label = label;
subItem.mOnMouseDown.Add(new => ValueClicked); subItem.mOnMouseDown.Add(new => ValueClicked);

View file

@ -892,6 +892,14 @@ BfSourceData* BfAstNode::GetSourceData()
#endif #endif
} }
BfParserData* BfAstNode::GetParserData()
{
BfSourceData* sourceData = GetSourceData();
if (sourceData == NULL)
return NULL;
return sourceData->ToParserData();
}
BfParser* BfAstNode::GetParser() BfParser* BfAstNode::GetParser()
{ {
BfSourceData* sourceData = GetSourceData(); BfSourceData* sourceData = GetSourceData();

View file

@ -1025,6 +1025,7 @@ public:
bool IsTemporary(); bool IsTemporary();
int GetStartCharId(); int GetStartCharId();
BfSourceData* GetSourceData(); BfSourceData* GetSourceData();
BfParserData* GetParserData();
BfParser* GetParser(); BfParser* GetParser();
bool IsFromParser(BfParser* parser); bool IsFromParser(BfParser* parser);
String ToString(); String ToString();

View file

@ -389,15 +389,13 @@ NS_BF_DBG_END
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
String DbgSubprogram::ToString() void DbgSubprogram::ToString(StringImpl& str, bool internalName)
{ {
if ((mInlineeInfo != NULL) && (mInlineeInfo->mInlineeId != 0)) if ((mInlineeInfo != NULL) && (mInlineeInfo->mInlineeId != 0))
mCompileUnit->mDbgModule->FixupInlinee(this); mCompileUnit->mDbgModule->FixupInlinee(this);
PopulateSubprogram(); PopulateSubprogram();
String str;
if (mCheckedKind == BfCheckedKind_Checked) if (mCheckedKind == BfCheckedKind_Checked)
str += "[Checked] "; str += "[Checked] ";
else if (mCheckedKind == BfCheckedKind_Unchecked) else if (mCheckedKind == BfCheckedKind_Unchecked)
@ -407,14 +405,17 @@ String DbgSubprogram::ToString()
if (mName == NULL) if (mName == NULL)
{ {
if (mLinkName[0] == '<') if (mLinkName[0] == '<')
return mLinkName; {
str += mLinkName;
return;
}
str = BfDemangler::Demangle(StringImpl::MakeRef(mLinkName), language); str = BfDemangler::Demangle(StringImpl::MakeRef(mLinkName), language);
// Strip off the params since we need to generate those ourselves // Strip off the params since we need to generate those ourselves
int parenPos = (int)str.IndexOf('('); int parenPos = (int)str.IndexOf('(');
if (parenPos != -1) if (parenPos != -1)
str = str.Substring(0, parenPos); str = str.Substring(0, parenPos);
} }
else if (mHasQualifiedName) else if ((mHasQualifiedName) && (!internalName))
{ {
const char* cPtr = mName; const char* cPtr = mName;
if (strncmp(cPtr, "_bf::", 5) == 0) if (strncmp(cPtr, "_bf::", 5) == 0)
@ -461,7 +462,7 @@ String DbgSubprogram::ToString()
{ {
if (mParentType != NULL) if (mParentType != NULL)
{ {
str += mParentType->ToString(); mParentType->ToString(str, language, true, internalName);
if (!str.empty()) if (!str.empty())
{ {
if (language == DbgLanguage_Beef) if (language == DbgLanguage_Beef)
@ -471,35 +472,51 @@ String DbgSubprogram::ToString()
} }
} }
if ((language == DbgLanguage_Beef) && (mParentType != NULL) && (mParentType->mTypeName != NULL) && (strcmp(mName, mParentType->mTypeName) == 0)) const char* name = mName;
if (mHasQualifiedName)
{
const char* cPtr = name;
for (; true; cPtr++)
{
char c = *cPtr;
if (c == 0)
break;
if ((c == ':') && (cPtr[1] == ':'))
{
name = cPtr + 2;
}
}
}
if ((language == DbgLanguage_Beef) && (mParentType != NULL) && (mParentType->mTypeName != NULL) && (strcmp(name, mParentType->mTypeName) == 0))
str += "this"; str += "this";
else if ((language == DbgLanguage_Beef) && (mName[0] == '~')) else if ((language == DbgLanguage_Beef) && (name[0] == '~'))
str += "~this"; str += "~this";
else if (strncmp(mName, "_bf::", 5) == 0) else if (strncmp(name, "_bf::", 5) == 0)
str += mName + 5; str += name + 5;
else else
{ {
bool handled = false; bool handled = false;
if ((language == DbgLanguage_Beef) && (mName[0] == '_')) if ((language == DbgLanguage_Beef) && (name[0] == '_'))
{ {
if (strcmp(mName, "__BfCtor") == 0) if (strcmp(name, "__BfCtor") == 0)
{ {
str += "this"; str += "this";
handled = true; handled = true;
} }
else if (strcmp(mName, "__BfStaticCtor") == 0) else if (strcmp(name, "__BfStaticCtor") == 0)
{ {
str += "this"; str += "this";
handled = true; handled = true;
} }
else if (strcmp(mName, "__BfCtorClear") == 0) else if (strcmp(name, "__BfCtorClear") == 0)
{ {
str += "this$clear"; str += "this$clear";
handled = true; handled = true;
} }
} }
if (!handled) if (!handled)
str += mName; str += name;
} }
} }
@ -538,7 +555,7 @@ String DbgSubprogram::ToString()
BF_ASSERT(varType->IsPointer()); BF_ASSERT(varType->IsPointer());
varType = varType->mTypeParam; varType = varType->mTypeParam;
} }
str += varType->ToString(language); varType->ToString(str, language, false, internalName);
if (variable->mName != NULL) if (variable->mName != NULL)
str += " "; str += " ";
} }
@ -548,6 +565,12 @@ String DbgSubprogram::ToString()
i++; i++;
} }
str += ")"; str += ")";
}
String DbgSubprogram::ToString()
{
String str;
ToString(str, false);
return str; return str;
} }
@ -1503,7 +1526,7 @@ String DbgType::ToStringRaw(DbgLanguage language)
return ToString(language); return ToString(language);
} }
String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject) void DbgType::ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName)
{ {
if (language == DbgLanguage_Unknown) if (language == DbgLanguage_Unknown)
language = GetLanguage(); language = GetLanguage();
@ -1513,27 +1536,38 @@ String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject)
switch (mTypeCode) switch (mTypeCode)
{ {
case DbgType_UChar: case DbgType_UChar:
return "char8"; str += "char8";
return;
case DbgType_UChar16: case DbgType_UChar16:
return "char16"; str += "char16";
return;
case DbgType_UChar32: case DbgType_UChar32:
return "char32"; str += "char32";
return;
case DbgType_i8: case DbgType_i8:
return "int8"; str += "int8";
return;
case DbgType_u8: case DbgType_u8:
return "uint8"; str += "uint8";
return;
case DbgType_i16: case DbgType_i16:
return "int16"; str += "int16";
return;
case DbgType_u16: case DbgType_u16:
return "uint16"; str += "uint16";
return;
case DbgType_i32: case DbgType_i32:
return "int32"; str += "int32";
return;
case DbgType_u32: case DbgType_u32:
return "uint32"; str += "uint32";
return;
case DbgType_i64: case DbgType_i64:
return "int64"; str += "int64";
return;
case DbgType_u64: case DbgType_u64:
return "uint64"; str += "uint64";
return;
} }
} }
else else
@ -1541,50 +1575,78 @@ String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject)
switch (mTypeCode) switch (mTypeCode)
{ {
case DbgType_SChar: case DbgType_SChar:
return "char"; str += "char";
return;
case DbgType_SChar16: case DbgType_SChar16:
return "wchar_t"; str += "wchar_t";
return;
case DbgType_SChar32: case DbgType_SChar32:
return "int32_t"; str += "int32_t";
return;
case DbgType_UChar: case DbgType_UChar:
return "uint8_t"; str += "uint8_t";
return;
case DbgType_UChar16: case DbgType_UChar16:
return "uint16_t"; str += "uint16_t";
return;
case DbgType_UChar32: case DbgType_UChar32:
return "uint32_t"; str += "uint32_t";
return;
case DbgType_i8: case DbgType_i8:
return "char"; str += "char";
return;
case DbgType_u8: case DbgType_u8:
return "uint8_t"; str += "uint8_t";
return;
case DbgType_i16: case DbgType_i16:
return "short"; str += "short";
return;
case DbgType_u16: case DbgType_u16:
return "uint16_t"; str += "uint16_t";
return;
case DbgType_i32: case DbgType_i32:
return "int"; str += "int";
return;
case DbgType_u32: case DbgType_u32:
return "uint32_t"; str += "uint32_t";
return;
case DbgType_i64: case DbgType_i64:
return "int64_t"; str += "int64_t";
return;
case DbgType_u64: case DbgType_u64:
return "uint64_t"; str += "uint64_t";
return;
} }
} }
if (mTypeCode == DbgType_Namespace)
internalName = false;
auto parent = mParent;
if ((parent == NULL) && (internalName))
{
auto primaryType = GetPrimaryType();
parent = primaryType->mParent;
}
if (mTypeName != NULL) if (mTypeName != NULL)
{ {
if ((!allowDirectBfObject) && (IsBfObject())) if ((!allowDirectBfObject) && (IsBfObject()))
{ {
// Only use the '#' for testing // Only use the '#' for testing
//return ToString(true) + "#"; //return ToString(true) + "#";
return ToString(DbgLanguage_Unknown, true); ToString(str, DbgLanguage_Unknown, true, internalName);
return;
} }
if (IsGlobalsContainer()) if (IsGlobalsContainer())
{ {
if (mParent != NULL) if (mParent != NULL)
return mParent->ToString(language); {
return ""; mParent->ToString(str, language, false, internalName);
return;
}
return;
} }
char* nameP = (char*)mTypeName; char* nameP = (char*)mTypeName;
@ -1601,180 +1663,269 @@ String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject)
FixName(); FixName();
} }
if (mParent == NULL) if (parent == NULL)
{ {
if (strncmp(nameP, "Box<", 4) == 0) if (strncmp(nameP, "Box<", 4) == 0)
return String(nameP + 4, nameP + strlen(nameP) - 1) + "^"; {
str += String(nameP + 4, nameP + strlen(nameP) - 1);
str += "^";
return;
}
// For declarations, may also include namespaces // For declarations, may also include namespaces
return mName; str += mName;
return;
} }
if (GetLanguage() == DbgLanguage_Beef) if (GetLanguage() == DbgLanguage_Beef)
return mParent->ToString(language) + "." + nameP; {
parent->ToString(str, language, allowDirectBfObject, internalName);
if ((internalName) && (parent->mTypeCode != DbgType_Namespace))
str += "+";
else
str += ".";
str += nameP;
}
else else
return mParent->ToString(language) + "::" + nameP; {
parent->ToString(str, language, allowDirectBfObject, internalName);
if ((internalName) && (parent->mTypeCode != DbgType_Namespace))
str += "+";
else
str += "::";
str += nameP;
}
return;
} }
switch (mTypeCode) switch (mTypeCode)
{ {
case DbgType_Struct: case DbgType_Struct:
{
if ((mTypeName == NULL) && (parent != NULL))
{ {
if ((mTypeName == NULL) && (mParent != NULL)) parent->ToString(str, language, allowDirectBfObject, internalName);
return mParent->ToString(language); return;
return "@struct";
} }
str += "@struct";
return;
}
case DbgType_Class: case DbgType_Class:
{ {
return "@class"; str += "@class";
} return;
}
case DbgType_TypeDef: case DbgType_TypeDef:
{ {
return "@typedef"; str += "@typedef";
} return;
}
case DbgType_Const: case DbgType_Const:
{
if (language == DbgLanguage_Beef)
{ {
if (language == DbgLanguage_Beef) str += "readonly";
if (mTypeParam != NULL)
{ {
if (mTypeParam == NULL) str += " ";
return "readonly"; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "readonly " + mTypeParam->ToString(language);
} }
return;
if (mTypeParam == NULL)
return "const";
return "const " + mTypeParam->ToString(language);
} }
str += "const";
if (mTypeParam != NULL)
{
str += " ";
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
}
return;
}
case DbgType_Volatile: case DbgType_Volatile:
{
str += "volatile";
if (mTypeParam != NULL)
{ {
if (mTypeParam == NULL) str += " ";
return "volatile"; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "volatile " + mTypeParam->ToString(language);
} }
return;
}
case DbgType_Unaligned: case DbgType_Unaligned:
{
str += "unaligned";
if (mTypeParam != NULL)
{ {
if (mTypeParam == NULL) str += " ";
return "unaligned"; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "unaligned " + mTypeParam->ToString(language);
} }
}
case DbgType_Restrict: case DbgType_Restrict:
{
str += "restrict";
if (mTypeParam != NULL)
{ {
if (mTypeParam == NULL) str += " ";
return "restrict"; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "restrict " + mTypeParam->ToString(language);
} }
}
case DbgType_Ptr: case DbgType_Ptr:
{
if (mTypeParam == NULL)
{ {
if (mTypeParam == NULL) str += "void*";
return "void*"; return;
if (mTypeParam->IsBfObject())
return mTypeParam->ToString(DbgLanguage_Unknown, true);
// Don't put a "*" on the end of a function type, it's implicit
if (mTypeParam->mTypeCode == DbgType_Subroutine)
return mTypeParam->ToString(language);
return mTypeParam->ToString(language) + "*";
} }
if (mTypeParam->IsBfObject())
{
mTypeParam->ToString(str, DbgLanguage_Unknown, true, internalName);
return;
}
// Don't put a "*" on the end of a function type, it's implicit
if (mTypeParam->mTypeCode == DbgType_Subroutine)
{
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return;
}
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
str += "*";
return;
}
case DbgType_Ref: case DbgType_Ref:
{
if (language == DbgLanguage_Beef)
{ {
if (language == DbgLanguage_Beef) str += "ref";
if (mTypeParam != NULL)
{ {
if (mTypeParam == NULL) str += " ";
return "ref"; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "ref " + mTypeParam->ToString(language);
} }
if (mTypeParam == NULL)
return "&";
return mTypeParam->ToString(language) + "&";
} }
if (mTypeParam == NULL)
{
str += "&";
return;
}
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
str += "&";
return;
}
case DbgType_RValueReference: case DbgType_RValueReference:
{
if (language == DbgLanguage_Beef)
{ {
if (language == DbgLanguage_Beef) // Ignore this - this is used for passing structs when we're not using the 'byval' attribute
{ mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
// Ignore this - this is used for passing structs when we're not using the 'byval' attribute return;
return mTypeParam->ToString(language);
}
if (mTypeParam == NULL)
return "&&";
return mTypeParam->ToString(language) + "&&";
} }
if (mTypeParam == NULL)
{
str += "&&";
return;
}
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
str += "&&";
return;
}
case DbgType_Unspecified: case DbgType_Unspecified:
return mTypeName; str += mTypeName;
return;
case DbgType_SizedArray: case DbgType_SizedArray:
{
StringT<128> name;
auto checkType = this;
while (checkType->mTypeCode == DbgType_SizedArray)
{ {
String name; intptr innerSize = checkType->mTypeParam->GetStride();
auto checkType = this; intptr arrSize = 0;
while (checkType->mTypeCode == DbgType_SizedArray) if (innerSize > 0)
{ {
intptr innerSize = checkType->mTypeParam->GetStride(); arrSize = checkType->GetStride() / innerSize;
intptr arrSize = 0;
if (innerSize > 0)
{
arrSize = checkType->GetStride() / innerSize;
}
name += StrFormat("[%lld]", arrSize);
checkType = checkType->mTypeParam;
} }
name = checkType->ToString(language) + name; name += StrFormat("[%lld]", arrSize);
checkType = checkType->mTypeParam;
return name;
} }
checkType->ToString(str, language, allowDirectBfObject, internalName);
str += name;
return;
}
case DbgType_Union: case DbgType_Union:
{
str += "union";
if (mTypeParam != NULL)
{ {
if (mTypeName != NULL) str += " ";
return String("union ") + mTypeName; mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
return "union";
} }
return;
}
case DbgType_Single: case DbgType_Single:
return "float"; str += "float";
return;
case DbgType_Double: case DbgType_Double:
return "double"; str += "double";
return;
case DbgType_Null: case DbgType_Null:
return "void"; str += "void";
return;
case DbgType_Subroutine: case DbgType_Subroutine:
{
mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
str += " (";
int paramIdx = 0;
for (auto param : mBlockParam->mVariables)
{ {
String str; if (paramIdx > 0)
str += mTypeParam->ToString(language); str += ", ";
str += " ("; param->mType->ToString(str, language, allowDirectBfObject, internalName);
int paramIdx = 0; paramIdx++;
for (auto param : mBlockParam->mVariables)
{
if (paramIdx > 0)
str += ", ";
str += param->mType->ToString(language);
paramIdx++;
}
str += ")";
return str;
} }
str += ")";
return;
}
case DbgType_VTable: case DbgType_VTable:
return "@vtable"; str += "@vtable";
return;
case DbgType_Enum: case DbgType_Enum:
return "@enum"; str += "@enum";
return;
case DbgType_Namespace: case DbgType_Namespace:
{ {
// Anonymous // Anonymous
return "`anon`"; str += "`anon`";
} return;
}
case DbgType_PtrToMember: case DbgType_PtrToMember:
return "@ptrToMember"; str += "@ptrToMember";
return;
case DbgType_Bitfield: case DbgType_Bitfield:
{ {
auto dbgBitfieldType = (DbgBitfieldType*)this; auto dbgBitfieldType = (DbgBitfieldType*)this;
return mTypeParam->ToString(language) + StrFormat("{%d:%d}", dbgBitfieldType->mPosition, dbgBitfieldType->mLength); mTypeParam->ToString(str, language, allowDirectBfObject, internalName);
} str += StrFormat("{%d:%d}", dbgBitfieldType->mPosition, dbgBitfieldType->mLength);
return;
}
default: default:
break; break;
} }
BF_FATAL("Unhandled type"); BF_FATAL("Unhandled type");
return "???"; str += "???";
} }
String DbgType::ToString(DbgLanguage language, bool allowDirectBfObject)
{
String str;
ToString(str, language, allowDirectBfObject, false);
return str;
}
intptr DbgType::GetByteCount() intptr DbgType::GetByteCount()
{ {
if (!mSizeCalculated) if (!mSizeCalculated)

View file

@ -433,6 +433,7 @@ public:
~DbgSubprogram(); ~DbgSubprogram();
void ToString(StringImpl& str, bool internalName);
String ToString(); String ToString();
DbgLineData* FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram = NULL, DbgSrcFile** srcFile = NULL, int* outLineIdx = NULL); DbgLineData* FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram = NULL, DbgSrcFile** srcFile = NULL, int* outLineIdx = NULL);
DbgType* GetParent(); DbgType* GetParent();
@ -636,6 +637,7 @@ public:
DbgType* GetRootBaseType(); DbgType* GetRootBaseType();
DbgType* RemoveModifiers(bool* hadRef = NULL); DbgType* RemoveModifiers(bool* hadRef = NULL);
String ToStringRaw(DbgLanguage language = DbgLanguage_Unknown); String ToStringRaw(DbgLanguage language = DbgLanguage_Unknown);
void ToString(StringImpl& str, DbgLanguage language, bool allowDirectBfObject, bool internalName);
String ToString(DbgLanguage language = DbgLanguage_Unknown, bool allowDirectBfObject = false); String ToString(DbgLanguage language = DbgLanguage_Unknown, bool allowDirectBfObject = false);
intptr GetByteCount(); intptr GetByteCount();
intptr GetStride(); intptr GetStride();

View file

@ -10766,7 +10766,9 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
} }
} }
if (demangledName.IsEmpty()) if (demangledName.IsEmpty())
demangledName = dwSubprogram->ToString(); {
dwSubprogram->ToString(demangledName, true);
}
DbgSrcFile* dwSrcFile = NULL; DbgSrcFile* dwSrcFile = NULL;
DbgLineData* dwLineData = NULL; DbgLineData* dwLineData = NULL;