mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7376 from jakobandersen/c_cpp_error_messages
C, C++, improve error messages
This commit is contained in:
commit
6deb592a2f
@ -1986,6 +1986,10 @@ class DefinitionParser(BaseParser):
|
|||||||
|
|
||||||
_prefix_keys = ('struct', 'enum', 'union')
|
_prefix_keys = ('struct', 'enum', 'union')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def language(self) -> str:
|
||||||
|
return 'C'
|
||||||
|
|
||||||
def _parse_string(self) -> str:
|
def _parse_string(self) -> str:
|
||||||
if self.current_char != '"':
|
if self.current_char != '"':
|
||||||
return None
|
return None
|
||||||
@ -2697,7 +2701,7 @@ class DefinitionParser(BaseParser):
|
|||||||
restrict=restrict, volatile=volatile, const=const,
|
restrict=restrict, volatile=volatile, const=const,
|
||||||
attrs=attrs)
|
attrs=attrs)
|
||||||
if typed and self.current_char == '(': # note: peeking, not skipping
|
if typed and self.current_char == '(': # note: peeking, not skipping
|
||||||
# maybe this is the beginning of params,try that first,
|
# maybe this is the beginning of params, try that first,
|
||||||
# otherwise assume it's noptr->declarator > ( ptr-declarator )
|
# otherwise assume it's noptr->declarator > ( ptr-declarator )
|
||||||
pos = self.pos
|
pos = self.pos
|
||||||
try:
|
try:
|
||||||
@ -2706,7 +2710,10 @@ class DefinitionParser(BaseParser):
|
|||||||
typed)
|
typed)
|
||||||
return res
|
return res
|
||||||
except DefinitionError as exParamQual:
|
except DefinitionError as exParamQual:
|
||||||
prevErrors.append((exParamQual, "If declId and parameters"))
|
msg = "If declarator-id with parameters"
|
||||||
|
if paramMode == 'function':
|
||||||
|
msg += " (e.g., 'void f(int arg)')"
|
||||||
|
prevErrors.append((exParamQual, msg))
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
try:
|
try:
|
||||||
assert self.current_char == '('
|
assert self.current_char == '('
|
||||||
@ -2723,7 +2730,10 @@ class DefinitionParser(BaseParser):
|
|||||||
return ASTDeclaratorParen(inner=inner, next=next)
|
return ASTDeclaratorParen(inner=inner, next=next)
|
||||||
except DefinitionError as exNoPtrParen:
|
except DefinitionError as exNoPtrParen:
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
prevErrors.append((exNoPtrParen, "If parenthesis in noptr-declarator"))
|
msg = "If parenthesis in noptr-declarator"
|
||||||
|
if paramMode == 'function':
|
||||||
|
msg += " (e.g., 'void (*f(int arg))(double)')"
|
||||||
|
prevErrors.append((exNoPtrParen, msg))
|
||||||
header = "Error in declarator"
|
header = "Error in declarator"
|
||||||
raise self._make_multi_error(prevErrors, header)
|
raise self._make_multi_error(prevErrors, header)
|
||||||
pos = self.pos
|
pos = self.pos
|
||||||
|
@ -4576,6 +4576,10 @@ class DefinitionParser(BaseParser):
|
|||||||
super().__init__(definition, location=location)
|
super().__init__(definition, location=location)
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def language(self) -> str:
|
||||||
|
return 'C++'
|
||||||
|
|
||||||
def _parse_string(self) -> str:
|
def _parse_string(self) -> str:
|
||||||
if self.current_char != '"':
|
if self.current_char != '"':
|
||||||
return None
|
return None
|
||||||
@ -5470,7 +5474,7 @@ class DefinitionParser(BaseParser):
|
|||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if not self.skip_string('('):
|
if not self.skip_string('('):
|
||||||
if paramMode == 'function':
|
if paramMode == 'function':
|
||||||
self.fail('Expecting "(" in parameters_and_qualifiers.')
|
self.fail('Expecting "(" in parameters-and-qualifiers.')
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
args = []
|
args = []
|
||||||
@ -5483,7 +5487,7 @@ class DefinitionParser(BaseParser):
|
|||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if not self.skip_string(')'):
|
if not self.skip_string(')'):
|
||||||
self.fail('Expected ")" after "..." in '
|
self.fail('Expected ")" after "..." in '
|
||||||
'parameters_and_qualifiers.')
|
'parameters-and-qualifiers.')
|
||||||
break
|
break
|
||||||
# note: it seems that function arguments can always be named,
|
# note: it seems that function arguments can always be named,
|
||||||
# even in function pointers and similar.
|
# even in function pointers and similar.
|
||||||
@ -5498,7 +5502,7 @@ class DefinitionParser(BaseParser):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.fail(
|
self.fail(
|
||||||
'Expecting "," or ")" in parameters_and_qualifiers, '
|
'Expecting "," or ")" in parameters-and-qualifiers, '
|
||||||
'got "%s".' % self.current_char)
|
'got "%s".' % self.current_char)
|
||||||
|
|
||||||
# TODO: why did we have this bail-out?
|
# TODO: why did we have this bail-out?
|
||||||
@ -5529,7 +5533,7 @@ class DefinitionParser(BaseParser):
|
|||||||
exceptionSpec = 'noexcept'
|
exceptionSpec = 'noexcept'
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if self.skip_string('('):
|
if self.skip_string('('):
|
||||||
self.fail('Parameterised "noexcept" not implemented.')
|
self.fail('Parameterised "noexcept" not yet implemented.')
|
||||||
|
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
override = self.skip_word_and_ws('override')
|
override = self.skip_word_and_ws('override')
|
||||||
@ -5795,14 +5799,15 @@ class DefinitionParser(BaseParser):
|
|||||||
typed)
|
typed)
|
||||||
return res
|
return res
|
||||||
except DefinitionError as exParamQual:
|
except DefinitionError as exParamQual:
|
||||||
prevErrors.append((exParamQual, "If declId, parameters, and qualifiers"))
|
prevErrors.append((exParamQual,
|
||||||
|
"If declarator-id with parameters-and-qualifiers"))
|
||||||
self.pos = pos
|
self.pos = pos
|
||||||
try:
|
try:
|
||||||
assert self.current_char == '('
|
assert self.current_char == '('
|
||||||
self.skip_string('(')
|
self.skip_string('(')
|
||||||
# TODO: hmm, if there is a name, it must be in inner, right?
|
# TODO: hmm, if there is a name, it must be in inner, right?
|
||||||
# TODO: hmm, if there must be parameters, they must b
|
# TODO: hmm, if there must be parameters, they must be
|
||||||
# inside, right?
|
# inside, right?
|
||||||
inner = self._parse_declarator(named, paramMode, typed)
|
inner = self._parse_declarator(named, paramMode, typed)
|
||||||
if not self.skip_string(')'):
|
if not self.skip_string(')'):
|
||||||
self.fail("Expected ')' in \"( ptr-declarator )\"")
|
self.fail("Expected ')' in \"( ptr-declarator )\"")
|
||||||
@ -5821,7 +5826,7 @@ class DefinitionParser(BaseParser):
|
|||||||
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"))
|
||||||
header = "Error in declarator or parameters and qualifiers"
|
header = "Error in declarator or parameters-and-qualifiers"
|
||||||
raise self._make_multi_error(prevErrors, header)
|
raise self._make_multi_error(prevErrors, header)
|
||||||
|
|
||||||
def _parse_initializer(self, outer: str = None, allowFallback: bool = True
|
def _parse_initializer(self, outer: str = None, allowFallback: bool = True
|
||||||
@ -5994,10 +5999,10 @@ class DefinitionParser(BaseParser):
|
|||||||
if eExpr is None:
|
if eExpr is None:
|
||||||
raise eType
|
raise eType
|
||||||
errs = []
|
errs = []
|
||||||
errs.append((eExpr, "If default is an expression"))
|
errs.append((eExpr, "If default template argument is an expression"))
|
||||||
errs.append((eType, "If default is a type"))
|
errs.append((eType, "If default template argument is a type"))
|
||||||
msg = "Error in non-type template parameter"
|
msg = "Error in non-type template parameter"
|
||||||
msg += " or constrianted template paramter."
|
msg += " or constrained template parameter."
|
||||||
raise self._make_multi_error(errs, msg)
|
raise self._make_multi_error(errs, msg)
|
||||||
|
|
||||||
def _parse_type_using(self) -> ASTTypeUsing:
|
def _parse_type_using(self) -> ASTTypeUsing:
|
||||||
|
@ -154,19 +154,23 @@ class BaseParser:
|
|||||||
result = [header, '\n']
|
result = [header, '\n']
|
||||||
for e in errors:
|
for e in errors:
|
||||||
if len(e[1]) > 0:
|
if len(e[1]) > 0:
|
||||||
ident = ' '
|
indent = ' '
|
||||||
result.append(e[1])
|
result.append(e[1])
|
||||||
result.append(':\n')
|
result.append(':\n')
|
||||||
for line in str(e[0]).split('\n'):
|
for line in str(e[0]).split('\n'):
|
||||||
if len(line) == 0:
|
if len(line) == 0:
|
||||||
continue
|
continue
|
||||||
result.append(ident)
|
result.append(indent)
|
||||||
result.append(line)
|
result.append(line)
|
||||||
result.append('\n')
|
result.append('\n')
|
||||||
else:
|
else:
|
||||||
result.append(str(e[0]))
|
result.append(str(e[0]))
|
||||||
return DefinitionError(''.join(result))
|
return DefinitionError(''.join(result))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def language(self) -> str:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def status(self, msg: str) -> None:
|
def status(self, msg: str) -> None:
|
||||||
# for debugging
|
# for debugging
|
||||||
indicator = '-' * self.pos + '^'
|
indicator = '-' * self.pos + '^'
|
||||||
@ -176,8 +180,8 @@ class BaseParser:
|
|||||||
errors = []
|
errors = []
|
||||||
indicator = '-' * self.pos + '^'
|
indicator = '-' * self.pos + '^'
|
||||||
exMain = DefinitionError(
|
exMain = DefinitionError(
|
||||||
'Invalid definition: %s [error at %d]\n %s\n %s' %
|
'Invalid %s declaration: %s [error at %d]\n %s\n %s' %
|
||||||
(msg, self.pos, self.definition, indicator))
|
(self.language, msg, self.pos, self.definition, indicator))
|
||||||
errors.append((exMain, "Main error"))
|
errors.append((exMain, "Main error"))
|
||||||
for err in self.otherErrors:
|
for err in self.otherErrors:
|
||||||
errors.append((err, "Potential other error"))
|
errors.append((err, "Potential other error"))
|
||||||
|
Loading…
Reference in New Issue
Block a user