mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, fix direct lookup problem
Also clarify documentation regarding cross-references involving templates. See also sphinx-doc/sphinx#2057
This commit is contained in:
parent
0af74a76dc
commit
4397606d03
2
CHANGES
2
CHANGES
@ -172,6 +172,8 @@ Features added
|
|||||||
* C++, add support for anonymous entities using names staring with ``@``.
|
* C++, add support for anonymous entities using names staring with ``@``.
|
||||||
Fixes #3593 and #2683.
|
Fixes #3593 and #2683.
|
||||||
* #5147: C++, add support for (most) character literals.
|
* #5147: C++, add support for (most) character literals.
|
||||||
|
* C++, cross-referencing entities inside primary templates is supported,
|
||||||
|
and now properly documented.
|
||||||
* #3606: MathJax should be loaded with async attribute
|
* #3606: MathJax should be loaded with async attribute
|
||||||
* html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs:
|
* html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs:
|
||||||
#4193)
|
#4193)
|
||||||
|
@ -1033,19 +1033,25 @@ Assume the following declarations.
|
|||||||
Inner
|
Inner
|
||||||
|
|
||||||
In general the reference must include the template parameter declarations,
|
In general the reference must include the template parameter declarations,
|
||||||
e.g., ``template\<typename TOuter> Wrapper::Outer``
|
and template arguments for the prefix of qualified names. For example:
|
||||||
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`). Currently the lookup
|
|
||||||
only succeed if the template parameter identifiers are equal strings. That is,
|
|
||||||
``template\<typename UOuter> Wrapper::Outer`` will not work.
|
|
||||||
|
|
||||||
The inner class template cannot be directly referenced, unless the current
|
- ``template\<typename TOuter> Wrapper::Outer``
|
||||||
namespace is changed or the following shorthand is used. If a template
|
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`)
|
||||||
parameter list is omitted, then the lookup will assume either a template or a
|
- ``template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner``
|
||||||
non-template, but not a partial template specialisation. This means the
|
(:cpp:class:`template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner`)
|
||||||
following references work.
|
|
||||||
|
|
||||||
- ``Wrapper::Outer`` (:cpp:class:`Wrapper::Outer`)
|
Currently the lookup only succeed if the template parameter identifiers are equal strings.
|
||||||
- ``Wrapper::Outer::Inner`` (:cpp:class:`Wrapper::Outer::Inner`)
|
That is, ``template\<typename UOuter> Wrapper::Outer`` will not work.
|
||||||
|
|
||||||
|
As a shorthand notation, if a template parameter list is omitted,
|
||||||
|
then the lookup will assume either a primary template or a non-template,
|
||||||
|
but not a partial template specialisation.
|
||||||
|
This means the following references work as well:
|
||||||
|
|
||||||
|
- ``Wrapper::Outer``
|
||||||
|
(:cpp:class:`Wrapper::Outer`)
|
||||||
|
- ``Wrapper::Outer::Inner``
|
||||||
|
(:cpp:class:`Wrapper::Outer::Inner`)
|
||||||
- ``template\<typename TInner> Wrapper::Outer::Inner``
|
- ``template\<typename TInner> Wrapper::Outer::Inner``
|
||||||
(:cpp:class:`template\<typename TInner> Wrapper::Outer::Inner`)
|
(:cpp:class:`template\<typename TInner> Wrapper::Outer::Inner`)
|
||||||
|
|
||||||
|
@ -3634,8 +3634,9 @@ class Symbol(object):
|
|||||||
return ASTNestedName(names, templates, rooted=False)
|
return ASTNestedName(names, templates, rooted=False)
|
||||||
|
|
||||||
def _find_named_symbol(self, identOrOp, templateParams, templateArgs,
|
def _find_named_symbol(self, identOrOp, templateParams, templateArgs,
|
||||||
templateShorthand, matchSelf, recurseInAnon):
|
templateShorthand, matchSelf, recurseInAnon,
|
||||||
# type: (Any, Any, Any, Any, bool, bool) -> Symbol
|
correctPrimaryTemplateArgs):
|
||||||
|
# type: (Any, Any, Any, Any, bool, bool, bool) -> Symbol
|
||||||
|
|
||||||
def isSpecialization():
|
def isSpecialization():
|
||||||
# the names of the template parameters must be given exactly as args
|
# the names of the template parameters must be given exactly as args
|
||||||
@ -3658,12 +3659,13 @@ class Symbol(object):
|
|||||||
if paramName != argName:
|
if paramName != argName:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
if templateParams is not None and templateArgs is not None:
|
if correctPrimaryTemplateArgs:
|
||||||
# If both are given, but it's not a specialization, then do lookup as if
|
if templateParams is not None and templateArgs is not None:
|
||||||
# there is no argument list.
|
# If both are given, but it's not a specialization, then do lookup as if
|
||||||
# For example: template<typename T> int A<T>::var;
|
# there is no argument list.
|
||||||
if not isSpecialization():
|
# For example: template<typename T> int A<T>::var;
|
||||||
templateArgs = None
|
if not isSpecialization():
|
||||||
|
templateArgs = None
|
||||||
|
|
||||||
def matches(s):
|
def matches(s):
|
||||||
if s.identOrOp != identOrOp:
|
if s.identOrOp != identOrOp:
|
||||||
@ -3722,7 +3724,8 @@ class Symbol(object):
|
|||||||
templateArgs,
|
templateArgs,
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False,
|
matchSelf=False,
|
||||||
recurseInAnon=True)
|
recurseInAnon=True,
|
||||||
|
correctPrimaryTemplateArgs=True)
|
||||||
if symbol is None:
|
if symbol is None:
|
||||||
symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
||||||
templateParams=templateParams,
|
templateParams=templateParams,
|
||||||
@ -3746,7 +3749,8 @@ class Symbol(object):
|
|||||||
templateArgs,
|
templateArgs,
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False,
|
matchSelf=False,
|
||||||
recurseInAnon=True)
|
recurseInAnon=True,
|
||||||
|
correctPrimaryTemplateArgs=False)
|
||||||
if symbol:
|
if symbol:
|
||||||
if not declaration:
|
if not declaration:
|
||||||
# good, just a scope creation
|
# good, just a scope creation
|
||||||
@ -3797,7 +3801,8 @@ class Symbol(object):
|
|||||||
templateArgs=otherChild.templateArgs,
|
templateArgs=otherChild.templateArgs,
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False,
|
matchSelf=False,
|
||||||
recurseInAnon=False)
|
recurseInAnon=False,
|
||||||
|
correctPrimaryTemplateArgs=False)
|
||||||
if ourChild is None:
|
if ourChild is None:
|
||||||
# TODO: hmm, should we prune by docnames?
|
# TODO: hmm, should we prune by docnames?
|
||||||
self._children.append(otherChild)
|
self._children.append(otherChild)
|
||||||
@ -3860,7 +3865,8 @@ class Symbol(object):
|
|||||||
templateParams, templateArgs,
|
templateParams, templateArgs,
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False,
|
matchSelf=False,
|
||||||
recurseInAnon=False)
|
recurseInAnon=False,
|
||||||
|
correctPrimaryTemplateArgs=False)
|
||||||
if not s:
|
if not s:
|
||||||
return None
|
return None
|
||||||
return s
|
return s
|
||||||
@ -3911,7 +3917,8 @@ class Symbol(object):
|
|||||||
templateParams, templateArgs,
|
templateParams, templateArgs,
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf,
|
matchSelf=matchSelf,
|
||||||
recurseInAnon=recurseInAnon)
|
recurseInAnon=recurseInAnon,
|
||||||
|
correctPrimaryTemplateArgs=False)
|
||||||
if symbol is not None:
|
if symbol is not None:
|
||||||
return symbol
|
return symbol
|
||||||
# try without template params and args
|
# try without template params and args
|
||||||
@ -3919,7 +3926,8 @@ class Symbol(object):
|
|||||||
None, None,
|
None, None,
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf,
|
matchSelf=matchSelf,
|
||||||
recurseInAnon=recurseInAnon)
|
recurseInAnon=recurseInAnon,
|
||||||
|
correctPrimaryTemplateArgs=False)
|
||||||
return symbol
|
return symbol
|
||||||
else:
|
else:
|
||||||
identOrOp = name.identOrOp
|
identOrOp = name.identOrOp
|
||||||
@ -3933,9 +3941,13 @@ class Symbol(object):
|
|||||||
templateParams, templateArgs,
|
templateParams, templateArgs,
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf,
|
matchSelf=matchSelf,
|
||||||
recurseInAnon=recurseInAnon)
|
recurseInAnon=recurseInAnon,
|
||||||
|
correctPrimaryTemplateArgs=True)
|
||||||
if symbol is None:
|
if symbol is None:
|
||||||
# TODO: maybe search without template args
|
# TODO: Maybe search without template args?
|
||||||
|
# Though, the correctPrimaryTemplateArgs above does
|
||||||
|
# that for primary templates.
|
||||||
|
# Is there another case where it would be good?
|
||||||
return None
|
return None
|
||||||
# We have now matched part of a nested name, and need to match more
|
# We have now matched part of a nested name, and need to match more
|
||||||
# so even if we should matchSelf before, we definitely shouldn't
|
# so even if we should matchSelf before, we definitely shouldn't
|
||||||
@ -6343,6 +6355,7 @@ class CPPDomain(Domain):
|
|||||||
if not parentSymbol:
|
if not parentSymbol:
|
||||||
print("Target: ", target)
|
print("Target: ", target)
|
||||||
print("ParentKey: ", parentKey)
|
print("ParentKey: ", parentKey)
|
||||||
|
print(rootSymbol.dump(1))
|
||||||
assert parentSymbol # should be there
|
assert parentSymbol # should be there
|
||||||
else:
|
else:
|
||||||
parentSymbol = rootSymbol
|
parentSymbol = rootSymbol
|
||||||
|
Loading…
Reference in New Issue
Block a user