(mangled_name: str, resolve_ud)
| 40 | |
| 41 | |
| 42 | def 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, []) |
no test coverage detected