def METHOD_NAME(type):
    if type.spelling in ("IOHANDLE", "LOCK"):
        return ""
    if type.kind == TypeKind.AUTO:
        return METHOD_NAME(type.get_canonical())
    if type.kind == TypeKind.LVALUEREFERENCE:
        return METHOD_NAME(type.get_pointee())
    if type.kind == TypeKind.POINTER:
        return "p" + METHOD_NAME(type.get_pointee())
    if is_array_type(type):
        return "a" + METHOD_NAME(type.element_type)
    if type.kind == TypeKind.FUNCTIONPROTO:
        return "fn"
    if type.kind == TypeKind.TYPEDEF:
        return METHOD_NAME(type.get_declaration().underlying_typedef_type)
    if type.kind == TypeKind.ELABORATED:
        return METHOD_NAME(type.get_named_type())
    if type.kind in (TypeKind.UNEXPOSED, TypeKind.RECORD):
        if type.get_declaration().spelling in "shared_ptr unique_ptr".split():
            return "p" + METHOD_NAME(type.get_template_argument_type(0))
        if type.get_declaration().spelling in "array sorted_array".split():
            return "a" + METHOD_NAME(type.get_template_argument_type(0))
    return ""