mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, fix handling of (templated) operators
This commit is contained in:
parent
324bc7e3c4
commit
f3c05adebc
@ -1408,9 +1408,9 @@ class ASTTemplateParamNonType(ASTBase):
|
|||||||
name = self.param.name
|
name = self.param.name
|
||||||
if name:
|
if name:
|
||||||
assert len(name.names) == 1
|
assert len(name.names) == 1
|
||||||
assert name.names[0].identifier
|
assert name.names[0].identOrOp
|
||||||
assert not name.names[0].templateArgs
|
assert not name.names[0].templateArgs
|
||||||
return name.names[0].identifier
|
return name.names[0].identOrOp
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -1650,8 +1650,8 @@ class ASTOperatorBuildIn(ASTBase):
|
|||||||
else:
|
else:
|
||||||
return u'operator' + self.op
|
return u'operator' + self.op
|
||||||
|
|
||||||
def describe_signature(self, signode, mode, env, prefix, symbol):
|
def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
|
||||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
# type: (addnodes.desc_signature, unicode, Any, unicode, unicode, Symbol) -> None
|
||||||
_verify_description_mode(mode)
|
_verify_description_mode(mode)
|
||||||
identifier = text_type(self)
|
identifier = text_type(self)
|
||||||
if mode == 'lastIsName':
|
if mode == 'lastIsName':
|
||||||
@ -1684,7 +1684,7 @@ class ASTOperatorType(ASTBase):
|
|||||||
# type: () -> unicode
|
# type: () -> unicode
|
||||||
return text_type(self)
|
return text_type(self)
|
||||||
|
|
||||||
def describe_signature(self, signode, mode, env, prefix, symbol):
|
def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
|
||||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
||||||
_verify_description_mode(mode)
|
_verify_description_mode(mode)
|
||||||
identifier = text_type(self)
|
identifier = text_type(self)
|
||||||
@ -1714,7 +1714,7 @@ class ASTOperatorLiteral(ASTBase):
|
|||||||
# type: () -> unicode
|
# type: () -> unicode
|
||||||
return u'operator""' + text_type(self.identifier)
|
return u'operator""' + text_type(self.identifier)
|
||||||
|
|
||||||
def describe_signature(self, signode, mode, env, prefix, symbol):
|
def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
|
||||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
||||||
_verify_description_mode(mode)
|
_verify_description_mode(mode)
|
||||||
identifier = text_type(self)
|
identifier = text_type(self)
|
||||||
@ -1788,9 +1788,9 @@ class ASTTemplateArgs(ASTBase):
|
|||||||
|
|
||||||
|
|
||||||
class ASTNestedNameElement(ASTBase):
|
class ASTNestedNameElement(ASTBase):
|
||||||
def __init__(self, identifier, templateArgs):
|
def __init__(self, identOrOp, templateArgs):
|
||||||
# type: (Any, Any) -> None
|
# type: (Any, Any) -> None
|
||||||
self.identifier = identifier
|
self.identOrOp = identOrOp
|
||||||
self.templateArgs = templateArgs
|
self.templateArgs = templateArgs
|
||||||
|
|
||||||
def is_operator(self):
|
def is_operator(self):
|
||||||
@ -1799,14 +1799,14 @@ class ASTNestedNameElement(ASTBase):
|
|||||||
|
|
||||||
def get_id(self, version):
|
def get_id(self, version):
|
||||||
# type: (int) -> unicode
|
# type: (int) -> unicode
|
||||||
res = self.identifier.get_id(version)
|
res = self.identOrOp.get_id(version)
|
||||||
if self.templateArgs:
|
if self.templateArgs:
|
||||||
res += self.templateArgs.get_id(version)
|
res += self.templateArgs.get_id(version)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
# type: () -> unicode
|
# type: () -> unicode
|
||||||
res = text_type(self.identifier)
|
res = text_type(self.identOrOp)
|
||||||
if self.templateArgs:
|
if self.templateArgs:
|
||||||
res += text_type(self.templateArgs)
|
res += text_type(self.templateArgs)
|
||||||
return res
|
return res
|
||||||
@ -1814,7 +1814,7 @@ class ASTNestedNameElement(ASTBase):
|
|||||||
def describe_signature(self, signode, mode, env, prefix, symbol):
|
def describe_signature(self, signode, mode, env, prefix, symbol):
|
||||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
|
||||||
tArgs = text_type(self.templateArgs) if self.templateArgs is not None else ''
|
tArgs = text_type(self.templateArgs) if self.templateArgs is not None else ''
|
||||||
self.identifier.describe_signature(signode, mode, env, prefix, tArgs, symbol)
|
self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol)
|
||||||
if self.templateArgs is not None:
|
if self.templateArgs is not None:
|
||||||
self.templateArgs.describe_signature(signode, mode, env, symbol)
|
self.templateArgs.describe_signature(signode, mode, env, symbol)
|
||||||
|
|
||||||
@ -3310,23 +3310,20 @@ class Symbol(object):
|
|||||||
# type: () -> None
|
# type: () -> None
|
||||||
if not self.parent:
|
if not self.parent:
|
||||||
# parent == None means global scope, so declaration means a parent
|
# parent == None means global scope, so declaration means a parent
|
||||||
assert not self.identifier
|
assert not self.identOrOp
|
||||||
assert not self.templateParams
|
assert not self.templateParams
|
||||||
assert not self.templateArgs
|
assert not self.templateArgs
|
||||||
assert not self.declaration
|
assert not self.declaration
|
||||||
assert not self.docname
|
assert not self.docname
|
||||||
else:
|
else:
|
||||||
if not self.identifier:
|
|
||||||
# in case it's an operator
|
|
||||||
assert self.declaration
|
|
||||||
if self.declaration:
|
if self.declaration:
|
||||||
assert self.docname
|
assert self.docname
|
||||||
|
|
||||||
def __init__(self, parent, identifier,
|
def __init__(self, parent, identOrOp,
|
||||||
templateParams, templateArgs, declaration, docname):
|
templateParams, templateArgs, declaration, docname):
|
||||||
# type: (Any, Any, Any, Any, Any, unicode) -> None
|
# type: (Any, Any, Any, Any, Any, unicode) -> None
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.identifier = identifier
|
self.identOrOp = identOrOp
|
||||||
self.templateParams = templateParams # template<templateParams>
|
self.templateParams = templateParams # template<templateParams>
|
||||||
self.templateArgs = templateArgs # identifier<templateArgs>
|
self.templateArgs = templateArgs # identifier<templateArgs>
|
||||||
self.declaration = declaration
|
self.declaration = declaration
|
||||||
@ -3365,8 +3362,8 @@ class Symbol(object):
|
|||||||
decl = ASTDeclaration('functionParam', None, None, p)
|
decl = ASTDeclaration('functionParam', None, None, p)
|
||||||
assert not nn.rooted
|
assert not nn.rooted
|
||||||
assert len(nn.names) == 1
|
assert len(nn.names) == 1
|
||||||
identifier = nn.names[0].identifier
|
identOrOp = nn.names[0].identOrOp
|
||||||
Symbol(parent=self, identifier=identifier,
|
Symbol(parent=self, identOrOp=identOrOp,
|
||||||
templateParams=None, templateArgs=None,
|
templateParams=None, templateArgs=None,
|
||||||
declaration=decl, docname=docname)
|
declaration=decl, docname=docname)
|
||||||
|
|
||||||
@ -3390,12 +3387,7 @@ class Symbol(object):
|
|||||||
if sChild.declaration and sChild.docname == docname:
|
if sChild.declaration and sChild.docname == docname:
|
||||||
sChild.declaration = None
|
sChild.declaration = None
|
||||||
sChild.docname = None
|
sChild.docname = None
|
||||||
# Just remove operators, because there is no identification if
|
newChildren.append(sChild)
|
||||||
# they got removed.
|
|
||||||
# Don't remove other symbols because they may be used in namespace
|
|
||||||
# directives.
|
|
||||||
if sChild.identifier or sChild.declaration:
|
|
||||||
newChildren.append(sChild)
|
|
||||||
self.children = newChildren
|
self.children = newChildren
|
||||||
|
|
||||||
def get_all_symbols(self):
|
def get_all_symbols(self):
|
||||||
@ -3415,11 +3407,7 @@ class Symbol(object):
|
|||||||
symbols.reverse()
|
symbols.reverse()
|
||||||
key = []
|
key = []
|
||||||
for s in symbols:
|
for s in symbols:
|
||||||
if s.identifier:
|
nne = ASTNestedNameElement(s.identOrOp, s.templateArgs)
|
||||||
nne = ASTNestedNameElement(s.identifier, s.templateArgs)
|
|
||||||
else:
|
|
||||||
assert s.declaration
|
|
||||||
nne = s.declaration.name.names[-1]
|
|
||||||
key.append((nne, s.templateParams))
|
key.append((nne, s.templateParams))
|
||||||
return key
|
return key
|
||||||
|
|
||||||
@ -3432,11 +3420,9 @@ class Symbol(object):
|
|||||||
templates.append(False)
|
templates.append(False)
|
||||||
return ASTNestedName(names, templates, rooted=False)
|
return ASTNestedName(names, templates, rooted=False)
|
||||||
|
|
||||||
def _find_named_symbol(self, identifier, templateParams,
|
def _find_named_symbol(self, identOrOp, templateParams, templateArgs,
|
||||||
templateArgs, operator,
|
|
||||||
templateShorthand, matchSelf):
|
templateShorthand, matchSelf):
|
||||||
# type: (Any, Any, Any, Any, Any, bool) -> Symbol
|
# type: (Any, Any, Any, Any, bool) -> Symbol
|
||||||
assert (identifier is None) != (operator is None)
|
|
||||||
|
|
||||||
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
|
||||||
@ -3464,17 +3450,8 @@ class Symbol(object):
|
|||||||
templateArgs = None
|
templateArgs = None
|
||||||
|
|
||||||
def matches(s):
|
def matches(s):
|
||||||
if s.identifier != identifier:
|
if s.identOrOp != identOrOp:
|
||||||
return False
|
return False
|
||||||
if not s.identifier:
|
|
||||||
if not s.declaration:
|
|
||||||
return False
|
|
||||||
assert operator
|
|
||||||
name = s.declaration.name.names[-1]
|
|
||||||
if not name.is_operator():
|
|
||||||
return False
|
|
||||||
if text_type(name) != text_type(operator):
|
|
||||||
return False
|
|
||||||
if (s.templateParams is None) != (templateParams is None):
|
if (s.templateParams is None) != (templateParams is None):
|
||||||
if templateParams is not None:
|
if templateParams is not None:
|
||||||
# we query with params, they must match params
|
# we query with params, they must match params
|
||||||
@ -3515,10 +3492,7 @@ class Symbol(object):
|
|||||||
names = nestedName.names
|
names = nestedName.names
|
||||||
iTemplateDecl = 0
|
iTemplateDecl = 0
|
||||||
for name in names[:-1]:
|
for name in names[:-1]:
|
||||||
# there shouldn't be anything inside an operator
|
identOrOp = name.identOrOp
|
||||||
# (other than template parameters, which are not added this way, right?)
|
|
||||||
assert not name.is_operator()
|
|
||||||
identifier = name.identifier
|
|
||||||
templateArgs = name.templateArgs
|
templateArgs = name.templateArgs
|
||||||
if templateArgs:
|
if templateArgs:
|
||||||
assert iTemplateDecl < len(templateDecls)
|
assert iTemplateDecl < len(templateDecls)
|
||||||
@ -3526,27 +3500,20 @@ class Symbol(object):
|
|||||||
iTemplateDecl += 1
|
iTemplateDecl += 1
|
||||||
else:
|
else:
|
||||||
templateParams = None
|
templateParams = None
|
||||||
symbol = parentSymbol._find_named_symbol(identifier,
|
symbol = parentSymbol._find_named_symbol(identOrOp,
|
||||||
templateParams,
|
templateParams,
|
||||||
templateArgs,
|
templateArgs,
|
||||||
operator=None,
|
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False)
|
matchSelf=False)
|
||||||
if symbol is None:
|
if symbol is None:
|
||||||
symbol = Symbol(parent=parentSymbol, identifier=identifier,
|
symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
||||||
templateParams=templateParams,
|
templateParams=templateParams,
|
||||||
templateArgs=templateArgs, declaration=None,
|
templateArgs=templateArgs, declaration=None,
|
||||||
docname=None)
|
docname=None)
|
||||||
parentSymbol = symbol
|
parentSymbol = symbol
|
||||||
name = names[-1]
|
name = names[-1]
|
||||||
if name.is_operator():
|
identOrOp = name.identOrOp
|
||||||
identifier = None
|
templateArgs = name.templateArgs
|
||||||
templateArgs = None
|
|
||||||
operator = name
|
|
||||||
else:
|
|
||||||
identifier = name.identifier
|
|
||||||
templateArgs = name.templateArgs
|
|
||||||
operator = None
|
|
||||||
if iTemplateDecl < len(templateDecls):
|
if iTemplateDecl < len(templateDecls):
|
||||||
if iTemplateDecl + 1 != len(templateDecls):
|
if iTemplateDecl + 1 != len(templateDecls):
|
||||||
print(text_type(templateDecls))
|
print(text_type(templateDecls))
|
||||||
@ -3556,10 +3523,9 @@ class Symbol(object):
|
|||||||
else:
|
else:
|
||||||
assert iTemplateDecl == len(templateDecls)
|
assert iTemplateDecl == len(templateDecls)
|
||||||
templateParams = None
|
templateParams = None
|
||||||
symbol = parentSymbol._find_named_symbol(identifier,
|
symbol = parentSymbol._find_named_symbol(identOrOp,
|
||||||
templateParams,
|
templateParams,
|
||||||
templateArgs,
|
templateArgs,
|
||||||
operator,
|
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False)
|
matchSelf=False)
|
||||||
if symbol:
|
if symbol:
|
||||||
@ -3576,7 +3542,7 @@ class Symbol(object):
|
|||||||
return symbol
|
return symbol
|
||||||
# It may simply be a function overload, so let's compare ids.
|
# It may simply be a function overload, so let's compare ids.
|
||||||
isRedeclaration = True
|
isRedeclaration = True
|
||||||
candSymbol = Symbol(parent=parentSymbol, identifier=identifier,
|
candSymbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
||||||
templateParams=templateParams,
|
templateParams=templateParams,
|
||||||
templateArgs=templateArgs,
|
templateArgs=templateArgs,
|
||||||
declaration=declaration,
|
declaration=declaration,
|
||||||
@ -3596,7 +3562,7 @@ class Symbol(object):
|
|||||||
candSymbol.isRedeclaration = True
|
candSymbol.isRedeclaration = True
|
||||||
raise _DuplicateSymbolError(symbol, declaration)
|
raise _DuplicateSymbolError(symbol, declaration)
|
||||||
else:
|
else:
|
||||||
symbol = Symbol(parent=parentSymbol, identifier=identifier,
|
symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
|
||||||
templateParams=templateParams,
|
templateParams=templateParams,
|
||||||
templateArgs=templateArgs,
|
templateArgs=templateArgs,
|
||||||
declaration=declaration,
|
declaration=declaration,
|
||||||
@ -3667,12 +3633,12 @@ class Symbol(object):
|
|||||||
templateDecls = []
|
templateDecls = []
|
||||||
return self._add_symbols(nestedName, templateDecls, declaration, docname)
|
return self._add_symbols(nestedName, templateDecls, declaration, docname)
|
||||||
|
|
||||||
def find_identifier(self, identifier, matchSelf):
|
def find_identifier(self, identOrOp, matchSelf):
|
||||||
# type: (Any, bool) -> Symbol
|
# type: (Any, bool) -> Symbol
|
||||||
if matchSelf and self.identifier and self.identifier == identifier:
|
if matchSelf and self.identOrOp == identOrOp:
|
||||||
return self
|
return self
|
||||||
for s in self.children:
|
for s in self.children:
|
||||||
if s.identifier and s.identifier == identifier:
|
if s.identOrOp == identOrOp:
|
||||||
return s
|
return s
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -3680,16 +3646,10 @@ class Symbol(object):
|
|||||||
# type: (List[Tuple[Any, Any]]) -> Symbol
|
# type: (List[Tuple[Any, Any]]) -> Symbol
|
||||||
s = self
|
s = self
|
||||||
for name, templateParams in key:
|
for name, templateParams in key:
|
||||||
if name.is_operator():
|
identOrOp = name.identOrOp
|
||||||
identifier = None
|
templateArgs = name.templateArgs
|
||||||
templateArgs = None
|
s = s._find_named_symbol(identOrOp,
|
||||||
operator = name
|
templateParams, templateArgs,
|
||||||
else:
|
|
||||||
identifier = name.identifier
|
|
||||||
templateArgs = name.templateArgs
|
|
||||||
operator = None
|
|
||||||
s = s._find_named_symbol(identifier, templateParams,
|
|
||||||
templateArgs, operator,
|
|
||||||
templateShorthand=False,
|
templateShorthand=False,
|
||||||
matchSelf=False)
|
matchSelf=False)
|
||||||
if not s:
|
if not s:
|
||||||
@ -3713,13 +3673,13 @@ class Symbol(object):
|
|||||||
firstName = names[0]
|
firstName = names[0]
|
||||||
if not firstName.is_operator():
|
if not firstName.is_operator():
|
||||||
while parentSymbol.parent:
|
while parentSymbol.parent:
|
||||||
if parentSymbol.find_identifier(firstName.identifier,
|
if parentSymbol.find_identifier(firstName.identOrOp,
|
||||||
matchSelf=matchSelf):
|
matchSelf=matchSelf):
|
||||||
# if we are in the scope of a constructor but wants to reference the class
|
# if we are in the scope of a constructor but wants to reference the class
|
||||||
# we need to walk one extra up
|
# we need to walk one extra up
|
||||||
if (len(names) == 1 and typ == 'class' and matchSelf and
|
if (len(names) == 1 and typ == 'class' and matchSelf and
|
||||||
parentSymbol.parent and parentSymbol.parent.identifier and
|
parentSymbol.parent and
|
||||||
parentSymbol.parent.identifier == firstName.identifier):
|
parentSymbol.parent.identOrOp == firstName.identOrOp):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@ -3728,48 +3688,36 @@ class Symbol(object):
|
|||||||
for iName in range(len(names)):
|
for iName in range(len(names)):
|
||||||
name = names[iName]
|
name = names[iName]
|
||||||
if iName + 1 == len(names):
|
if iName + 1 == len(names):
|
||||||
if name.is_operator():
|
identOrOp = name.identOrOp
|
||||||
identifier = None
|
templateArgs = name.templateArgs
|
||||||
templateArgs = None
|
|
||||||
operator = name
|
|
||||||
else:
|
|
||||||
identifier = name.identifier
|
|
||||||
templateArgs = name.templateArgs
|
|
||||||
operator = None
|
|
||||||
if iTemplateDecl < len(templateDecls):
|
if iTemplateDecl < len(templateDecls):
|
||||||
assert iTemplateDecl + 1 == len(templateDecls)
|
assert iTemplateDecl + 1 == len(templateDecls)
|
||||||
templateParams = templateDecls[iTemplateDecl]
|
templateParams = templateDecls[iTemplateDecl]
|
||||||
else:
|
else:
|
||||||
assert iTemplateDecl == len(templateDecls)
|
assert iTemplateDecl == len(templateDecls)
|
||||||
templateParams = None
|
templateParams = None
|
||||||
symbol = parentSymbol._find_named_symbol(identifier,
|
symbol = parentSymbol._find_named_symbol(identOrOp,
|
||||||
templateParams, templateArgs,
|
templateParams, templateArgs,
|
||||||
operator,
|
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf)
|
matchSelf=matchSelf)
|
||||||
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
|
||||||
symbol = parentSymbol._find_named_symbol(identifier,
|
symbol = parentSymbol._find_named_symbol(identOrOp,
|
||||||
None, None,
|
None, None,
|
||||||
operator,
|
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf)
|
matchSelf=matchSelf)
|
||||||
return symbol
|
return symbol
|
||||||
else:
|
else:
|
||||||
# there shouldn't be anything inside an operator
|
identOrOp = name.identOrOp
|
||||||
assert not name.is_operator()
|
|
||||||
identifier = name.identifier
|
|
||||||
templateArgs = name.templateArgs
|
templateArgs = name.templateArgs
|
||||||
if templateArgs and iTemplateDecl < len(templateDecls):
|
if templateArgs and iTemplateDecl < len(templateDecls):
|
||||||
templateParams = templateDecls[iTemplateDecl]
|
templateParams = templateDecls[iTemplateDecl]
|
||||||
iTemplateDecl += 1
|
iTemplateDecl += 1
|
||||||
else:
|
else:
|
||||||
templateParams = None
|
templateParams = None
|
||||||
symbol = parentSymbol._find_named_symbol(identifier,
|
symbol = parentSymbol._find_named_symbol(identOrOp,
|
||||||
templateParams,
|
templateParams, templateArgs,
|
||||||
templateArgs,
|
|
||||||
operator=None,
|
|
||||||
templateShorthand=templateShorthand,
|
templateShorthand=templateShorthand,
|
||||||
matchSelf=matchSelf)
|
matchSelf=matchSelf)
|
||||||
if symbol is None:
|
if symbol is None:
|
||||||
@ -3792,8 +3740,8 @@ class Symbol(object):
|
|||||||
res.append(text_type(self.templateParams))
|
res.append(text_type(self.templateParams))
|
||||||
res.append('\n')
|
res.append('\n')
|
||||||
res.append('\t' * indent)
|
res.append('\t' * indent)
|
||||||
if self.identifier:
|
if self.identOrOp:
|
||||||
res.append(text_type(self.identifier))
|
res.append(text_type(self.identOrOp))
|
||||||
else:
|
else:
|
||||||
res.append(text_type(self.declaration))
|
res.append(text_type(self.declaration))
|
||||||
if self.templateArgs:
|
if self.templateArgs:
|
||||||
@ -4561,8 +4509,7 @@ class DefinitionParser(object):
|
|||||||
template = False
|
template = False
|
||||||
templates.append(template)
|
templates.append(template)
|
||||||
if self.skip_word_and_ws('operator'):
|
if self.skip_word_and_ws('operator'):
|
||||||
op = self._parse_operator()
|
identOrOp = self._parse_operator()
|
||||||
names.append(op)
|
|
||||||
else:
|
else:
|
||||||
if not self.match(_identifier_re):
|
if not self.match(_identifier_re):
|
||||||
if memberPointer and len(names) > 0:
|
if memberPointer and len(names) > 0:
|
||||||
@ -4574,17 +4521,17 @@ class DefinitionParser(object):
|
|||||||
if identifier in _keywords:
|
if identifier in _keywords:
|
||||||
self.fail("Expected identifier in nested name, "
|
self.fail("Expected identifier in nested name, "
|
||||||
"got keyword: %s" % identifier)
|
"got keyword: %s" % identifier)
|
||||||
# try greedily to get template parameters,
|
identOrOp = ASTIdentifier(identifier) # type: ignore
|
||||||
# but otherwise a < might be because we are in an expression
|
# try greedily to get template arguments,
|
||||||
pos = self.pos
|
# but otherwise a < might be because we are in an expression
|
||||||
try:
|
pos = self.pos
|
||||||
templateArgs = self._parse_template_argument_list()
|
try:
|
||||||
except DefinitionError as ex:
|
templateArgs = self._parse_template_argument_list()
|
||||||
self.pos = pos
|
except DefinitionError as ex:
|
||||||
templateArgs = None
|
self.pos = pos
|
||||||
self.otherErrors.append(ex)
|
templateArgs = None
|
||||||
identifier = ASTIdentifier(identifier) # type: ignore
|
self.otherErrors.append(ex)
|
||||||
names.append(ASTNestedNameElement(identifier, templateArgs))
|
names.append(ASTNestedNameElement(identOrOp, templateArgs))
|
||||||
|
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if not self.skip_string('::'):
|
if not self.skip_string('::'):
|
||||||
@ -5532,7 +5479,7 @@ class CPPObject(ObjectDescription):
|
|||||||
# then add the name to the parent scope
|
# then add the name to the parent scope
|
||||||
symbol = ast.symbol
|
symbol = ast.symbol
|
||||||
assert symbol
|
assert symbol
|
||||||
assert symbol.identifier is not None
|
assert symbol.identOrOp is not None
|
||||||
assert symbol.templateParams is None
|
assert symbol.templateParams is None
|
||||||
assert symbol.templateArgs is None
|
assert symbol.templateArgs is None
|
||||||
parentSymbol = symbol.parent
|
parentSymbol = symbol.parent
|
||||||
@ -5545,7 +5492,7 @@ class CPPObject(ObjectDescription):
|
|||||||
if parentDecl is None:
|
if parentDecl is None:
|
||||||
# the parent is not explicitly declared
|
# the parent is not explicitly declared
|
||||||
# TODO: we could warn, but it could be a style to just assume
|
# TODO: we could warn, but it could be a style to just assume
|
||||||
# enumerator parnets to be scoped
|
# enumerator parents to be scoped
|
||||||
return
|
return
|
||||||
if parentDecl.objectType != 'enum':
|
if parentDecl.objectType != 'enum':
|
||||||
# TODO: maybe issue a warning, enumerators in non-enums is weird,
|
# TODO: maybe issue a warning, enumerators in non-enums is weird,
|
||||||
@ -5555,13 +5502,13 @@ class CPPObject(ObjectDescription):
|
|||||||
return
|
return
|
||||||
|
|
||||||
targetSymbol = parentSymbol.parent
|
targetSymbol = parentSymbol.parent
|
||||||
s = targetSymbol.find_identifier(symbol.identifier, matchSelf=False)
|
s = targetSymbol.find_identifier(symbol.identOrOp, matchSelf=False)
|
||||||
if s is not None:
|
if s is not None:
|
||||||
# something is already declared with that name
|
# something is already declared with that name
|
||||||
return
|
return
|
||||||
declClone = symbol.declaration.clone()
|
declClone = symbol.declaration.clone()
|
||||||
declClone.enumeratorScopedSymbol = symbol
|
declClone.enumeratorScopedSymbol = symbol
|
||||||
Symbol(parent=targetSymbol, identifier=symbol.identifier,
|
Symbol(parent=targetSymbol, identOrOp=symbol.identOrOp,
|
||||||
templateParams=None, templateArgs=None,
|
templateParams=None, templateArgs=None,
|
||||||
declaration=declClone,
|
declaration=declClone,
|
||||||
docname=self.env.docname)
|
docname=self.env.docname)
|
||||||
|
@ -28,14 +28,20 @@ directives
|
|||||||
|
|
||||||
An unscoped enum.
|
An unscoped enum.
|
||||||
|
|
||||||
|
.. cpp:enumerator:: A
|
||||||
|
|
||||||
.. cpp:enum-class:: MyScopedEnum
|
.. cpp:enum-class:: MyScopedEnum
|
||||||
|
|
||||||
A scoped enum.
|
A scoped enum.
|
||||||
|
|
||||||
|
.. cpp:enumerator:: B
|
||||||
|
|
||||||
.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type
|
.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type
|
||||||
|
|
||||||
A scoped enum with non-default visibility, and with a specified underlying type.
|
A scoped enum with non-default visibility, and with a specified underlying type.
|
||||||
|
|
||||||
|
.. cpp:enumerator:: B
|
||||||
|
|
||||||
|
|
||||||
.. cpp:function:: void paren_1(int, float)
|
.. cpp:function:: void paren_1(int, float)
|
||||||
.. cpp:function:: void paren_2(int, float)
|
.. cpp:function:: void paren_2(int, float)
|
||||||
|
@ -205,6 +205,9 @@ def test_expressions():
|
|||||||
check('class', "template<int T = 42> A", {2: "I_iE1A"})
|
check('class', "template<int T = 42> A", {2: "I_iE1A"})
|
||||||
check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"})
|
check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"})
|
||||||
|
|
||||||
|
exprCheck('operator()()', 'clclE')
|
||||||
|
exprCheck('operator()<int>()', 'clclIiEE')
|
||||||
|
|
||||||
|
|
||||||
def test_type_definitions():
|
def test_type_definitions():
|
||||||
check("type", "public bool b", {1: "b", 2: "1b"}, "bool b")
|
check("type", "public bool b", {1: "b", 2: "1b"}, "bool b")
|
||||||
@ -245,6 +248,10 @@ def test_type_definitions():
|
|||||||
|
|
||||||
check('type', 'T = A::template B<int>::template C<double>', {2: '1T'})
|
check('type', 'T = A::template B<int>::template C<double>', {2: '1T'})
|
||||||
|
|
||||||
|
check('type', 'T = Q<A::operator()>', {2: '1T'})
|
||||||
|
check('type', 'T = Q<A::operator()<int>>', {2: '1T'})
|
||||||
|
check('type', 'T = Q<A::operator bool>', {2: '1T'})
|
||||||
|
|
||||||
|
|
||||||
def test_concept_definitions():
|
def test_concept_definitions():
|
||||||
check('concept', 'template<typename Param> A::B::Concept',
|
check('concept', 'template<typename Param> A::B::Concept',
|
||||||
|
Loading…
Reference in New Issue
Block a user