summaryrefslogtreecommitdiff
path: root/sphinx/domains/cpp.py
diff options
context:
space:
mode:
authorJakob Lykke Andersen <Jakob@caput.dk>2022-07-24 21:24:15 +0200
committerJakob Lykke Andersen <Jakob@caput.dk>2022-07-24 21:41:51 +0200
commit92a48c7fc32365365ed849d1cec1cfee3e41c707 (patch)
treeceb728191b43f2adf937fae86f7d2665614efb06 /sphinx/domains/cpp.py
parent0f09e4e4288f3e11d2ca02a9b3e996dff2678d8c (diff)
downloadsphinx-git-92a48c7fc32365365ed849d1cec1cfee3e41c707.tar.gz
C++, refactor requires clause ID handling
Diffstat (limited to 'sphinx/domains/cpp.py')
-rw-r--r--sphinx/domains/cpp.py47
1 files changed, 28 insertions, 19 deletions
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 75fdba35e..690998e5f 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -3878,6 +3878,14 @@ class ASTTemplateDeclarationPrefix(ASTBase):
# templates is None means it's an explicit instantiation of a variable
self.templates = templates
+ def get_requires_clause_in_last(self) -> Optional["ASTRequiresClause"]:
+ if self.templates is None:
+ return None
+ lastList = self.templates[-1]
+ if not isinstance(lastList, ASTTemplateParams):
+ return None
+ return lastList.requiresClause # which may be None
+
def get_id_except_requires_clause_in_last(self, version: int) -> str:
assert version >= 2
# This is not part of the Itanium ABI mangling system.
@@ -3953,17 +3961,6 @@ class ASTDeclaration(ASTBase):
return self.declaration.name
@property
- def requiresClause(self) -> Optional[ASTRequiresClause]:
- if self.templatePrefix is None:
- return None
- if not self.templatePrefix.templates:
- return None
- lastTemplate = self.templatePrefix.templates[-1]
- if not isinstance(lastTemplate, ASTTemplateParams):
- return None
- return lastTemplate.requiresClause
-
- @property
def function_params(self) -> List[ASTFunctionParameter]:
if self.objectType != 'function':
return None
@@ -3983,19 +3980,31 @@ class ASTDeclaration(ASTBase):
res = [_id_prefix[version]]
else:
res = []
- if self.templatePrefix:
+ # (See also https://github.com/sphinx-doc/sphinx/pull/10286#issuecomment-1168102147)
+ # The first implementation of requires clauses only supported a single clause after the
+ # template prefix, and no trailing clause. It put the ID after the template parameter
+ # list, i.e.,
+ # "I" + template_parameter_list_id + "E" + "IQ" + requires_clause_id + "E"
+ # but the second implementation associates the requires clause with each list, i.e.,
+ # "I" + template_parameter_list_id + "IQ" + requires_clause_id + "E" + "E"
+ # To avoid making a new ID version, we make an exception for the last requires clause
+ # in the template prefix, and still put it in the end.
+ # As we now support trailing requires clauses we add that as if it was a conjunction.
+ if self.templatePrefix is not None:
res.append(self.templatePrefix.get_id_except_requires_clause_in_last(version))
- # Encode the last requires clause specially to avoid introducing a new
- # ID version number.
- requiresClause = self.requiresClause
- if requiresClause or self.trailingRequiresClause:
+ requiresClauseInLast = self.templatePrefix.get_requires_clause_in_last()
+ else:
+ requiresClauseInLast = None
+
+ if requiresClauseInLast or self.trailingRequiresClause:
if version < 4:
raise NoOldIdError()
res.append('IQ')
- if requiresClause and self.trailingRequiresClause:
+ if requiresClauseInLast and self.trailingRequiresClause:
+ # make a conjunction of them
res.append('aa')
- if requiresClause:
- res.append(requiresClause.expr.get_id(version))
+ if requiresClauseInLast:
+ res.append(requiresClauseInLast.expr.get_id(version))
if self.trailingRequiresClause:
res.append(self.trailingRequiresClause.expr.get_id(version))
res.append('E')