import re


def _SymbolKey(symbol):
  """Returns a tuple that can be used to see if two Symbol are the same.

  Keys are not guaranteed to be unique within a SymbolGroup. When multiple
  symbols have the same key, they will be matched up in order of appearance.
  We do this because the numbering of these generated symbols is not stable.

  Examples of symbols with shared keys:
    "** merge strings"
    "** symbol gap 3", "** symbol gap 5"
    "foo() [clone ##]"
    "CSWTCH.61", "CSWTCH.62"
    "._468", "._467"
    ".L__unnamed_1193", ".L__unnamed_712"
  """
  name = symbol.full_name
  clone_idx = name.find(' [clone ')
  if clone_idx != -1:
    name = name[:clone_idx]
  if name.startswith('*'):
    # "symbol gap 3 (bar)" -> "symbol gaps"
    name = re.sub(r'\s+\d+( \(.*\))?$', 's', name)

  # Use section rather than section_name since clang & gcc use
  # .data.rel.ro vs .data.rel.ro.local.
  if '.' not in name:
    return (symbol.section, name)

  # Compiler or Linker generated symbol.
  name = re.sub(r'[.0-9]', '', name)  # Strip out all numbers and dots.
  return (symbol.section, name, symbol.object_path)