1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
import logging
import libghdl.thin.vhdl.nodes as nodes
import libghdl.thin.vhdl.nodes_meta as nodes_meta
import libghdl.thin.vhdl.pyutils as pyutils
import libghdl.thin.name_table as name_table
log = logging.getLogger(__name__)
def find_def_chain(first, loc):
n1 = first
while n1 != nodes.Null_Iir:
res = find_def(n1, loc)
if res is not None:
return res
n1 = nodes.Get_Chain(n1)
return None
def find_def(n, loc):
"Return the node at location :param loc:, or None if not under :param n:"
if n == nodes.Null_Iir:
return None
k = nodes.Get_Kind(n)
if k in [nodes.Iir_Kind.Simple_Name,
nodes.Iir_Kind.Character_Literal,
nodes.Iir_Kind.Operator_Symbol,
nodes.Iir_Kind.Selected_Name,
nodes.Iir_Kind.Attribute_Name,
nodes.Iir_Kind.Selected_Element]:
n_loc = nodes.Get_Location(n)
if loc >= n_loc:
ident = nodes.Get_Identifier(n)
id_len = name_table.Get_Name_Length(ident)
if loc < n_loc + id_len:
return n
if k == nodes.Iir_Kind.Simple_Name:
return None
elif k == nodes.Iir_Kind.Design_File:
return find_def_chain(nodes.Get_First_Design_Unit(n), loc)
elif k == nodes.Iir_Kind.Design_Unit:
#if loc > elocations.Get_End_Location(unit):
# return None
res = find_def_chain(nodes.Get_Context_Items(n), loc)
if res is not None:
return res
unit = nodes.Get_Library_Unit(n)
return find_def(unit, loc)
# This is *much* faster than using node_iter!
for f in pyutils.fields_iter(n):
typ = nodes_meta.get_field_type(f)
if typ == nodes_meta.types.Iir:
attr = nodes_meta.get_field_attribute(f)
if attr == nodes_meta.Attr.ANone:
res = find_def(nodes_meta.Get_Iir(n, f), loc)
if res is not None:
return res
elif attr == nodes_meta.Attr.Chain:
res = find_def_chain(nodes_meta.Get_Iir(n, f), loc)
if res is not None:
return res
elif attr == nodes_meta.Attr.Maybe_Ref:
if not nodes.Get_Is_Ref(n, f):
res = find_def(nodes_meta.Get_Iir(n, f), loc)
if res is not None:
return res
elif typ == nodes_meta.types.Iir_List:
attr = nodes_meta.get_field_attribute(f)
if attr == nodes_meta.Attr.ANone:
for n1 in pyutils.list_iter(nodes_meta.Get_Iir_List(n, f)):
res = find_def(n1, loc)
if res is not None:
return res
elif typ == nodes_meta.types.Iir_Flist:
attr = nodes_meta.get_field_attribute(f)
if attr == nodes_meta.Attr.ANone:
for n1 in pyutils.flist_iter(nodes_meta.Get_Iir_Flist(n, f)):
res = find_def(n1, loc)
if res is not None:
return res
return None
def goto_definition(n, loc):
"Return the declaration (as a node) under :param loc: or None"
ref = find_def(n, loc)
log.debug("for loc %u found node %s", loc, ref)
if ref is None:
return None
log.debug("for loc %u id=%s", loc, name_table.Get_Name_Ptr(nodes.Get_Identifier(ref)).decode('utf-8'))
ent = nodes.Get_Named_Entity(ref)
return None if ent == nodes.Null_Iir else ent
|