summaryrefslogtreecommitdiff
path: root/sphinx/domains
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/domains')
-rw-r--r--sphinx/domains/c.py64
-rw-r--r--sphinx/domains/cpp.py27
2 files changed, 61 insertions, 30 deletions
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index 304c871ea..fafe827af 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -10,9 +10,8 @@
import re
from typing import (
- Any, Callable, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union
+ Any, Callable, cast, Dict, Generator, Iterator, List, Type, TypeVar, Tuple, Union
)
-from typing import cast
from docutils import nodes
from docutils.nodes import Element, Node, TextElement, system_message
@@ -47,6 +46,11 @@ from sphinx.util.nodes import make_refnode
logger = logging.getLogger(__name__)
T = TypeVar('T')
+DeclarationType = Union[
+ "ASTStruct", "ASTUnion", "ASTEnum", "ASTEnumerator",
+ "ASTType", "ASTTypeWithInit", "ASTMacro",
+]
+
# https://en.cppreference.com/w/c/keyword
_keywords = [
'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double',
@@ -636,6 +640,10 @@ class ASTFunctionParameter(ASTBase):
self.arg = arg
self.ellipsis = ellipsis
+ def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
+ # the anchor will be our parent
+ return symbol.parent.declaration.get_id(version, prefixed=False)
+
def _stringify(self, transform: StringifyTransform) -> str:
if self.ellipsis:
return '...'
@@ -1149,6 +1157,9 @@ class ASTType(ASTBase):
def name(self) -> ASTNestedName:
return self.decl.name
+ def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
+ return symbol.get_full_nested_name().get_id(version)
+
@property
def function_params(self) -> List[ASTFunctionParameter]:
return self.decl.function_params
@@ -1191,6 +1202,9 @@ class ASTTypeWithInit(ASTBase):
def name(self) -> ASTNestedName:
return self.type.name
+ def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
+ return self.type.get_id(version, objectType, symbol)
+
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.type))
@@ -1242,6 +1256,9 @@ class ASTMacro(ASTBase):
def name(self) -> ASTNestedName:
return self.ident
+ def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
+ return symbol.get_full_nested_name().get_id(version)
+
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.ident))
@@ -1342,7 +1359,8 @@ class ASTEnumerator(ASTBase):
class ASTDeclaration(ASTBaseBase):
- def __init__(self, objectType: str, directiveType: str, declaration: Any,
+ def __init__(self, objectType: str, directiveType: str,
+ declaration: Union[DeclarationType, ASTFunctionParameter],
semicolon: bool = False) -> None:
self.objectType = objectType
self.directiveType = directiveType
@@ -1359,18 +1377,20 @@ class ASTDeclaration(ASTBaseBase):
@property
def name(self) -> ASTNestedName:
- return self.declaration.name
+ decl = cast(DeclarationType, self.declaration)
+ return decl.name
@property
def function_params(self) -> List[ASTFunctionParameter]:
if self.objectType != 'function':
return None
- return self.declaration.function_params
+ decl = cast(ASTType, self.declaration)
+ return decl.function_params
def get_id(self, version: int, prefixed: bool = True) -> str:
if self.objectType == 'enumerator' and self.enumeratorScopedSymbol:
return self.enumeratorScopedSymbol.declaration.get_id(version, prefixed)
- id_ = self.symbol.get_full_nested_name().get_id(version)
+ id_ = self.declaration.get_id(version, self.objectType, self.symbol)
if prefixed:
return _id_prefix[version] + id_
else:
@@ -1413,7 +1433,8 @@ class ASTDeclaration(ASTBaseBase):
elif self.objectType == 'enumerator':
mainDeclNode += addnodes.desc_annotation('enumerator ', 'enumerator ')
elif self.objectType == 'type':
- prefix = self.declaration.get_type_declaration_prefix()
+ decl = cast(ASTType, self.declaration)
+ prefix = decl.get_type_declaration_prefix()
prefix += ' '
mainDeclNode += addnodes.desc_annotation(prefix, prefix)
else:
@@ -2988,7 +3009,7 @@ class DefinitionParser(BaseParser):
def parse_pre_v3_type_definition(self) -> ASTDeclaration:
self.skip_ws()
- declaration = None # type: Any
+ declaration = None # type: DeclarationType
if self.skip_word('struct'):
typ = 'struct'
declaration = self._parse_struct()
@@ -3011,7 +3032,7 @@ class DefinitionParser(BaseParser):
'macro', 'struct', 'union', 'enum', 'enumerator', 'type'):
raise Exception('Internal error, unknown directiveType "%s".' % directiveType)
- declaration = None # type: Any
+ declaration = None # type: DeclarationType
if objectType == 'member':
declaration = self._parse_type_with_init(named=True, outer='member')
elif objectType == 'function':
@@ -3158,10 +3179,6 @@ class CObject(ObjectDescription):
self.state.document.note_explicit_target(signode)
- domain = cast(CDomain, self.env.get_domain('c'))
- if name not in domain.objects:
- domain.objects[name] = (domain.env.docname, newestId, self.objtype)
-
if 'noindexentry' not in self.options:
indexText = self.get_index_text(name)
self.indexnode['entries'].append(('single', indexText, newestId, '', None))
@@ -3681,10 +3698,6 @@ class CDomain(Domain):
'objects': {}, # fullname -> docname, node_id, objtype
} # type: Dict[str, Union[Symbol, Dict[str, Tuple[str, str, str]]]]
- @property
- def objects(self) -> Dict[str, Tuple[str, str, str]]:
- return self.data.setdefault('objects', {}) # fullname -> docname, node_id, objtype
-
def clear_doc(self, docname: str) -> None:
if Symbol.debug_show_tree:
print("clear_doc:", docname)
@@ -3700,9 +3713,6 @@ class CDomain(Domain):
print(self.data['root_symbol'].dump(1))
print("\tafter end")
print("clear_doc end:", docname)
- for fullname, (fn, _id, _l) in list(self.objects.items()):
- if fn == docname:
- del self.objects[fullname]
def process_doc(self, env: BuildEnvironment, docname: str,
document: nodes.document) -> None:
@@ -3788,8 +3798,18 @@ class CDomain(Domain):
return []
def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]:
- for refname, (docname, node_id, objtype) in list(self.objects.items()):
- yield (refname, refname, objtype, docname, node_id, 1)
+ rootSymbol = self.data['root_symbol']
+ for symbol in rootSymbol.get_all_symbols():
+ if symbol.declaration is None:
+ continue
+ assert symbol.docname
+ fullNestedName = symbol.get_full_nested_name()
+ name = str(fullNestedName).lstrip('.')
+ dispname = fullNestedName.get_display_string().lstrip('.')
+ objectType = symbol.declaration.objectType
+ docname = symbol.docname
+ newestId = symbol.declaration.get_newest_id()
+ yield (name, dispname, objectType, docname, newestId, 1)
def setup(app: Sphinx) -> Dict[str, Any]:
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 7b10f8166..0e996532f 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -1836,7 +1836,7 @@ class ASTFunctionParameter(ASTBase):
# this is not part of the normal name mangling in C++
if symbol:
# the anchor will be our parent
- return symbol.parent.declaration.get_id(version, prefixed=None)
+ return symbol.parent.declaration.get_id(version, prefixed=False)
# else, do the usual
if self.ellipsis:
return 'z'
@@ -4107,7 +4107,7 @@ class Symbol:
Symbol.debug_print("self:")
print(self.to_string(Symbol.debug_indent + 1), end="")
Symbol.debug_print("nestedName: ", nestedName)
- Symbol.debug_print("templateDecls: ", templateDecls)
+ Symbol.debug_print("templateDecls: ", ",".join(str(t) for t in templateDecls))
Symbol.debug_print("strictTemplateParamArgLists:", strictTemplateParamArgLists)
Symbol.debug_print("ancestorLookupType:", ancestorLookupType)
Symbol.debug_print("templateShorthand: ", templateShorthand)
@@ -4231,7 +4231,7 @@ class Symbol:
Symbol.debug_indent += 1
Symbol.debug_print("_add_symbols:")
Symbol.debug_indent += 1
- Symbol.debug_print("tdecls:", templateDecls)
+ Symbol.debug_print("tdecls:", ",".join(str(t) for t in templateDecls))
Symbol.debug_print("nn: ", nestedName)
Symbol.debug_print("decl: ", declaration)
Symbol.debug_print("doc: ", docname)
@@ -4360,6 +4360,11 @@ class Symbol:
if Symbol.debug_lookup:
Symbol.debug_print("candId:", candId)
for symbol in withDecl:
+ # but all existing must be functions as well,
+ # otherwise we declare it to be a duplicate
+ if symbol.declaration.objectType != 'function':
+ handleDuplicateDeclaration(symbol, candSymbol)
+ # (not reachable)
oldId = symbol.declaration.get_newest_id()
if Symbol.debug_lookup:
Symbol.debug_print("oldId: ", oldId)
@@ -4370,7 +4375,11 @@ class Symbol:
# if there is an empty symbol, fill that one
if len(noDecl) == 0:
if Symbol.debug_lookup:
- Symbol.debug_print("no match, no empty, candSybmol is not None?:", candSymbol is not None) # NOQA
+ Symbol.debug_print("no match, no empty")
+ if candSymbol is not None:
+ Symbol.debug_print("result is already created candSymbol")
+ else:
+ Symbol.debug_print("result is makeCandSymbol()")
Symbol.debug_indent -= 2
if candSymbol is not None:
return candSymbol
@@ -6814,10 +6823,12 @@ class CPPObject(ObjectDescription):
parentSymbol = env.temp_data['cpp:parent_symbol']
parentDecl = parentSymbol.declaration
if parentDecl is not None and parentDecl.objectType == 'function':
- logger.warning("C++ declarations inside functions are not supported." +
- " Parent function is " +
- str(parentSymbol.get_full_nested_name()),
- location=self.get_source_info())
+ msg = "C++ declarations inside functions are not supported." \
+ " Parent function: {}\nDirective name: {}\nDirective arg: {}"
+ logger.warning(msg.format(
+ str(parentSymbol.get_full_nested_name()),
+ self.name, self.arguments[0]
+ ), location=self.get_source_info())
name = _make_phony_error_name()
symbol = parentSymbol.add_name(name)
env.temp_data['cpp:last_symbol'] = symbol