# Buggy code
def add_target_and_index(self, ast, sig, signode):
    # general note: name must be lstrip(':')'ed, to remove "::"
    try:
        id_v1 = ast.get_id_v1()
    except NoOldIdError:
        id_v1 = None
    id_v2 = ast.get_id_v2()
    # store them in reverse order, so the newest is first
    ids = [id_v2, id_v1]

    theid = ids[0]
    ast.newestId = theid
    assert theid  # shouldn't be None
    name = text_type(ast.prefixedName).lstrip(":")
    if theid not in self.state.document.ids:
        # if the name is not unique, the first one will win
        objects = self.env.domaindata["cpp"]["objects"]
        if name not in objects:
            signode["names"].append(name)
        else:
            pass
            # print("[CPP] non-unique name:", name)
        for id in ids:
            if id:  # is None when the element didn't exist in that version
                signode["ids"].append(id)
        signode["first"] = not self.names
        self.state.document.note_explicit_target(signode)
        if name not in objects:
            objects.setdefault(name, (self.env.docname, ast))
            if ast.objectType == "enumerator":
                # find the parent, if it exists && is an enum
                #                     && it's unscoped,
                #                  then add the name to the parent scope
                assert len(ast.prefixedName.names) > 0
                parentPrefixedAstName = ASTNestedName(ast.prefixedName.names[:-1])
                parentPrefixedName = text_type(parentPrefixedAstName).lstrip(":")
                if parentPrefixedName in objects:
                    docname, parentAst = objects[parentPrefixedName]
                    if parentAst.objectType == "enum" and not parentAst.scoped:
                        enumeratorName = ASTNestedName([ast.prefixedName.names[-1]])
                        assert len(parentAst.prefixedName.names) > 0
                        enumScope = ASTNestedName(parentAst.prefixedName.names[:-1])
                        unscopedName = enumeratorName.prefix_nested_name(enumScope)
                        txtUnscopedName = text_type(unscopedName).lstrip(":")
                        if txtUnscopedName not in objects:
                            objects.setdefault(txtUnscopedName, (self.env.docname, ast))
            # add the uninstantiated template if it doesn't exist
            uninstantiated = ast.prefixedName.get_name_no_last_template().lstrip(":")
            if uninstantiated != name and uninstantiated not in objects:
                signode["names"].append(uninstantiated)
                objects.setdefault(uninstantiated, (self.env.docname, ast))

    indextext = self.get_index_text(name)
    if not re.compile(r"^[a-zA-Z0-9_]*$").match(theid):
        self.state_machine.reporter.warning(
            'Index id generation for C++ object "%s" failed, please '
            "report as bug (id=%s)." % (text_type(ast), theid),
            line=self.lineno,
        )
    self.indexnode["entries"].append(("single", indextext, theid, ""))


# Traceback (AssertionError)
# Sphinx version: 1.3.1
# Python version: 2.7.9 (CPython)
# Docutils version: 0.12 release
# Jinja2 version: 2.7.3
# Last messages:
#   reading sources... [ 16%] blas_like/level2/QuasiTrsv
#   reading sources... [ 16%] blas_like/level2/Symv
#   reading sources... [ 16%] blas_like/level2/Syr
#   reading sources... [ 16%] blas_like/level2/Syr2
#   reading sources... [ 17%] blas_like/level2/Trmv
#   reading sources... [ 17%] blas_like/level2/Trr
#   reading sources... [ 17%] blas_like/level2/Trr2
#   reading sources... [ 17%] blas_like/level2/Trsv
#   reading sources... [ 18%] blas_like/level3
#   reading sources... [ 18%] blas_like/level3/Gemm
# Loaded extensions:
#   sphinx.ext.autodoc (1.3.1) from /Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/autodoc.pyc
#   sphinx.ext.doctest (1.3.1) from /Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/doctest.pyc
#   sphinx.ext.mathjax (1.3.1) from /Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/mathjax.pyc
#   sphinx.ext.coverage (1.3.1) from /Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/coverage.pyc
#   sphinx.ext.todo (1.3.1) from /Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/todo.pyc
#   alabaster (0.7.4) from /Users/poulson/anaconda/lib/python2.7/site-packages/alabaster-0.7.4-py2.7.egg/alabaster/__init__.pyc
Traceback (most recent call last):
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/cmdline.py", line 245, in main
    app.build(opts.force_all, filenames)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/application.py", line 264, in build
    self.builder.build_update()
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/builders/__init__.py", line 245, in build_update
    'out of date' % len(to_build))
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/builders/__init__.py", line 259, in build
    self.doctreedir, self.app))
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/environment.py", line 618, in update
    self._read_serial(docnames, app)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/environment.py", line 638, in _read_serial
    self.read_doc(docname, app)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/environment.py", line 791, in read_doc
    pub.publish()
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/core.py", line 217, in publish
    self.settings)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/environment.py", line 126, in read
    self.parse()
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/__init__.py", line 172, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 170, in run
    input_source=document['source'])
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2726, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2726, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2299, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2311, in explicit_construct
    return method(self, expmatch)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2054, in directive
    directive_class, match, type_name, option_presets)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2103, in run_directive
    result = directive_instance.run()
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/domains/__init__.py", line 197, in run
    return BaseDirective.run(self)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/directives/__init__.py", line 156, in run
    self.state.nested_parse(self.content, self.content_offset, contentnode)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 195, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2299, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2311, in explicit_construct
    return method(self, expmatch)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2054, in directive
    directive_class, match, type_name, option_presets)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/docutils/parsers/rst/states.py", line 2103, in run_directive
    result = directive_instance.run()
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/domains/__init__.py", line 197, in run
    return BaseDirective.run(self)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/directives/__init__.py", line 148, in run
    self.add_target_and_index(name, sig, signode)
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/domains/cpp.py", line 2459, in add_target_and_index
    enumScope = ASTNestedName(parentAst.prefixedName.names[:-1])
  File "/Users/poulson/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/domains/cpp.py", line 656, in __init__
    assert len(names) > 0
AssertionError


# Fixed code
def add_target_and_index(self, ast, sig, signode):
    # general note: name must be lstrip(':')'ed, to remove "::"
    try:
        id_v1 = ast.get_id_v1()
    except NoOldIdError:
        id_v1 = None
    id_v2 = ast.get_id_v2()
    # store them in reverse order, so the newest is first
    ids = [id_v2, id_v1]

    theid = ids[0]
    ast.newestId = theid
    assert theid  # shouldn't be None
    name = text_type(ast.prefixedName).lstrip(":")
    if theid not in self.state.document.ids:
        # if the name is not unique, the first one will win
        objects = self.env.domaindata["cpp"]["objects"]
        if name not in objects:
            signode["names"].append(name)
        else:
            pass
            # print("[CPP] non-unique name:", name)
        for id in ids:
            if id:  # is None when the element didn't exist in that version
                signode["ids"].append(id)
        signode["first"] = not self.names
        self.state.document.note_explicit_target(signode)
        if name not in objects:
            objects.setdefault(name, (self.env.docname, ast))
            if ast.objectType == "enumerator":
                self._add_enumerator_to_parent(ast, objects)
            # add the uninstantiated template if it doesn't exist
            uninstantiated = ast.prefixedName.get_name_no_last_template().lstrip(":")
            if uninstantiated != name and uninstantiated not in objects:
                signode["names"].append(uninstantiated)
                objects.setdefault(uninstantiated, (self.env.docname, ast))

    indextext = self.get_index_text(name)
    if not re.compile(r"^[a-zA-Z0-9_]*$").match(theid):
        self.state_machine.reporter.warning(
            'Index id generation for C++ object "%s" failed, please '
            "report as bug (id=%s)." % (text_type(ast), theid),
            line=self.lineno,
        )
    self.indexnode["entries"].append(("single", indextext, theid, ""))