better debugging support for native debuggers; changed name mangling; fixes #3471
This commit is contained in:
parent
97129ebd8a
commit
b654aa399a
3 changed files with 164 additions and 58 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# The Nim Compiler
|
||||
# (c) Copyright 2013 Andreas Rumpf
|
||||
# (c) Copyright 2016 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
# ------------------------- Name Mangling --------------------------------
|
||||
|
||||
import debuginfo
|
||||
|
||||
proc isKeyword(w: PIdent): bool =
|
||||
# Nim and C++ share some keywords
|
||||
# it's more efficient to test the whole Nim keywords range
|
||||
|
|
@ -26,67 +28,66 @@ proc mangleField(name: PIdent): string =
|
|||
result[0] = result[0].toUpper # Mangling makes everything lowercase,
|
||||
# but some identifiers are C keywords
|
||||
|
||||
proc hashOwner(s: PSym): FilenameHash =
|
||||
var m = s
|
||||
while m.kind != skModule: m = m.owner
|
||||
let p = m.owner
|
||||
assert p.kind == skPackage
|
||||
result = gDebugInfo.register(p.name.s, m.name.s)
|
||||
|
||||
proc mangleName(s: PSym): Rope =
|
||||
result = s.loc.r
|
||||
if result == nil:
|
||||
when oKeepVariableNames:
|
||||
let keepOrigName = s.kind in skLocalVars - {skForVar} and
|
||||
{sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
|
||||
not isKeyword(s.name)
|
||||
# XXX: This is still very experimental
|
||||
#
|
||||
# Even with all these inefficient checks, the bootstrap
|
||||
# time is actually improved. This is probably because so many
|
||||
# rope concatenations are now eliminated.
|
||||
#
|
||||
# Future notes:
|
||||
# sfFromGeneric seems to be needed in order to avoid multiple
|
||||
# definitions of certain variables generated in transf with
|
||||
# names such as:
|
||||
# `r`, `res`
|
||||
# I need to study where these come from.
|
||||
#
|
||||
# about sfShadowed:
|
||||
# consider the following Nim code:
|
||||
# var x = 10
|
||||
# block:
|
||||
# var x = something(x)
|
||||
# The generated C code will be:
|
||||
# NI x;
|
||||
# x = 10;
|
||||
# {
|
||||
# NI x;
|
||||
# x = something(x); // Oops, x is already shadowed here
|
||||
# }
|
||||
# Right now, we work-around by not keeping the original name
|
||||
# of the shadowed variable, but we can do better - we can
|
||||
# create an alternative reference to it in the outer scope and
|
||||
# use that in the inner scope.
|
||||
#
|
||||
# about isCKeyword:
|
||||
# Nim variable names can be C keywords.
|
||||
# We need to avoid such names in the generated code.
|
||||
# XXX: Study whether mangleName is called just once per variable.
|
||||
# Otherwise, there might be better place to do this.
|
||||
#
|
||||
# about sfGlobal:
|
||||
# This seems to be harder - a top level extern variable from
|
||||
# another modules can have the same name as a local one.
|
||||
# Maybe we should just implement sfShadowed for them too.
|
||||
#
|
||||
# about skForVar:
|
||||
# These are not properly scoped now - we need to add blocks
|
||||
# around for loops in transf
|
||||
if keepOrigName:
|
||||
result = s.name.s.mangle.rope
|
||||
else:
|
||||
add(result, rope(mangle(s.name.s)))
|
||||
add(result, ~"_")
|
||||
add(result, rope(s.id))
|
||||
let keepOrigName = s.kind in skLocalVars - {skForVar} and
|
||||
{sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
|
||||
not isKeyword(s.name)
|
||||
# Even with all these inefficient checks, the bootstrap
|
||||
# time is actually improved. This is probably because so many
|
||||
# rope concatenations are now eliminated.
|
||||
#
|
||||
# sfFromGeneric is needed in order to avoid multiple
|
||||
# definitions of certain variables generated in transf with
|
||||
# names such as:
|
||||
# `r`, `res`
|
||||
# I need to study where these come from.
|
||||
#
|
||||
# about sfShadowed:
|
||||
# consider the following Nim code:
|
||||
# var x = 10
|
||||
# block:
|
||||
# var x = something(x)
|
||||
# The generated C code will be:
|
||||
# NI x;
|
||||
# x = 10;
|
||||
# {
|
||||
# NI x;
|
||||
# x = something(x); // Oops, x is already shadowed here
|
||||
# }
|
||||
# Right now, we work-around by not keeping the original name
|
||||
# of the shadowed variable, but we can do better - we can
|
||||
# create an alternative reference to it in the outer scope and
|
||||
# use that in the inner scope.
|
||||
#
|
||||
# about isCKeyword:
|
||||
# Nim variable names can be C keywords.
|
||||
# We need to avoid such names in the generated code.
|
||||
#
|
||||
# about sfGlobal:
|
||||
# This seems to be harder - a top level extern variable from
|
||||
# another modules can have the same name as a local one.
|
||||
# Maybe we should just implement sfShadowed for them too.
|
||||
#
|
||||
# about skForVar:
|
||||
# These are not properly scoped now - we need to add blocks
|
||||
# around for loops in transf
|
||||
result = s.name.s.mangle.rope
|
||||
if keepOrigName:
|
||||
result.add "0"
|
||||
else:
|
||||
add(result, rope(mangle(s.name.s)))
|
||||
add(result, ~"_")
|
||||
add(result, rope(s.id))
|
||||
add(result, ~"_")
|
||||
add(result, rope(hashOwner(s).BiggestInt))
|
||||
s.loc.r = result
|
||||
|
||||
proc typeName(typ: PType): Rope =
|
||||
|
|
@ -570,15 +571,27 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
|
|||
let t = if t.kind == tyRange: t.lastSon else: t
|
||||
result = getTypeName(t)
|
||||
idTablePut(m.typeCache, t, result)
|
||||
var size: int
|
||||
if firstOrd(t) < 0:
|
||||
addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result])
|
||||
size = 4
|
||||
else:
|
||||
case int(getSize(typ))
|
||||
size = int(getSize(t))
|
||||
case size
|
||||
of 1: addf(m.s[cfsTypes], "typedef NU8 $1;$n", [result])
|
||||
of 2: addf(m.s[cfsTypes], "typedef NU16 $1;$n", [result])
|
||||
of 4: addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result])
|
||||
of 8: addf(m.s[cfsTypes], "typedef NI64 $1;$n", [result])
|
||||
else: internalError(t.sym.info, "getTypeDescAux: " & $getSize(t))
|
||||
else: internalError(t.sym.info, "getTypeDescAux: enum")
|
||||
let owner = hashOwner(t.sym)
|
||||
if not gDebugInfo.hasEnum(t.sym.name.s, t.sym.info.line, owner):
|
||||
var vals: seq[(string, int)] = @[]
|
||||
for i in countup(0, t.n.len - 1):
|
||||
assert(t.n.sons[i].kind == nkSym)
|
||||
let field = t.n.sons[i].sym
|
||||
vals.add((field.name.s, field.position.int))
|
||||
gDebugInfo.registerEnum(EnumDesc(size: size, owner: owner, id: t.sym.id,
|
||||
name: t.sym.name.s, values: vals))
|
||||
of tyProc:
|
||||
result = getTypeName(t)
|
||||
idTablePut(m.typeCache, t, result)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue