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"))
|
prevErrors.append((e, "If type argument"))
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
try:
|
try:
|
||||||
# actually here we shouldn't use the fallback parser (hence allow=False),
|
value = self._parse_constant_expression(inTemplate=True)
|
||||||
# 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)
|
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if self.skip_string('>'):
|
if self.skip_string('>'):
|
||||||
parsedEnd = True
|
parsedEnd = True
|
||||||
@ -5460,7 +5454,6 @@ class DefinitionParser(BaseParser):
|
|||||||
if self.skip_word_and_ws(k):
|
if self.skip_word_and_ws(k):
|
||||||
prefix = k
|
prefix = k
|
||||||
break
|
break
|
||||||
|
|
||||||
nestedName = self._parse_nested_name()
|
nestedName = self._parse_nested_name()
|
||||||
return ASTTrailingTypeSpecName(prefix, nestedName)
|
return ASTTrailingTypeSpecName(prefix, nestedName)
|
||||||
|
|
||||||
@ -5754,32 +5747,6 @@ class DefinitionParser(BaseParser):
|
|||||||
if typed and self.skip_string("..."):
|
if typed and self.skip_string("..."):
|
||||||
next = self._parse_declarator(named, paramMode, False)
|
next = self._parse_declarator(named, paramMode, False)
|
||||||
return ASTDeclaratorParamPack(next=next)
|
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 typed and self.current_char == '(': # note: peeking, not skipping
|
||||||
if paramMode == "operatorCast":
|
if paramMode == "operatorCast":
|
||||||
# TODO: we should be able to parse cast operators which return
|
# 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"))
|
prevErrors.append((exNoPtrParen, "If parenthesis in noptr-declarator"))
|
||||||
header = "Error in declarator"
|
header = "Error in declarator"
|
||||||
raise self._make_multi_error(prevErrors, header)
|
raise self._make_multi_error(prevErrors, header)
|
||||||
|
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)
|
||||||
pos = self.pos
|
pos = self.pos
|
||||||
try:
|
try:
|
||||||
return self._parse_declarator_name_suffix(named, paramMode, typed)
|
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:
|
except DefinitionError as e:
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
prevErrors.append((e, "If declarator-id"))
|
prevErrors.append((e, "If declarator-id"))
|
||||||
@ -5886,7 +5884,6 @@ class DefinitionParser(BaseParser):
|
|||||||
raise Exception('Internal error, unknown outer "%s".' % outer)
|
raise Exception('Internal error, unknown outer "%s".' % outer)
|
||||||
if outer != 'operatorCast':
|
if outer != 'operatorCast':
|
||||||
assert named
|
assert named
|
||||||
|
|
||||||
if outer in ('type', 'function'):
|
if outer in ('type', 'function'):
|
||||||
# We allow type objects to just be a name.
|
# We allow type objects to just be a name.
|
||||||
# Some functions don't have normal return types: constructors,
|
# Some functions don't have normal return types: constructors,
|
||||||
@ -6080,8 +6077,8 @@ class DefinitionParser(BaseParser):
|
|||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if not self.skip_string("<"):
|
if not self.skip_string("<"):
|
||||||
self.fail("Expected '<' after 'template'")
|
self.fail("Expected '<' after 'template'")
|
||||||
|
prevErrors = []
|
||||||
while 1:
|
while 1:
|
||||||
prevErrors = []
|
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if self.skip_word('template'):
|
if self.skip_word('template'):
|
||||||
# declare a tenplate template parameter
|
# declare a tenplate template parameter
|
||||||
@ -6134,6 +6131,7 @@ class DefinitionParser(BaseParser):
|
|||||||
if self.skip_string('>'):
|
if self.skip_string('>'):
|
||||||
return ASTTemplateParams(templateParams)
|
return ASTTemplateParams(templateParams)
|
||||||
elif self.skip_string(','):
|
elif self.skip_string(','):
|
||||||
|
prevErrors = []
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
header = "Error in template parameter list."
|
header = "Error in template parameter list."
|
||||||
|
Loading…
Reference in New Issue
Block a user