MCPcopy Create free account
hub / github.com/bfbbdecomp/bfbb / demangle

Function demangle

ghidra_scripts/gimport/demangle.py:42–207  ·  view source on GitHub ↗
(mangled_name: str, resolve_ud)

Source from the content-addressed store, hash-verified

40
41
42def demangle(mangled_name: str, resolve_ud) -> Tuple[str, List[GType]]:
43 # Cut off name
44 index = mangled_name.find("__", 1) # 1 instead of 0 to skip __ in names like __ct
45 if index == -1:
46 # Not a mangled function
47 return None
48 # Don't know how to demangle some things
49 if mangled_name in SPECIAL_IGNORE:
50 return None
51 name = mangled_name[:index] # Name part only
52 without_name = mangled_name[index+2:] # Cut off name
53
54 # Cut off namespacing bits
55 namespaces = []
56 while len(without_name) > 0 and (without_name[0] == "Q" or str.isdigit(without_name[0])):
57 if without_name[0] == "Q":
58 qualification_count = int(without_name[1])
59 without_name = without_name[2:]
60 for i in range(qualification_count):
61 (namespace_len_text, rest) = re.match(r"^(\d+)(.*)", without_name).groups()
62 namespace_len = int(namespace_len_text)
63 namespaces.append(rest[:namespace_len])
64 without_name = rest[namespace_len:]
65 else:
66 (len_str, rest) = re.match(r"^(\d+)(.*)", without_name).groups()
67 namespace_len = int(len_str)
68 namespaces.append(rest[:namespace_len])
69 without_name = rest[namespace_len:]
70 this_type = resolve_ud(namespaces[-1]) if namespaces else None
71
72 # Namespaced global variable, not a function
73 if len(without_name) == 0:
74 return None
75
76 # Handle special names
77 if name.startswith("__"):
78 if name in SPECIAL_NAME_TO_OPERATOR:
79 name = f"operator{SPECIAL_NAME_TO_OPERATOR[name]}"
80 elif name == "__ct":
81 name = namespaces[-1]
82 elif name == "__dt":
83 name = f"~{namespaces[-1]}"
84
85 # Add namespaces to name
86 name = "::".join(namespaces + [name])
87
88 # C -> Const method.
89 is_const = without_name[0] == "C"
90 if is_const:
91 without_name = without_name[1:]
92
93 # F -> function, no F -> method.
94 is_member = without_name[0] != "F"
95 whole_text = without_name if is_member else without_name[1:]
96
97 # Easier to handle this here
98 if whole_text == "v":
99 return (name, [])

Callers 2

postprocess_cleanupMethod · 0.90

Calls 2

GPointerTypeClass · 0.85
parse_typeFunction · 0.85

Tested by

no test coverage detected