This commit is contained in:
Jakob Lykke Andersen 2015-05-30 09:56:32 +02:00
parent 048f54f2b0
commit 6b8f29bb45
2 changed files with 39 additions and 17 deletions

View File

@ -13,6 +13,7 @@ Bugs fixed
* #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following * #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following
lines after class definitions lines after class definitions
* #1790: ``literalinclude`` strips empty lines at the head and tail * #1790: ``literalinclude`` strips empty lines at the head and tail
* #1913: C++, fix assert bug for enumerators in next-to-global and global scope.
Documentation Documentation
------------- -------------

View File

@ -2415,6 +2415,43 @@ class CPPObject(ObjectDescription):
names=('returns', 'return')), names=('returns', 'return')),
] ]
def _add_enumerator_to_parent(self, ast, objects):
assert 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
if len(ast.prefixedName.names) == 1:
# TODO: we could warn, but it is somewhat equivalent to unscoped
# enums, without the enum
return # no parent
parentPrefixedAstName = ASTNestedName(ast.prefixedName.names[:-1])
parentPrefixedName = text_type(parentPrefixedAstName).lstrip(':')
if parentPrefixedName not in objects:
# the parent is not explicitly declared
# TODO: we could warn, but it could be a style to just assume
# enumerator parnets to be scoped
return
docname, parentAst = objects[parentPrefixedName]
if parentAst.objectType != 'enum':
# TODO: maybe issue a warning, enumerators in non-enums is weird,
# but it is somewhat equivalent to unscoped enums, without the enum
return
if parentAst.scoped:
return
enumeratorName = ASTNestedName([ast.prefixedName.names[-1]])
assert len(parentAst.prefixedName.names) > 0
if len(parentAst.prefixedName.names) == 1:
# the enum is in global scope
unscopedName = enumeratorName
else:
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))
def add_target_and_index(self, ast, sig, signode): def add_target_and_index(self, ast, sig, signode):
# general note: name must be lstrip(':')'ed, to remove "::" # general note: name must be lstrip(':')'ed, to remove "::"
try: try:
@ -2445,23 +2482,7 @@ class CPPObject(ObjectDescription):
if name not in objects: if name not in objects:
objects.setdefault(name, (self.env.docname, ast)) objects.setdefault(name, (self.env.docname, ast))
if ast.objectType == 'enumerator': if ast.objectType == 'enumerator':
# find the parent, if it exists && is an enum self._add_enumerator_to_parent(ast, objects)
# && 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 # add the uninstantiated template if it doesn't exist
uninstantiated = ast.prefixedName.get_name_no_last_template().lstrip(':') uninstantiated = ast.prefixedName.get_name_no_last_template().lstrip(':')
if uninstantiated != name and uninstantiated not in objects: if uninstantiated != name and uninstantiated not in objects: