mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
C++, improve error messages for template parameter/argument lists
This commit is contained in:
parent
0dd09cb549
commit
1ab1e1c324
@ -5334,13 +5334,7 @@ class DefinitionParser(BaseParser):
|
||||
prevErrors.append((e, "If type argument"))
|
||||
self.pos = pos
|
||||
try:
|
||||
# actually here we shouldn't use the fallback parser (hence allow=False),
|
||||
# because if actually took the < in an expression, then we _will_ fail,
|
||||
# which is handled elsewhere. E.g., :cpp:expr:`A <= 0`.
|
||||
def parser():
|
||||
return self._parse_constant_expression(inTemplate=True)
|
||||
value = self._parse_expression_fallback(
|
||||
[',', '>'], parser, allow=False)
|
||||
value = self._parse_constant_expression(inTemplate=True)
|
||||
self.skip_ws()
|
||||
if self.skip_string('>'):
|
||||
parsedEnd = True
|
||||
@ -5460,7 +5454,6 @@ class DefinitionParser(BaseParser):
|
||||
if self.skip_word_and_ws(k):
|
||||
prefix = k
|
||||
break
|
||||
|
||||
nestedName = self._parse_nested_name()
|
||||
return ASTTrailingTypeSpecName(prefix, nestedName)
|
||||
|
||||
@ -5754,32 +5747,6 @@ class DefinitionParser(BaseParser):
|
||||
if typed and self.skip_string("..."):
|
||||
next = self._parse_declarator(named, paramMode, False)
|
||||
return ASTDeclaratorParamPack(next=next)
|
||||
if typed: # pointer to member
|
||||
pos = self.pos
|
||||
try:
|
||||
name = self._parse_nested_name(memberPointer=True)
|
||||
self.skip_ws()
|
||||
if not self.skip_string('*'):
|
||||
self.fail("Expected '*' in pointer to member declarator.")
|
||||
self.skip_ws()
|
||||
except DefinitionError as e:
|
||||
self.pos = pos
|
||||
prevErrors.append((e, "If pointer to member declarator"))
|
||||
else:
|
||||
volatile = False
|
||||
const = False
|
||||
while 1:
|
||||
if not volatile:
|
||||
volatile = self.skip_word_and_ws('volatile')
|
||||
if volatile:
|
||||
continue
|
||||
if not const:
|
||||
const = self.skip_word_and_ws('const')
|
||||
if const:
|
||||
continue
|
||||
break
|
||||
next = self._parse_declarator(named, paramMode, typed)
|
||||
return ASTDeclaratorMemPtr(name, const, volatile, next=next)
|
||||
if typed and self.current_char == '(': # note: peeking, not skipping
|
||||
if paramMode == "operatorCast":
|
||||
# TODO: we should be able to parse cast operators which return
|
||||
@ -5815,9 +5782,40 @@ class DefinitionParser(BaseParser):
|
||||
prevErrors.append((exNoPtrParen, "If parenthesis in noptr-declarator"))
|
||||
header = "Error in declarator"
|
||||
raise self._make_multi_error(prevErrors, header)
|
||||
if typed: # pointer to member
|
||||
pos = self.pos
|
||||
try:
|
||||
return self._parse_declarator_name_suffix(named, paramMode, typed)
|
||||
name = self._parse_nested_name(memberPointer=True)
|
||||
self.skip_ws()
|
||||
if not self.skip_string('*'):
|
||||
self.fail("Expected '*' in pointer to member declarator.")
|
||||
self.skip_ws()
|
||||
except DefinitionError as e:
|
||||
self.pos = pos
|
||||
prevErrors.append((e, "If pointer to member declarator"))
|
||||
else:
|
||||
volatile = False
|
||||
const = False
|
||||
while 1:
|
||||
if not volatile:
|
||||
volatile = self.skip_word_and_ws('volatile')
|
||||
if volatile:
|
||||
continue
|
||||
if not const:
|
||||
const = self.skip_word_and_ws('const')
|
||||
if const:
|
||||
continue
|
||||
break
|
||||
next = self._parse_declarator(named, paramMode, typed)
|
||||
return ASTDeclaratorMemPtr(name, const, volatile, next=next)
|
||||
pos = self.pos
|
||||
try:
|
||||
res = self._parse_declarator_name_suffix(named, paramMode, typed)
|
||||
# this is a heuristic for error messages, for when there is a < after a
|
||||
# nested name, but it was not a successful template argument list
|
||||
if self.current_char == '<':
|
||||
self.otherErrors.append(self._make_multi_error(prevErrors, ""))
|
||||
return res
|
||||
except DefinitionError as e:
|
||||
self.pos = pos
|
||||
prevErrors.append((e, "If declarator-id"))
|
||||
@ -5886,7 +5884,6 @@ class DefinitionParser(BaseParser):
|
||||
raise Exception('Internal error, unknown outer "%s".' % outer)
|
||||
if outer != 'operatorCast':
|
||||
assert named
|
||||
|
||||
if outer in ('type', 'function'):
|
||||
# We allow type objects to just be a name.
|
||||
# Some functions don't have normal return types: constructors,
|
||||
@ -6080,8 +6077,8 @@ class DefinitionParser(BaseParser):
|
||||
self.skip_ws()
|
||||
if not self.skip_string("<"):
|
||||
self.fail("Expected '<' after 'template'")
|
||||
while 1:
|
||||
prevErrors = []
|
||||
while 1:
|
||||
self.skip_ws()
|
||||
if self.skip_word('template'):
|
||||
# declare a tenplate template parameter
|
||||
@ -6134,6 +6131,7 @@ class DefinitionParser(BaseParser):
|
||||
if self.skip_string('>'):
|
||||
return ASTTemplateParams(templateParams)
|
||||
elif self.skip_string(','):
|
||||
prevErrors = []
|
||||
continue
|
||||
else:
|
||||
header = "Error in template parameter list."
|
||||
|
Loading…
Reference in New Issue
Block a user