Skip to content

Commit 1ef607b

Browse files
Merge pull request #7067 from jakobandersen/cpp-dependent-type-lookup
C++, suppress some warnings that can never be fixed
2 parents 82a465c + 3231b84 commit 1ef607b

File tree

4 files changed

+74
-26
lines changed

4 files changed

+74
-26
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Bugs fixed
5353
function overloads.
5454
* #5078: C++, fix cross reference lookup when a directive contains multiple
5555
declarations.
56+
* C++, suppress warnings for directly dependent typenames in cross references
57+
generated automatically in signatures.
5658

5759
Testing
5860
--------

sphinx/domains/cpp.py

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,8 +4300,10 @@ def direct_lookup(self, key: "LookupKey") -> "Symbol":
43004300

43014301
def find_name(self, nestedName: ASTNestedName, templateDecls: List[Any],
43024302
typ: str, templateShorthand: bool, matchSelf: bool,
4303-
recurseInAnon: bool, searchInSiblings: bool) -> List["Symbol"]:
4303+
recurseInAnon: bool, searchInSiblings: bool) -> Tuple[List["Symbol"], str]:
43044304
# templateShorthand: missing template parameter lists for templates is ok
4305+
# If the first component is None,
4306+
# then the second component _may_ be a string explaining why.
43054307
if Symbol.debug_lookup:
43064308
Symbol.debug_indent += 1
43074309
Symbol.debug_print("find_name:")
@@ -4316,6 +4318,9 @@ def find_name(self, nestedName: ASTNestedName, templateDecls: List[Any],
43164318
Symbol.debug_print("recurseInAnon: ", recurseInAnon)
43174319
Symbol.debug_print("searchInSiblings: ", searchInSiblings)
43184320

4321+
class QualifiedSymbolIsTemplateParam(Exception):
4322+
pass
4323+
43194324
def onMissingQualifiedSymbol(parentSymbol: "Symbol",
43204325
identOrOp: Union[ASTIdentifier, ASTOperator],
43214326
templateParams: Any,
@@ -4324,28 +4329,39 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol",
43244329
# Though, the correctPrimaryTemplateArgs does
43254330
# that for primary templates.
43264331
# Is there another case where it would be good?
4332+
if parentSymbol.declaration is not None:
4333+
if parentSymbol.declaration.objectType == 'templateParam':
4334+
raise QualifiedSymbolIsTemplateParam()
43274335
return None
43284336

4329-
lookupResult = self._symbol_lookup(nestedName, templateDecls,
4330-
onMissingQualifiedSymbol,
4331-
strictTemplateParamArgLists=False,
4332-
ancestorLookupType=typ,
4333-
templateShorthand=templateShorthand,
4334-
matchSelf=matchSelf,
4335-
recurseInAnon=recurseInAnon,
4336-
correctPrimaryTemplateArgs=False,
4337-
searchInSiblings=searchInSiblings)
4337+
try:
4338+
lookupResult = self._symbol_lookup(nestedName, templateDecls,
4339+
onMissingQualifiedSymbol,
4340+
strictTemplateParamArgLists=False,
4341+
ancestorLookupType=typ,
4342+
templateShorthand=templateShorthand,
4343+
matchSelf=matchSelf,
4344+
recurseInAnon=recurseInAnon,
4345+
correctPrimaryTemplateArgs=False,
4346+
searchInSiblings=searchInSiblings)
4347+
except QualifiedSymbolIsTemplateParam:
4348+
return None, "templateParamInQualified"
4349+
43384350
if lookupResult is None:
43394351
# if it was a part of the qualification that could not be found
43404352
if Symbol.debug_lookup:
43414353
Symbol.debug_indent -= 2
4342-
return None
4354+
return None, None
43434355

43444356
res = list(lookupResult.symbols)
43454357
if len(res) != 0:
43464358
if Symbol.debug_lookup:
43474359
Symbol.debug_indent -= 2
4348-
return res
4360+
return res, None
4361+
4362+
if lookupResult.parentSymbol.declaration is not None:
4363+
if lookupResult.parentSymbol.declaration.objectType == 'templateParam':
4364+
return None, "templateParamInQualified"
43494365

43504366
# try without template params and args
43514367
symbol = lookupResult.parentSymbol._find_first_named_symbol(
@@ -4355,9 +4371,9 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol",
43554371
if Symbol.debug_lookup:
43564372
Symbol.debug_indent -= 2
43574373
if symbol is not None:
4358-
return [symbol]
4374+
return [symbol], None
43594375
else:
4360-
return None
4376+
return None, None
43614377

43624378
def find_declaration(self, declaration: ASTDeclaration, typ: str, templateShorthand: bool,
43634379
matchSelf: bool, recurseInAnon: bool) -> "Symbol":
@@ -6778,12 +6794,13 @@ def warn(self, msg):
67786794
templateDecls = ns.templatePrefix.templates
67796795
else:
67806796
templateDecls = []
6781-
symbols = parentSymbol.find_name(nestedName=name,
6782-
templateDecls=templateDecls,
6783-
typ='any',
6784-
templateShorthand=True,
6785-
matchSelf=True, recurseInAnon=True,
6786-
searchInSiblings=False)
6797+
symbols, failReason = parentSymbol.find_name(
6798+
nestedName=name,
6799+
templateDecls=templateDecls,
6800+
typ='any',
6801+
templateShorthand=True,
6802+
matchSelf=True, recurseInAnon=True,
6803+
searchInSiblings=False)
67876804
if symbols is None:
67886805
symbols = []
67896806
else:
@@ -7089,12 +7106,21 @@ def findWarning(e): # as arg to stop flake8 from complaining
70897106
templateDecls = []
70907107
# let's be conservative with the sibling lookup for now
70917108
searchInSiblings = (not name.rooted) and len(name.names) == 1
7092-
symbols = parentSymbol.find_name(name, templateDecls, typ,
7093-
templateShorthand=True,
7094-
matchSelf=True, recurseInAnon=True,
7095-
searchInSiblings=searchInSiblings)
7096-
# just refer to the arbitrarily first symbol
7097-
s = None if symbols is None else symbols[0]
7109+
symbols, failReason = parentSymbol.find_name(
7110+
name, templateDecls, typ,
7111+
templateShorthand=True,
7112+
matchSelf=True, recurseInAnon=True,
7113+
searchInSiblings=searchInSiblings)
7114+
if symbols is None:
7115+
if typ == 'identifier':
7116+
if failReason == 'templateParamInQualified':
7117+
# this is an xref we created as part of a signature,
7118+
# so don't warn for names nested in template parameters
7119+
raise NoUri(str(name), typ)
7120+
s = None
7121+
else:
7122+
# just refer to the arbitrarily first symbol
7123+
s = symbols[0]
70987124
else:
70997125
decl = ast # type: ASTDeclaration
71007126
name = decl.name
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.. default-domain:: cpp
2+
3+
.. class:: template<typename T> A
4+
5+
.. type:: N1 = T::typeOk
6+
7+
- Not ok, warn: :type:`T::typeWarn`
8+
9+
.. type:: N2 = T::U::typeOk
10+
11+
- Not ok, warn: :type:`T::U::typeWarn`

tests/test_domain_cpp.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,15 @@ def test_build_domain_cpp_multi_decl_lookup(app, status, warning):
806806
assert len(ws) == 0
807807

808808

809+
@pytest.mark.sphinx(testroot='domain-cpp', confoverrides={'nitpicky': True})
810+
def test_build_domain_cpp_warn_template_param_qualified_name(app, status, warning):
811+
app.builder.build_all()
812+
ws = filter_warnings(warning, "warn-template-param-qualified-name")
813+
assert len(ws) == 2
814+
assert "WARNING: cpp:type reference target not found: T::typeWarn" in ws[0]
815+
assert "WARNING: cpp:type reference target not found: T::U::typeWarn" in ws[1]
816+
817+
809818
@pytest.mark.sphinx(testroot='domain-cpp')
810819
def test_build_domain_cpp_misuse_of_roles(app, status, warning):
811820
app.builder.build_all()

0 commit comments

Comments
 (0)